2019-06-11 04:05:38

by dbasehore .

[permalink] [raw]
Subject: [PATCH v2 0/5] Panel rotation patches

This adds the plumbing for reading panel rotation from the devicetree
and sets up adding a panel property for the panel orientation on
Mediatek SoCs when a rotation is present.

v2 changes:
fixed build errors in i915

Derek Basehore (5):
drm/panel: Add helper for reading DT rotation
dt-bindings: display/panel: Expand rotation documentation
drm/panel: Add attach/detach callbacks
drm/connector: Split out orientation quirk detection
drm/mtk: add panel orientation property

.../bindings/display/panel/panel.txt | 32 +++++++++++
drivers/gpu/drm/drm_connector.c | 16 ++----
drivers/gpu/drm/drm_panel.c | 55 +++++++++++++++++++
drivers/gpu/drm/i915/vlv_dsi.c | 13 +++--
drivers/gpu/drm/mediatek/mtk_dsi.c | 8 +++
include/drm/drm_connector.h | 2 +-
include/drm/drm_panel.h | 11 ++++
7 files changed, 120 insertions(+), 17 deletions(-)

--
2.22.0.rc2.383.gf4fbbf30c2-goog


2019-06-11 04:06:12

by dbasehore .

[permalink] [raw]
Subject: [PATCH 3/5] drm/panel: Add attach/detach callbacks

