devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Thierry Reding <thierry.reding@gmail.com>
To: Ajay Kumar <ajaykumar.rs@samsung.com>
Cc: devicetree@vger.kernel.org, linux-samsung-soc@vger.kernel.org,
	seanpaul@google.com, daniel.vetter@ffwll.ch, joshi@samsung.com,
	dri-devel@lists.freedesktop.org, ajaynumb@gmail.com,
	prashanth.g@samsung.com
Subject: Re: [PATCH V6 2/8] drm/panel: Add support for prepare and unprepare routines
Date: Wed, 30 Jul 2014 12:32:41 +0200	[thread overview]
Message-ID: <20140730103239.GE29590@ulmo> (raw)
In-Reply-To: <1406316130-4744-3-git-send-email-ajaykumar.rs@samsung.com>


[-- Attachment #1.1: Type: text/plain, Size: 7883 bytes --]

On Sat, Jul 26, 2014 at 12:52:04AM +0530, Ajay Kumar wrote:
> Now that we have 2 new callbacks(prepare and unprepare) for drm_panel,
> make changes in all the drm drivers which use the drm_panel framework
> to support the new callbacks.
> 
> Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_dpi.c |    8 +++--
>  drivers/gpu/drm/exynos/exynos_drm_dsi.c |    7 +++++
>  drivers/gpu/drm/panel/panel-ld9040.c    |   18 +++++++++--
>  drivers/gpu/drm/panel/panel-s6e8aa0.c   |   18 +++++++++--
>  drivers/gpu/drm/panel/panel-simple.c    |   51 ++++++++++++++++++++++++-------
>  drivers/gpu/drm/tegra/output.c          |    2 ++
>  6 files changed, 85 insertions(+), 19 deletions(-)

I'd prefer for this to be split up into patches per panel and per
display driver. The reason is that if this patch is merged as-is, then
if it's ever determined to cause a regression it'll be difficult to find
out which change exactly caused this.

But to not break bisectability you'll need to be careful in how you
break up the patches. I think the following should work:

	- for each panel driver, implement dummy .prepare() and
	  .unprepare() that return 0
	- for each display driver, make use of drm_panel_prepare() and
	  drm_panel_unprepare()
	- for each panel driver, properly implement .prepare() and
	  .unprepare() (presumably by moving code out of .enable() and
	  .disable(), respectively)

I have a couple more comments below about the ordering of the .prepare()
vs. .enable() and .disable() vs. .unprepare() calls.

> diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> index 5e78d45..2f58e45 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> @@ -1333,6 +1333,12 @@ static int exynos_dsi_enable(struct exynos_dsi *dsi)
>  	if (ret < 0)
>  		return ret;
>  
> +	ret = drm_panel_prepare(dsi->panel);
> +	if (ret < 0) {
> +		exynos_dsi_poweroff(dsi);
> +		return ret;
> +	}
> +
>  	ret = drm_panel_enable(dsi->panel);
>  	if (ret < 0) {
>  		exynos_dsi_poweroff(dsi);
> @@ -1354,6 +1360,7 @@ static void exynos_dsi_disable(struct exynos_dsi *dsi)
>  
>  	exynos_dsi_set_display_enable(dsi, false);
>  	drm_panel_disable(dsi->panel);
> +	drm_panel_unprepare(dsi->panel);
>  	exynos_dsi_poweroff(dsi);

I don't know Exynos very well, so this may be completely wrong, but
should disable_panel_prepare() be called much earlier than
drm_panel_enable() and drm_panel_unprepare() much later than
drm_panel_disable()? With the above the result is still the same, so
you'll get the same glitches as without their separation.

Without knowing exactly what Exynos does in the above, I'd expect the
correct sequence to be something like this:

	ret = exynos_dsi_power_on(dsi);
	if (ret < 0)
		return ret;

	ret = drm_panel_prepare(dsi->panel);
	if (ret < 0) {
		exynos_dsi_poweroff(dsi);
		return ret;
	}

	exynos_dsi_set_display_mode(dsi);
	exynos_dsi_set_display_enable(dsi, true);

	ret = drm_panel_enable(dsi->panel);
	if (ret < 0) {
		/* perhaps undo exynos_dsi_set_display_enable() here? */
		exynos_dsi_poweroff(dsi);
		return ret;
	}

And for disable:

	drm_panel_disable(dsi->panel);
	exynos_dsi_set_display_enable(dsi, false);
	drm_panel_unprepare(dsi->panel);
	exynos_dsi_poweroff(dsi);

Perhaps I should quote the kerneldoc that I added for drm_panel_funcs to
underline why I think this is important:

/**
 * struct drm_panel_funcs - perform operations on a given panel
 * @disable: disable panel (turn off back light, etc.)
 * @unprepare: turn off panel
 * @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
 * return the number of modes added
 *
 * The .prepare() function is typically called before the display controller
 * starts to transmit video data. Panel drivers can use this to turn the panel
 * on and wait for it to become ready. If additional configuration is required
 * (via a control bus such as I2C, SPI or DSI for example) this is a good time
 * to do that.
 *
 * After the display controller has started transmitting video data, it's safe
 * to call the .enable() function. This will typically enable the backlight to
 * make the image on screen visible. Some panels require a certain amount of
 * time or frames before the image is displayed. This function is responsible
 * for taking this into account before enabling the backlight to avoid visual
 * glitches.
 *
 * Before stopping video transmission from the display controller it can be
 * necessary to turn off the panel to avoid visual glitches. This is done in
 * the .disable() function. Analogously to .enable() this typically involves
 * turning off the backlight and waiting for some time to make sure no image
 * is visible on the panel. It is then safe for the display controller to
 * cease transmission of video data.
 *
 * To save power when no video data is transmitted, a driver can power down
 * the panel. This is the job of the .unprepare() function.
 */

As you see, .prepare() should do whatever is necessary to make the panel
accept a stream of video data, then the display driver can start sending
video data and call .enable() to make the transmitted data visible.

Analogously .disable() should turn off the display, so that the user can
no longer see what's going on, then the display controller can cease
transmission of video data (and since the panel is disabled this should
no longer cause visual glitches) and then call .unprepare() to turn the
panel off.

I know that this isn't immediately relevant just yet because currently
the backlight will already turn on by default, but like we discussed
earlier I have ideas on how to properly fix it. As a matter of fact I'll
go and send out another mail about that when I'm through this series.

>  static const struct drm_panel_funcs ld9040_drm_funcs = {
> +	.unprepare = ld9040_unprepare,
>  	.disable = ld9040_disable,
> +	.prepare = ld9040_prepare,
>  	.enable = ld9040_enable,
>  	.get_modes = ld9040_get_modes,
>  };

The patch I applied for .prepare() and .unprepare() I've reordered the
functions slightly to give a more natural sequence. .disable() is now
first, while .unprepare() is next, since that's the sequence that they
should be called in.

Patches for the panel drivers should follow this same ordering.

> diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
> index a251361..fb0cfe2 100644
> --- a/drivers/gpu/drm/panel/panel-simple.c
> +++ b/drivers/gpu/drm/panel/panel-simple.c
> @@ -45,7 +45,8 @@ struct panel_desc {
>  
>  struct panel_simple {
>  	struct drm_panel base;
> -	bool enabled;
> +	bool panel_enabled;
> +	bool backlight_enabled;

Perhaps this should rather be:

	bool prepared;
	bool enabled;

?

> diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c
> index 446837e..b574ee6 100644
> --- a/drivers/gpu/drm/tegra/output.c
> +++ b/drivers/gpu/drm/tegra/output.c
> @@ -139,9 +139,11 @@ static void tegra_encoder_dpms(struct drm_encoder *encoder, int mode)
>  
>  	if (mode != DRM_MODE_DPMS_ON) {
>  		drm_panel_disable(panel);
> +		drm_panel_unprepare(panel);
>  		tegra_output_disable(output);

Similarly to my comments for the Exynos drivers, this should be:

		drm_panel_disable(panel);
		tegra_output_disable(output);
		drm_panel_unprepare(panel);

>  	} else {
>  		tegra_output_enable(output);
> +		drm_panel_prepare(panel);
>  		drm_panel_enable(panel);
>  	}

and

		drm_panel_prepare(panel);
		tegra_output_enable(output);
		drm_panel_enable(panel);

Thierry

[-- Attachment #1.2: Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2014-07-30 10:32 UTC|newest]

Thread overview: 70+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-25 19:22 [PATCH V6 0/8] drm/exynos: few patches to enhance bridge chip support Ajay Kumar
2014-07-25 19:22 ` [PATCH V6 1/8] drm/panel: Add prepare, unprepare and get_modes routines Ajay Kumar
2014-07-30 10:00   ` Thierry Reding
2014-07-30 10:29     ` Ajay kumar
2014-07-25 19:22 ` [PATCH V6 2/8] drm/panel: Add support for prepare and unprepare routines Ajay Kumar
2014-07-30 10:32   ` Thierry Reding [this message]
2014-07-30 11:09     ` Ajay kumar
2014-07-25 19:22 ` [PATCH V6 3/8] drm/panel: simple: Add support for auo_b133htn01 panel Ajay Kumar
2014-07-30 10:51   ` Thierry Reding
2014-07-30 11:32     ` Ajay kumar
2014-07-30 13:30       ` Thierry Reding
2014-07-30 13:42         ` Ajay kumar
2014-07-25 19:22 ` [PATCH V6 4/8] drm/exynos: Move DP setup into commit() Ajay Kumar
2014-07-30 10:52   ` Thierry Reding
2014-07-30 12:05     ` Ajay kumar
2014-07-25 19:22 ` [PATCH V6 5/8] drm/exynos: dp: Modify driver to support drm_panel Ajay Kumar
2014-07-30 10:58   ` Thierry Reding
2014-07-25 19:22 ` [PATCH V6 6/8] drm/bridge: Modify drm_bridge core to support driver model Ajay Kumar
2014-07-30 11:19   ` Thierry Reding
2014-07-30 14:31     ` Ajay kumar
2014-07-30 15:08       ` Thierry Reding
2014-07-30 16:03         ` Ajay kumar
2014-07-31 10:58           ` Thierry Reding
2014-08-22 23:33             ` Javier Martinez Canillas
2014-08-25  6:11               ` Ajay kumar
2014-08-25 10:10                 ` Javier Martinez Canillas
2014-09-15 17:37   ` Laurent Pinchart
2014-09-17  9:07     ` Ajay kumar
2014-09-17  9:22       ` Dave Airlie
2014-09-17  9:27       ` Laurent Pinchart
2014-09-17 13:15         ` Ajay kumar
2014-09-22  7:40         ` Thierry Reding
2014-09-23  0:29           ` Laurent Pinchart
2014-09-23  5:36             ` Thierry Reding
2014-07-25 19:22 ` [PATCH V2 7/8] drm/bridge: Add i2c based driver for ptn3460 bridge Ajay Kumar
2014-07-30 12:05   ` Thierry Reding
2014-07-30 15:16     ` Ajay kumar
2014-07-30 15:40       ` Thierry Reding
2014-07-30 16:14         ` Ajay kumar
2014-07-31 11:21           ` Thierry Reding
2014-07-25 19:22 ` [PATCH V6 8/8] drm/bridge: Add i2c based driver for ps8622/ps8625 bridge Ajay Kumar
2014-07-29 11:29   ` Andreas Färber
2014-07-30  6:27     ` Ajay kumar
2014-07-30 13:11   ` Thierry Reding
2014-07-27 18:22 ` [PATCH V6 0/8] drm/exynos: few patches to enhance bridge chip support Andreas Färber
2014-07-28  6:13   ` Ajay kumar
2014-07-29 11:21     ` Andreas Färber
2014-07-29 11:36       ` Thierry Reding
2014-07-29 11:42         ` Andreas Färber
2014-07-29 11:47           ` Thierry Reding
2014-07-30  6:24             ` Ajay kumar
2014-07-30  9:40               ` Thierry Reding
2014-07-30 10:24                 ` Ajay kumar
2014-07-30 13:16                   ` Thierry Reding
2014-09-17  9:53                 ` Laurent Pinchart
2014-09-17 10:13                   ` Ajay kumar
2014-09-18  9:54                     ` Laurent Pinchart
2014-07-29 11:43         ` Thierry Reding
2014-07-30  6:21       ` Ajay kumar
2014-07-30 19:32         ` Andreas Färber
2014-07-31  8:38           ` Ajay kumar
2014-07-31  8:57             ` Andreas Färber
2014-07-31 10:07               ` Ajay kumar
2014-07-31 10:23               ` Thierry Reding
2014-07-31 10:28                 ` Andreas Färber
2014-07-31 14:22                 ` Andreas Färber
2014-08-01  7:02                   ` Ajay kumar
2014-08-01 12:13                     ` Andreas Färber
2014-08-01 14:57                     ` Andreas Färber
2014-07-30  9:56 ` Thierry Reding

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140730103239.GE29590@ulmo \
    --to=thierry.reding@gmail.com \
    --cc=ajaykumar.rs@samsung.com \
    --cc=ajaynumb@gmail.com \
    --cc=daniel.vetter@ffwll.ch \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=joshi@samsung.com \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=prashanth.g@samsung.com \
    --cc=seanpaul@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).