[RFC PATCH] staging: imx-drm: add suspend / resume

Fabio Estevam festevam at gmail.com
Thu Mar 20 15:31:48 UTC 2014


Hi Martin,

On Thu, Mar 20, 2014 at 12:17 PM, Martin Fuzzey <mfuzzey at parkeon.com> wrote:
> Currently i.MX53 boards with the imx-drm display driver active
> fail an intensive suspend to ram / resume test.
>
> After around 5 - 50 cycles it is no longer possible to resume
> the board.
>
> The culprit is the imx-drm driver which does not stop DMA
> before suspending. Removing the driver "fixes" the problem.
>
> This patch provides a minimal suspend / resume implementation
> enabling the intensive test to work (500 cycles ok).
>
> I am only sending this as RFC for the moment since I don't
> really know the hardware or driver code well enough to be
> sure this is the "right" way of doing it.

Does this patch still cause the visual artifacts you mentioned earlier?

Regards,

Fabio Estevam

>
> Signed-off-by: Martin Fuzzey <mfuzzey at parkeon.com>
> ---
>  drivers/staging/imx-drm/ipu-v3/ipu-common.c |   47 +++++++++++++++++++++++++++
>  drivers/staging/imx-drm/ipu-v3/ipu-prv.h    |    1 +
>  2 files changed, 48 insertions(+)
>
> diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-common.c b/drivers/staging/imx-drm/ipu-v3/ipu-common.c
> index 97ca692..484a90a 100644
> --- a/drivers/staging/imx-drm/ipu-v3/ipu-common.c
> +++ b/drivers/staging/imx-drm/ipu-v3/ipu-common.c
> @@ -692,6 +692,8 @@ int ipu_idmac_enable_channel(struct ipuv3_channel *channel)
>         val |= idma_mask(channel->num);
>         ipu_idmac_write(ipu, val, IDMAC_CHA_EN(channel->num));
>
> +       channel->enabled = true;
> +
>         spin_unlock_irqrestore(&ipu->lock, flags);
>
>         return 0;
> @@ -750,6 +752,8 @@ int ipu_idmac_disable_channel(struct ipuv3_channel *channel)
>         val &= ~idma_mask(channel->num);
>         ipu_cm_write(ipu, val, IPU_CHA_DB_MODE_SEL(channel->num));
>
> +       channel->enabled = false;
> +
>         spin_unlock_irqrestore(&ipu->lock, flags);
>
>         return 0;
> @@ -1245,10 +1249,53 @@ static int ipu_remove(struct platform_device *pdev)
>         return 0;
>  }
>
> +#ifdef CONFIG_PM_SLEEP
> +
> +static int ipu_suspend(struct device *dev)
> +{
> +       struct ipu_soc *ipu = dev_get_drvdata(dev);
> +       struct ipuv3_channel *channel;
> +       int i;
> +
> +       channel = ipu->channel;
> +       for (i = 0; i < ARRAY_SIZE(ipu->channel); i++, channel++) {
> +               channel->suspended = false;
> +               if (channel->enabled) {
> +                       if (ipu_idmac_wait_busy(channel, 50))
> +                               dev_warn(dev,
> +                                       "%s: Timeout channel %d idle\n",
> +                                       __func__, i);
> +                       ipu_idmac_disable_channel(channel);
> +                       channel->suspended = true;
> +               }
> +       }
> +       return 0;
> +}
> +
> +static int ipu_resume(struct device *dev)
> +{
> +       struct ipu_soc *ipu = dev_get_drvdata(dev);
> +       struct ipuv3_channel *channel;
> +       int i;
> +
> +       channel = ipu->channel;
> +       for (i = 0; i < ARRAY_SIZE(ipu->channel); i++, channel++) {
> +               if (channel->suspended) {
> +                       ipu_idmac_enable_channel(channel);
> +                       channel->suspended = false;
> +               }
> +       }
> +       return 0;
> +}
> +#endif
> +
> +static SIMPLE_DEV_PM_OPS(ipu_pm_ops, ipu_suspend, ipu_resume);
> +
>  static struct platform_driver imx_ipu_driver = {
>         .driver = {
>                 .name = "imx-ipuv3",
>                 .of_match_table = imx_ipu_dt_ids,
> +               .pm = &ipu_pm_ops,
>         },
>         .probe = ipu_probe,
>         .remove = ipu_remove,
> diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-prv.h b/drivers/staging/imx-drm/ipu-v3/ipu-prv.h
> index 4df0050..233749a 100644
> --- a/drivers/staging/imx-drm/ipu-v3/ipu-prv.h
> +++ b/drivers/staging/imx-drm/ipu-v3/ipu-prv.h
> @@ -144,6 +144,7 @@ struct ipuv3_channel {
>
>         bool enabled;
>         bool busy;
> +       bool suspended;
>
>         struct ipu_soc *ipu;
>  };
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


More information about the devel mailing list