This adds the attach/detach callbacks. These are for setting up
internal state for the connector/panel pair that can't be done at
probe (since the connector doesn't exist) and which don't need to be
repeatedly done for every get/modes, prepare, or enable callback.
Values such as the panel orientation, and display size can be filled
in for the connector.

Signed-off-by: Derek Basehore <[email protected]>
---
drivers/gpu/drm/drm_panel.c | 14 ++++++++++++++
include/drm/drm_panel.h | 4 ++++
2 files changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
index 3b689ce4a51a..72f67678d9d5 100644
--- a/drivers/gpu/drm/drm_panel.c
+++ b/drivers/gpu/drm/drm_panel.c
@@ -104,12 +104,23 @@ EXPORT_SYMBOL(drm_panel_remove);
*/
int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector)
{
+ int ret;
+
if (panel->connector)
return -EBUSY;

panel->connector = connector;
panel->drm = connector->dev;

+ if (panel->funcs->attach) {
+ ret = panel->funcs->attach(panel);
+ if (ret < 0) {
+ panel->connector = NULL;
+ panel->drm = NULL;
+ return ret;
+ }
+ }
+
return 0;
}
EXPORT_SYMBOL(drm_panel_attach);
@@ -128,6 +139,9 @@ EXPORT_SYMBOL(drm_panel_attach);
*/
int drm_panel_detach(struct drm_panel *panel)
{
+ if (panel->funcs->detach)
+ panel->funcs->detach(panel);
+
panel->connector = NULL;
panel->drm = NULL;

diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
index 13631b2efbaa..e136e3a3c996 100644
--- a/include/drm/drm_panel.h
+++ b/include/drm/drm_panel.h
@@ -37,6 +37,8 @@ struct display_timing;
* struct drm_panel_funcs - perform operations on a given panel
* @disable: disable panel (turn off back light, etc.)
* @unprepare: turn off panel
+ * @detach: detach panel->connector (clear internal state, etc.)
+ * @attach: attach panel->connector (update internal state, etc.)
* @prepare: turn on panel and perform set up
* @enable: enable panel (turn on back light, etc.)
* @get_modes: add modes to the connector that the panel is attached to and
@@ -70,6 +72,8 @@ struct display_timing;
struct drm_panel_funcs {
int (*disable)(struct drm_panel *panel);
int (*unprepare)(struct drm_panel *panel);
+ void (*detach)(struct drm_panel *panel);
+ int (*attach)(struct drm_panel *panel);
int (*prepare)(struct drm_panel *panel);
int (*enable)(struct drm_panel *panel);
int (*get_modes)(struct drm_panel *panel);
--
2.22.0.rc2.383.gf4fbbf30c2-goog

2019-06-11 04:06:46

by dbasehore .

[permalink] [raw]
Subject: [PATCH 1/5] drm/panel: Add helper for reading DT rotation

This adds a helper function for reading the rotation (panel
orientation) from the device tree.

Signed-off-by: Derek Basehore <[email protected]>
---
drivers/gpu/drm/drm_panel.c | 41 +++++++++++++++++++++++++++++++++++++
include/drm/drm_panel.h | 7 +++++++
2 files changed, 48 insertions(+)

diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
index dbd5b873e8f2..3b689ce4a51a 100644
--- a/drivers/gpu/drm/drm_panel.c
+++ b/drivers/gpu/drm/drm_panel.c
@@ -172,6 +172,47 @@ struct drm_panel *of_drm_find_panel(const struct device_node *np)
return ERR_PTR(-EPROBE_DEFER);
}
EXPORT_SYMBOL(of_drm_find_panel);
+
+/**
+ * of_drm_get_panel_orientation - look up the rotation of the panel using a
+ * device tree node
+ * @np: device tree node of the panel
+ * @orientation: orientation enum to be filled in
+ *
+ * Looks up the rotation of a panel in the device tree. The rotation in the
+ * device tree is counter clockwise.
+ *
+ * Return: 0 when a valid rotation value (0, 90, 180, or 270) is read or the
+ * rotation property doesn't exist. -EERROR otherwise.
+ */
+int of_drm_get_panel_orientation(const struct device_node *np, int *orientation)
+{
+ int rotation, ret;
+
+ ret = of_property_read_u32(np, "rotation", &rotation);
+ if (ret == -EINVAL) {
+ /* Don't return an error if there's no rotation property. */
+ *orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
+ return 0;
+ }
+
+ if (ret < 0)
+ return ret;
+
+ if (rotation == 0)
+ *orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
+ else if (rotation == 90)
+ *orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP;
+ else if (rotation == 180)
+ *orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
+ else if (rotation == 270)
+ *orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP;
+ else
+ return -EINVAL;
+
+ return 0;
+}
+EXPORT_SYMBOL(of_drm_get_panel_orientation);
#endif

MODULE_AUTHOR("Thierry Reding <[email protected]>");
diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
index 8c738c0e6e9f..13631b2efbaa 100644
--- a/include/drm/drm_panel.h
+++ b/include/drm/drm_panel.h
@@ -197,11 +197,18 @@ int drm_panel_detach(struct drm_panel *panel);

#if defined(CONFIG_OF) && defined(CONFIG_DRM_PANEL)
struct drm_panel *of_drm_find_panel(const struct device_node *np);
+int of_drm_get_panel_orientation(const struct device_node *np,
+ int *orientation);
#else
static inline struct drm_panel *of_drm_find_panel(const struct device_node *np)
{
return ERR_PTR(-ENODEV);
}
+int of_drm_get_panel_orientation(const struct device_node *np,
+ int *orientation)
+{
+ return -ENODEV;
+}
#endif

#endif
--
2.22.0.rc2.383.gf4fbbf30c2-goog

2019-06-11 08:58:36

by Daniel Vetter

[permalink] [raw]
Subject: Re: [PATCH 3/5] drm/panel: Add attach/detach callbacks

On Mon, Jun 10, 2019 at 09:03:48PM -0700, Derek Basehore wrote:
> This adds the attach/detach callbacks. These are for setting up
> internal state for the connector/panel pair that can't be done at
> probe (since the connector doesn't exist) and which don't need to be
> repeatedly done for every get/modes, prepare, or enable callback.
> Values such as the panel orientation, and display size can be filled
> in for the connector.
>
> Signed-off-by: Derek Basehore <[email protected]>
> ---
> drivers/gpu/drm/drm_panel.c | 14 ++++++++++++++
> include/drm/drm_panel.h | 4 ++++
> 2 files changed, 18 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
> index 3b689ce4a51a..72f67678d9d5 100644
> --- a/drivers/gpu/drm/drm_panel.c
> +++ b/drivers/gpu/drm/drm_panel.c
> @@ -104,12 +104,23 @@ EXPORT_SYMBOL(drm_panel_remove);
> */
> int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector)
> {
> + int ret;
> +
> if (panel->connector)
> return -EBUSY;
>
> panel->connector = connector;
> panel->drm = connector->dev;
>
> + if (panel->funcs->attach) {
> + ret = panel->funcs->attach(panel);
> + if (ret < 0) {
> + panel->connector = NULL;
> + panel->drm = NULL;
> + return ret;
> + }
> + }

Why can't we just implement this in the drm helpers for everyone, by e.g.
storing a dt node in drm_panel? Feels a bit overkill to have these new
hooks here.

Also, my understanding is that this dt stuff is supposed to be
standardized, so this should work.
-Daniel

> +
> return 0;
> }
> EXPORT_SYMBOL(drm_panel_attach);
> @@ -128,6 +139,9 @@ EXPORT_SYMBOL(drm_panel_attach);
> */
> int drm_panel_detach(struct drm_panel *panel)
> {
> + if (panel->funcs->detach)
> + panel->funcs->detach(panel);
> +
> panel->connector = NULL;
> panel->drm = NULL;
>
> diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
> index 13631b2efbaa..e136e3a3c996 100644
> --- a/include/drm/drm_panel.h
> +++ b/include/drm/drm_panel.h
> @@ -37,6 +37,8 @@ struct display_timing;
> * struct drm_panel_funcs - perform operations on a given panel
> * @disable: disable panel (turn off back light, etc.)
> * @unprepare: turn off panel
> + * @detach: detach panel->connector (clear internal state, etc.)
> + * @attach: attach panel->connector (update internal state, etc.)
> * @prepare: turn on panel and perform set up
> * @enable: enable panel (turn on back light, etc.)
> * @get_modes: add modes to the connector that the panel is attached to and
> @@ -70,6 +72,8 @@ struct display_timing;
> struct drm_panel_funcs {
> int (*disable)(struct drm_panel *panel);
> int (*unprepare)(struct drm_panel *panel);
> + void (*detach)(struct drm_panel *panel);
> + int (*attach)(struct drm_panel *panel);
> int (*prepare)(struct drm_panel *panel);
> int (*enable)(struct drm_panel *panel);
> int (*get_modes)(struct drm_panel *panel);
> --
> 2.22.0.rc2.383.gf4fbbf30c2-goog
>

--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

2019-06-12 07:16:44

by dbasehore .

[permalink] [raw]
Subject: Re: [PATCH 3/5] drm/panel: Add attach/detach callbacks

On Tue, Jun 11, 2019 at 1:57 AM Daniel Vetter <[email protected]> wrote:
>
> On Mon, Jun 10, 2019 at 09:03:48PM -0700, Derek Basehore wrote:
> > This adds the attach/detach callbacks. These are for setting up
> > internal state for the connector/panel pair that can't be done at
> > probe (since the connector doesn't exist) and which don't need to be
> > repeatedly done for every get/modes, prepare, or enable callback.
> > Values such as the panel orientation, and display size can be filled
> > in for the connector.
> >
> > Signed-off-by: Derek Basehore <[email protected]>
> > ---
> > drivers/gpu/drm/drm_panel.c | 14 ++++++++++++++
> > include/drm/drm_panel.h | 4 ++++
> > 2 files changed, 18 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
> > index 3b689ce4a51a..72f67678d9d5 100644
> > --- a/drivers/gpu/drm/drm_panel.c
> > +++ b/drivers/gpu/drm/drm_panel.c
> > @@ -104,12 +104,23 @@ EXPORT_SYMBOL(drm_panel_remove);
> > */
> > int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector)
> > {
> > + int ret;
> > +
> > if (panel->connector)
> > return -EBUSY;
> >
> > panel->connector = connector;
> > panel->drm = connector->dev;
> >
> > + if (panel->funcs->attach) {
> > + ret = panel->funcs->attach(panel);
> > + if (ret < 0) {
> > + panel->connector = NULL;
> > + panel->drm = NULL;
> > + return ret;
> > + }
> > + }
>
> Why can't we just implement this in the drm helpers for everyone, by e.g.
> storing a dt node in drm_panel? Feels a bit overkill to have these new
> hooks here.
>
> Also, my understanding is that this dt stuff is supposed to be
> standardized, so this should work.

So do you want all of this information added to the drm_panel struct?
If we do that, we don't necessarily even need the drm helper function.
We could just copy the values over here in the drm_panel_attach
function (and clear them in drm_panel_detach).

> -Daniel
>
> > +
> > return 0;
> > }
> > EXPORT_SYMBOL(drm_panel_attach);
> > @@ -128,6 +139,9 @@ EXPORT_SYMBOL(drm_panel_attach);
> > */
> > int drm_panel_detach(struct drm_panel *panel)
> > {
> > + if (panel->funcs->detach)
> > + panel->funcs->detach(panel);
> > +
> > panel->connector = NULL;
> > panel->drm = NULL;
> >
> > diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
> > index 13631b2efbaa..e136e3a3c996 100644
> > --- a/include/drm/drm_panel.h
> > +++ b/include/drm/drm_panel.h
> > @@ -37,6 +37,8 @@ struct display_timing;
> > * struct drm_panel_funcs - perform operations on a given panel
> > * @disable: disable panel (turn off back light, etc.)
> > * @unprepare: turn off panel
> > + * @detach: detach panel->connector (clear internal state, etc.)
> > + * @attach: attach panel->connector (update internal state, etc.)
> > * @prepare: turn on panel and perform set up
> > * @enable: enable panel (turn on back light, etc.)
> > * @get_modes: add modes to the connector that the panel is attached to and
> > @@ -70,6 +72,8 @@ struct display_timing;
> > struct drm_panel_funcs {
> > int (*disable)(struct drm_panel *panel);
> > int (*unprepare)(struct drm_panel *panel);
> > + void (*detach)(struct drm_panel *panel);
> > + int (*attach)(struct drm_panel *panel);
> > int (*prepare)(struct drm_panel *panel);
> > int (*enable)(struct drm_panel *panel);
> > int (*get_modes)(struct drm_panel *panel);
> > --
> > 2.22.0.rc2.383.gf4fbbf30c2-goog
> >
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

2019-06-13 17:18:03

by Sam Ravnborg

[permalink] [raw]
Subject: Re: [PATCH 1/5] drm/panel: Add helper for reading DT rotation

Hi Derek.

On Mon, Jun 10, 2019 at 09:03:46PM -0700, Derek Basehore wrote:
> This adds a helper function for reading the rotation (panel
> orientation) from the device tree.
>
> Signed-off-by: Derek Basehore <[email protected]>
> ---
> drivers/gpu/drm/drm_panel.c | 41 +++++++++++++++++++++++++++++++++++++
> include/drm/drm_panel.h | 7 +++++++
> 2 files changed, 48 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
> index dbd5b873e8f2..3b689ce4a51a 100644
> --- a/drivers/gpu/drm/drm_panel.c
> +++ b/drivers/gpu/drm/drm_panel.c
> @@ -172,6 +172,47 @@ struct drm_panel *of_drm_find_panel(const struct device_node *np)
> return ERR_PTR(-EPROBE_DEFER);
> }
> EXPORT_SYMBOL(of_drm_find_panel);
> +
> +/**
> + * of_drm_get_panel_orientation - look up the rotation of the panel using a
> + * device tree node
> + * @np: device tree node of the panel
> + * @orientation: orientation enum to be filled in
The comment says "enum" but the type used is an int.
Why not use enum drm_panel_orientation?

> + *
> + * Looks up the rotation of a panel in the device tree. The rotation in the
> + * device tree is counter clockwise.
> + *
> + * Return: 0 when a valid rotation value (0, 90, 180, or 270) is read or the
> + * rotation property doesn't exist. -EERROR otherwise.
> + */
Initially I read -EEROOR as a specific error code.
But I gues the semantic is to say that a negative error code is returned
if something was wrong.
As we do not use the "-EERROR" syntax anywhere else in drm, please
reword like we do in other places.


Also - it is worth to mention that the rotation returned is
DRM_MODE_PANEL_ORIENTATION_UNKNOWN if the property is not specified.
I wonder if this is correct, as no property could also been
interpretated as DRM_MODE_PANEL_ORIENTATION_NORMAL.
And in most cases the roation property is optional, so one could
assume that no property equals 0 degree.


Sam

> +int of_drm_get_panel_orientation(const struct device_node *np, int *orientation)
> +{
> + int rotation, ret;
> +
> + ret = of_property_read_u32(np, "rotation", &rotation);
> + if (ret == -EINVAL) {
> + /* Don't return an error if there's no rotation property. */
> + *orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
> + return 0;
> + }
> +
> + if (ret < 0)
> + return ret;
> +
> + if (rotation == 0)
> + *orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
> + else if (rotation == 90)
> + *orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP;
> + else if (rotation == 180)
> + *orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
> + else if (rotation == 270)
> + *orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP;
> + else
> + return -EINVAL;
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(of_drm_get_panel_orientation);
> #endif
>
> MODULE_AUTHOR("Thierry Reding <[email protected]>");
> diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
> index 8c738c0e6e9f..13631b2efbaa 100644
> --- a/include/drm/drm_panel.h
> +++ b/include/drm/drm_panel.h
> @@ -197,11 +197,18 @@ int drm_panel_detach(struct drm_panel *panel);
>
> #if defined(CONFIG_OF) && defined(CONFIG_DRM_PANEL)
> struct drm_panel *of_drm_find_panel(const struct device_node *np);
> +int of_drm_get_panel_orientation(const struct device_node *np,
> + int *orientation);
> #else
> static inline struct drm_panel *of_drm_find_panel(const struct device_node *np)
> {
> return ERR_PTR(-ENODEV);
> }
> +int of_drm_get_panel_orientation(const struct device_node *np,
> + int *orientation)
> +{
> + return -ENODEV;
> +}
> #endif
>
> #endif
> --
> 2.22.0.rc2.383.gf4fbbf30c2-goog

2019-06-13 17:19:07

by Sam Ravnborg

[permalink] [raw]
Subject: Re: [PATCH 1/5] drm/panel: Add helper for reading DT rotation

Hi Derek.

On Mon, Jun 10, 2019 at 09:03:46PM -0700, Derek Basehore wrote:
> This adds a helper function for reading the rotation (panel
> orientation) from the device tree.
>
> Signed-off-by: Derek Basehore <[email protected]>
> ---
> drivers/gpu/drm/drm_panel.c | 41 +++++++++++++++++++++++++++++++++++++
> include/drm/drm_panel.h | 7 +++++++
> 2 files changed, 48 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
> index dbd5b873e8f2..3b689ce4a51a 100644
> --- a/drivers/gpu/drm/drm_panel.c
> +++ b/drivers/gpu/drm/drm_panel.c
> @@ -172,6 +172,47 @@ struct drm_panel *of_drm_find_panel(const struct device_node *np)
> return ERR_PTR(-EPROBE_DEFER);
> }
> EXPORT_SYMBOL(of_drm_find_panel);
> +
> +/**
> + * of_drm_get_panel_orientation - look up the rotation of the panel using a
> + * device tree node
> + * @np: device tree node of the panel
> + * @orientation: orientation enum to be filled in
> + *
> + * Looks up the rotation of a panel in the device tree. The rotation in the
> + * device tree is counter clockwise.
> + *
> + * Return: 0 when a valid rotation value (0, 90, 180, or 270) is read or the
> + * rotation property doesn't exist. -EERROR otherwise.
> + */
> +int of_drm_get_panel_orientation(const struct device_node *np, int *orientation)
> +{
> + int rotation, ret;
> +
> + ret = of_property_read_u32(np, "rotation", &rotation);

I just noticed that everywhere this code talks about orientation,
but the property that it reads are rotation.
To my best understanding these are not the same.

Sam

2019-06-14 00:33:30

by dbasehore .

[permalink] [raw]
Subject: Re: [PATCH 1/5] drm/panel: Add helper for reading DT rotation

On Wed, Jun 12, 2019 at 2:20 PM Sam Ravnborg <[email protected]> wrote:
>
> Hi Derek.
>
> On Mon, Jun 10, 2019 at 09:03:46PM -0700, Derek Basehore wrote:
> > This adds a helper function for reading the rotation (panel
> > orientation) from the device tree.
> >
> > Signed-off-by: Derek Basehore <[email protected]>
> > ---
> > drivers/gpu/drm/drm_panel.c | 41 +++++++++++++++++++++++++++++++++++++
> > include/drm/drm_panel.h | 7 +++++++
> > 2 files changed, 48 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
> > index dbd5b873e8f2..3b689ce4a51a 100644
> > --- a/drivers/gpu/drm/drm_panel.c
> > +++ b/drivers/gpu/drm/drm_panel.c
> > @@ -172,6 +172,47 @@ struct drm_panel *of_drm_find_panel(const struct device_node *np)
> > return ERR_PTR(-EPROBE_DEFER);
> > }
> > EXPORT_SYMBOL(of_drm_find_panel);
> > +
> > +/**
> > + * of_drm_get_panel_orientation - look up the rotation of the panel using a
> > + * device tree node
> > + * @np: device tree node of the panel
> > + * @orientation: orientation enum to be filled in
> > + *
> > + * Looks up the rotation of a panel in the device tree. The rotation in the
> > + * device tree is counter clockwise.
> > + *
> > + * Return: 0 when a valid rotation value (0, 90, 180, or 270) is read or the
> > + * rotation property doesn't exist. -EERROR otherwise.
> > + */
> > +int of_drm_get_panel_orientation(const struct device_node *np, int *orientation)
> > +{
> > + int rotation, ret;
> > +
> > + ret = of_property_read_u32(np, "rotation", &rotation);
>
> I just noticed that everywhere this code talks about orientation,
> but the property that it reads are rotation.
> To my best understanding these are not the same.

This is because both were previously defined in the kernel. Rotation
was defined as a binding in the devicetree for panels (which is where
we wanted to put this property) and orientation already exists as a
DRM property.

If we want to change one, I would suggest the rotation binding since
it doesn't have any upstream users yet.

>
> Sam

2019-06-15 00:44:13

by dbasehore .

[permalink] [raw]
Subject: Re: [PATCH 1/5] drm/panel: Add helper for reading DT rotation

On Wed, Jun 12, 2019 at 2:18 PM Sam Ravnborg <[email protected]> wrote:
>
> Hi Derek.
>
> On Mon, Jun 10, 2019 at 09:03:46PM -0700, Derek Basehore wrote:
> > This adds a helper function for reading the rotation (panel
> > orientation) from the device tree.
> >
> > Signed-off-by: Derek Basehore <[email protected]>
> > ---
> > drivers/gpu/drm/drm_panel.c | 41 +++++++++++++++++++++++++++++++++++++
> > include/drm/drm_panel.h | 7 +++++++
> > 2 files changed, 48 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
> > index dbd5b873e8f2..3b689ce4a51a 100644
> > --- a/drivers/gpu/drm/drm_panel.c
> > +++ b/drivers/gpu/drm/drm_panel.c
> > @@ -172,6 +172,47 @@ struct drm_panel *of_drm_find_panel(const struct device_node *np)
> > return ERR_PTR(-EPROBE_DEFER);
> > }
> > EXPORT_SYMBOL(of_drm_find_panel);
> > +
> > +/**
> > + * of_drm_get_panel_orientation - look up the rotation of the panel using a
> > + * device tree node
> > + * @np: device tree node of the panel
> > + * @orientation: orientation enum to be filled in
> The comment says "enum" but the type used is an int.
> Why not use enum drm_panel_orientation?
>

The binding is just an int value, but I can change it to the enum.

> > + *
> > + * Looks up the rotation of a panel in the device tree. The rotation in the
> > + * device tree is counter clockwise.
> > + *
> > + * Return: 0 when a valid rotation value (0, 90, 180, or 270) is read or the
> > + * rotation property doesn't exist. -EERROR otherwise.
> > + */
> Initially I read -EEROOR as a specific error code.
> But I gues the semantic is to say that a negative error code is returned
> if something was wrong.
> As we do not use the "-EERROR" syntax anywhere else in drm, please
> reword like we do in other places.
>
>
> Also - it is worth to mention that the rotation returned is
> DRM_MODE_PANEL_ORIENTATION_UNKNOWN if the property is not specified.
> I wonder if this is correct, as no property could also been
> interpretated as DRM_MODE_PANEL_ORIENTATION_NORMAL.
> And in most cases the roation property is optional, so one could
> assume that no property equals 0 degree.
>
>
> Sam
>
> > +int of_drm_get_panel_orientation(const struct device_node *np, int *orientation)
> > +{
> > + int rotation, ret;
> > +
> > + ret = of_property_read_u32(np, "rotation", &rotation);
> > + if (ret == -EINVAL) {
> > + /* Don't return an error if there's no rotation property. */
> > + *orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
> > + return 0;
> > + }
> > +
> > + if (ret < 0)
> > + return ret;
> > +
> > + if (rotation == 0)
> > + *orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
> > + else if (rotation == 90)
> > + *orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP;
> > + else if (rotation == 180)
> > + *orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
> > + else if (rotation == 270)
> > + *orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP;
> > + else
> > + return -EINVAL;
> > +
> > + return 0;
> > +}
> > +EXPORT_SYMBOL(of_drm_get_panel_orientation);
> > #endif
> >
> > MODULE_AUTHOR("Thierry Reding <[email protected]>");
> > diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
> > index 8c738c0e6e9f..13631b2efbaa 100644
> > --- a/include/drm/drm_panel.h
> > +++ b/include/drm/drm_panel.h
> > @@ -197,11 +197,18 @@ int drm_panel_detach(struct drm_panel *panel);
> >
> > #if defined(CONFIG_OF) && defined(CONFIG_DRM_PANEL)
> > struct drm_panel *of_drm_find_panel(const struct device_node *np);
> > +int of_drm_get_panel_orientation(const struct device_node *np,
> > + int *orientation);
> > #else
> > static inline struct drm_panel *of_drm_find_panel(const struct device_node *np)
> > {
> > return ERR_PTR(-ENODEV);
> > }
> > +int of_drm_get_panel_orientation(const struct device_node *np,
> > + int *orientation)
> > +{
> > + return -ENODEV;
> > +}
> > #endif
> >
> > #endif
> > --
> > 2.22.0.rc2.383.gf4fbbf30c2-goog

2019-06-15 00:45:52

by dbasehore .

[permalink] [raw]
Subject: Re: [PATCH 1/5] drm/panel: Add helper for reading DT rotation

On Fri, Jun 14, 2019 at 5:43 PM dbasehore . <[email protected]> wrote:
>
> On Wed, Jun 12, 2019 at 2:18 PM Sam Ravnborg <[email protected]> wrote:
> >
> > Hi Derek.
> >
> > On Mon, Jun 10, 2019 at 09:03:46PM -0700, Derek Basehore wrote:
> > > This adds a helper function for reading the rotation (panel
> > > orientation) from the device tree.
> > >
> > > Signed-off-by: Derek Basehore <[email protected]>
> > > ---
> > > drivers/gpu/drm/drm_panel.c | 41 +++++++++++++++++++++++++++++++++++++
> > > include/drm/drm_panel.h | 7 +++++++
> > > 2 files changed, 48 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
> > > index dbd5b873e8f2..3b689ce4a51a 100644
> > > --- a/drivers/gpu/drm/drm_panel.c
> > > +++ b/drivers/gpu/drm/drm_panel.c
> > > @@ -172,6 +172,47 @@ struct drm_panel *of_drm_find_panel(const struct device_node *np)
> > > return ERR_PTR(-EPROBE_DEFER);
> > > }
> > > EXPORT_SYMBOL(of_drm_find_panel);
> > > +
> > > +/**
> > > + * of_drm_get_panel_orientation - look up the rotation of the panel using a
> > > + * device tree node
> > > + * @np: device tree node of the panel
> > > + * @orientation: orientation enum to be filled in
> > The comment says "enum" but the type used is an int.
> > Why not use enum drm_panel_orientation?
> >
>
> The binding is just an int value, but I can change it to the enum.

Oops, I see what happened here. The way I wrote it should actually use the enum

>
> > > + *
> > > + * Looks up the rotation of a panel in the device tree. The rotation in the
> > > + * device tree is counter clockwise.
> > > + *
> > > + * Return: 0 when a valid rotation value (0, 90, 180, or 270) is read or the
> > > + * rotation property doesn't exist. -EERROR otherwise.
> > > + */
> > Initially I read -EEROOR as a specific error code.
> > But I gues the semantic is to say that a negative error code is returned
> > if something was wrong.
> > As we do not use the "-EERROR" syntax anywhere else in drm, please
> > reword like we do in other places.
> >
> >
> > Also - it is worth to mention that the rotation returned is
> > DRM_MODE_PANEL_ORIENTATION_UNKNOWN if the property is not specified.
> > I wonder if this is correct, as no property could also been
> > interpretated as DRM_MODE_PANEL_ORIENTATION_NORMAL.
> > And in most cases the roation property is optional, so one could
> > assume that no property equals 0 degree.
> >
> >
> > Sam
> >
> > > +int of_drm_get_panel_orientation(const struct device_node *np, int *orientation)
> > > +{
> > > + int rotation, ret;
> > > +
> > > + ret = of_property_read_u32(np, "rotation", &rotation);
> > > + if (ret == -EINVAL) {
> > > + /* Don't return an error if there's no rotation property. */
> > > + *orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
> > > + return 0;
> > > + }
> > > +
> > > + if (ret < 0)
> > > + return ret;
> > > +
> > > + if (rotation == 0)
> > > + *orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
> > > + else if (rotation == 90)
> > > + *orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP;
> > > + else if (rotation == 180)
> > > + *orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
> > > + else if (rotation == 270)
> > > + *orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP;
> > > + else
> > > + return -EINVAL;
> > > +
> > > + return 0;
> > > +}
> > > +EXPORT_SYMBOL(of_drm_get_panel_orientation);
> > > #endif
> > >
> > > MODULE_AUTHOR("Thierry Reding <[email protected]>");
> > > diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
> > > index 8c738c0e6e9f..13631b2efbaa 100644
> > > --- a/include/drm/drm_panel.h
> > > +++ b/include/drm/drm_panel.h
> > > @@ -197,11 +197,18 @@ int drm_panel_detach(struct drm_panel *panel);
> > >
> > > #if defined(CONFIG_OF) && defined(CONFIG_DRM_PANEL)
> > > struct drm_panel *of_drm_find_panel(const struct device_node *np);
> > > +int of_drm_get_panel_orientation(const struct device_node *np,
> > > + int *orientation);
> > > #else
> > > static inline struct drm_panel *of_drm_find_panel(const struct device_node *np)
> > > {
> > > return ERR_PTR(-ENODEV);
> > > }
> > > +int of_drm_get_panel_orientation(const struct device_node *np,
> > > + int *orientation)
> > > +{
> > > + return -ENODEV;
> > > +}
> > > #endif
> > >
> > > #endif
> > > --
> > > 2.22.0.rc2.383.gf4fbbf30c2-goog

2019-06-21 01:59:24

by dbasehore .

[permalink] [raw]
Subject: Re: [PATCH 3/5] drm/panel: Add attach/detach callbacks

If we want to query the device tree outside of the panel code in
helper functions, we can do this with the struct as is. There's
already a device struct pointer in drm_panel, so I think we can pull
from that.

On Tue, Jun 11, 2019 at 5:25 PM dbasehore . <[email protected]> wrote:
>
> On Tue, Jun 11, 2019 at 1:57 AM Daniel Vetter <[email protected]> wrote:
> >
> > On Mon, Jun 10, 2019 at 09:03:48PM -0700, Derek Basehore wrote:
> > > This adds the attach/detach callbacks. These are for setting up
> > > internal state for the connector/panel pair that can't be done at
> > > probe (since the connector doesn't exist) and which don't need to be
> > > repeatedly done for every get/modes, prepare, or enable callback.
> > > Values such as the panel orientation, and display size can be filled
> > > in for the connector.
> > >
> > > Signed-off-by: Derek Basehore <[email protected]>
> > > ---
> > > drivers/gpu/drm/drm_panel.c | 14 ++++++++++++++
> > > include/drm/drm_panel.h | 4 ++++
> > > 2 files changed, 18 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
> > > index 3b689ce4a51a..72f67678d9d5 100644
> > > --- a/drivers/gpu/drm/drm_panel.c
> > > +++ b/drivers/gpu/drm/drm_panel.c
> > > @@ -104,12 +104,23 @@ EXPORT_SYMBOL(drm_panel_remove);
> > > */
> > > int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector)
> > > {
> > > + int ret;
> > > +
> > > if (panel->connector)
> > > return -EBUSY;
> > >
> > > panel->connector = connector;
> > > panel->drm = connector->dev;
> > >
> > > + if (panel->funcs->attach) {
> > > + ret = panel->funcs->attach(panel);
> > > + if (ret < 0) {
> > > + panel->connector = NULL;
> > > + panel->drm = NULL;
> > > + return ret;
> > > + }
> > > + }
> >
> > Why can't we just implement this in the drm helpers for everyone, by e.g.
> > storing a dt node in drm_panel? Feels a bit overkill to have these new
> > hooks here.
> >
> > Also, my understanding is that this dt stuff is supposed to be
> > standardized, so this should work.
>
> So do you want all of this information added to the drm_panel struct?
> If we do that, we don't necessarily even need the drm helper function.
> We could just copy the values over here in the drm_panel_attach
> function (and clear them in drm_panel_detach).
>
> > -Daniel
> >
> > > +
> > > return 0;
> > > }
> > > EXPORT_SYMBOL(drm_panel_attach);
> > > @@ -128,6 +139,9 @@ EXPORT_SYMBOL(drm_panel_attach);
> > > */
> > > int drm_panel_detach(struct drm_panel *panel)
> > > {
> > > + if (panel->funcs->detach)
> > > + panel->funcs->detach(panel);
> > > +
> > > panel->connector = NULL;
> > > panel->drm = NULL;
> > >
> > > diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
> > > index 13631b2efbaa..e136e3a3c996 100644
> > > --- a/include/drm/drm_panel.h
> > > +++ b/include/drm/drm_panel.h
> > > @@ -37,6 +37,8 @@ struct display_timing;
> > > * struct drm_panel_funcs - perform operations on a given panel
> > > * @disable: disable panel (turn off back light, etc.)
> > > * @unprepare: turn off panel
> > > + * @detach: detach panel->connector (clear internal state, etc.)
> > > + * @attach: attach panel->connector (update internal state, etc.)
> > > * @prepare: turn on panel and perform set up
> > > * @enable: enable panel (turn on back light, etc.)
> > > * @get_modes: add modes to the connector that the panel is attached to and
> > > @@ -70,6 +72,8 @@ struct display_timing;
> > > struct drm_panel_funcs {
> > > int (*disable)(struct drm_panel *panel);
> > > int (*unprepare)(struct drm_panel *panel);
> > > + void (*detach)(struct drm_panel *panel);
> > > + int (*attach)(struct drm_panel *panel);
> > > int (*prepare)(struct drm_panel *panel);
> > > int (*enable)(struct drm_panel *panel);
> > > int (*get_modes)(struct drm_panel *panel);
> > > --
> > > 2.22.0.rc2.383.gf4fbbf30c2-goog
> > >
> >
> > --
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch

2019-06-21 09:21:14

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCH 3/5] drm/panel: Add attach/detach callbacks

On Tue, Jun 11, 2019 at 05:25:47PM -0700, dbasehore . wrote:
> On Tue, Jun 11, 2019 at 1:57 AM Daniel Vetter <[email protected]> wrote:
> >
> > On Mon, Jun 10, 2019 at 09:03:48PM -0700, Derek Basehore wrote:
> > > This adds the attach/detach callbacks. These are for setting up
> > > internal state for the connector/panel pair that can't be done at
> > > probe (since the connector doesn't exist) and which don't need to be
> > > repeatedly done for every get/modes, prepare, or enable callback.
> > > Values such as the panel orientation, and display size can be filled
> > > in for the connector.
> > >
> > > Signed-off-by: Derek Basehore <[email protected]>
> > > ---
> > > drivers/gpu/drm/drm_panel.c | 14 ++++++++++++++
> > > include/drm/drm_panel.h | 4 ++++
> > > 2 files changed, 18 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
> > > index 3b689ce4a51a..72f67678d9d5 100644
> > > --- a/drivers/gpu/drm/drm_panel.c
> > > +++ b/drivers/gpu/drm/drm_panel.c
> > > @@ -104,12 +104,23 @@ EXPORT_SYMBOL(drm_panel_remove);
> > > */
> > > int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector)
> > > {
> > > + int ret;
> > > +
> > > if (panel->connector)
> > > return -EBUSY;
> > >
> > > panel->connector = connector;
> > > panel->drm = connector->dev;
> > >
> > > + if (panel->funcs->attach) {
> > > + ret = panel->funcs->attach(panel);
> > > + if (ret < 0) {
> > > + panel->connector = NULL;
> > > + panel->drm = NULL;
> > > + return ret;
> > > + }
> > > + }
> >
> > Why can't we just implement this in the drm helpers for everyone, by e.g.
> > storing a dt node in drm_panel? Feels a bit overkill to have these new
> > hooks here.
> >
> > Also, my understanding is that this dt stuff is supposed to be
> > standardized, so this should work.
>
> So do you want all of this information added to the drm_panel struct?
> If we do that, we don't necessarily even need the drm helper function.
> We could just copy the values over here in the drm_panel_attach
> function (and clear them in drm_panel_detach).

Yeah, I think we should have all this extra information in the struct
drm_panel. However, I think we need to more carefully split things such
that the DT parsing happens at panel probe time. That way we can catch
errors in DT, or missing entries/resources when we can still do
something about it.

If we start parsing DT and encounter failures, it's going to be very
confusing if that's at panel attach time where code will usually just
assume that everything is already validated and can't fail anymore.

Thierry


Attachments:
(No filename) (2.75 kB)
signature.asc (849.00 B)
Download all attachments

2019-06-22 01:55:42

by dbasehore .

[permalink] [raw]
Subject: Re: [PATCH 3/5] drm/panel: Add attach/detach callbacks

On Fri, Jun 21, 2019 at 2:19 AM Thierry Reding <[email protected]> wrote:
>
> On Tue, Jun 11, 2019 at 05:25:47PM -0700, dbasehore . wrote:
> > On Tue, Jun 11, 2019 at 1:57 AM Daniel Vetter <[email protected]> wrote:
> > >
> > > On Mon, Jun 10, 2019 at 09:03:48PM -0700, Derek Basehore wrote:
> > > > This adds the attach/detach callbacks. These are for setting up
> > > > internal state for the connector/panel pair that can't be done at
> > > > probe (since the connector doesn't exist) and which don't need to be
> > > > repeatedly done for every get/modes, prepare, or enable callback.
> > > > Values such as the panel orientation, and display size can be filled
> > > > in for the connector.
> > > >
> > > > Signed-off-by: Derek Basehore <[email protected]>
> > > > ---
> > > > drivers/gpu/drm/drm_panel.c | 14 ++++++++++++++
> > > > include/drm/drm_panel.h | 4 ++++
> > > > 2 files changed, 18 insertions(+)
> > > >
> > > > diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
> > > > index 3b689ce4a51a..72f67678d9d5 100644
> > > > --- a/drivers/gpu/drm/drm_panel.c
> > > > +++ b/drivers/gpu/drm/drm_panel.c
> > > > @@ -104,12 +104,23 @@ EXPORT_SYMBOL(drm_panel_remove);
> > > > */
> > > > int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector)
> > > > {
> > > > + int ret;
> > > > +
> > > > if (panel->connector)
> > > > return -EBUSY;
> > > >
> > > > panel->connector = connector;
> > > > panel->drm = connector->dev;
> > > >
> > > > + if (panel->funcs->attach) {
> > > > + ret = panel->funcs->attach(panel);
> > > > + if (ret < 0) {
> > > > + panel->connector = NULL;
> > > > + panel->drm = NULL;
> > > > + return ret;
> > > > + }
> > > > + }
> > >
> > > Why can't we just implement this in the drm helpers for everyone, by e.g.
> > > storing a dt node in drm_panel? Feels a bit overkill to have these new
> > > hooks here.
> > >
> > > Also, my understanding is that this dt stuff is supposed to be
> > > standardized, so this should work.
> >
> > So do you want all of this information added to the drm_panel struct?
> > If we do that, we don't necessarily even need the drm helper function.
> > We could just copy the values over here in the drm_panel_attach
> > function (and clear them in drm_panel_detach).
>
> Yeah, I think we should have all this extra information in the struct
> drm_panel. However, I think we need to more carefully split things such
> that the DT parsing happens at panel probe time. That way we can catch
> errors in DT, or missing entries/resources when we can still do
> something about it.

For now, I'll just put width, height, bpc, orientation, bus_flags, and
bus_formats in the drm_panel struct. Those are pretty consistently set
from either get_modes or prepare. The other thing those all have in
common is that the values don't change.

We could just add an entire drm_display_info struct inside drm_panel,
but I don't know if we can just copy that over or set a pointer
without breaking something else, since some of the values in the
drm_display_info struct are not set by the panel (but maybe set by
something else).

>
> If we start parsing DT and encounter failures, it's going to be very
> confusing if that's at panel attach time where code will usually just
> assume that everything is already validated and can't fail anymore.
>
> Thierry

Thanks for the review