[PATCH 1/2] drm/omap: Add PM capabilities

Rob Clark rob at ti.com
Tue Dec 18 16:18:08 PST 2012


On Tue, Dec 18, 2012 at 12:02 AM, Andy Gross <andy.gross at ti.com> wrote:
> Added resume hooks that will be called on resuming from DEVICE_OFF.
> The dmm portion of the patch reprograms the LUT to point to the dummy
> pages.  The omapdrm portion of the patch repins the buffers into the
> DMM.
>
> Signed-off-by: Andy Gross <andy.gross at ti.com>

I am sort of thinking it might be worth a comment somewhere explaining
why this works (ie. resume order between the two platform devices),
even if only in the commit msg.  But with that:

Signed-off-by: Rob Clark <rob at ti.com>

> ---
>  drivers/staging/omapdrm/omap_dmm_tiler.c |   34 ++++++++++++++++++++++++++++++
>  drivers/staging/omapdrm/omap_drv.c       |   14 ++++++++++++
>  drivers/staging/omapdrm/omap_drv.h       |    4 +++
>  drivers/staging/omapdrm/omap_gem.c       |   28 ++++++++++++++++++++++++
>  4 files changed, 80 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c b/drivers/staging/omapdrm/omap_dmm_tiler.c
> index 59bf438..c42c5e5 100644
> --- a/drivers/staging/omapdrm/omap_dmm_tiler.c
> +++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
> @@ -903,12 +903,46 @@ error:
>  }
>  #endif
>
> +#ifdef CONFIG_PM
> +static int omap_dmm_resume(struct device *dev)
> +{
> +       struct tcm_area area;
> +       int i;
> +
> +       if (!omap_dmm)
> +               return -ENODEV;
> +
> +       area = (struct tcm_area) {
> +               .is2d = true,
> +               .tcm = NULL,
> +               .p1.x = omap_dmm->container_width - 1,
> +               .p1.y = omap_dmm->container_height - 1,
> +       };
> +
> +       /* initialize all LUTs to dummy page entries */
> +       for (i = 0; i < omap_dmm->num_lut; i++) {
> +               area.tcm = omap_dmm->tcm[i];
> +               if (fill(&area, NULL, 0, 0, true))
> +                       dev_err(dev, "refill failed");
> +       }
> +
> +       return 0;
> +}
> +
> +static const struct dev_pm_ops omap_dmm_pm_ops = {
> +       .resume = omap_dmm_resume,
> +};
> +#endif
> +
>  struct platform_driver omap_dmm_driver = {
>         .probe = omap_dmm_probe,
>         .remove = omap_dmm_remove,
>         .driver = {
>                 .owner = THIS_MODULE,
>                 .name = DMM_DRIVER_NAME,
> +#ifdef CONFIG_PM
> +               .pm = &omap_dmm_pm_ops,
> +#endif
>         },
>  };
>
> diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c
> index ae5ecc2..d246f85 100644
> --- a/drivers/staging/omapdrm/omap_drv.c
> +++ b/drivers/staging/omapdrm/omap_drv.c
> @@ -368,6 +368,9 @@ static int dev_load(struct drm_device *dev, unsigned long flags)
>                 /* well, limp along without an fbdev.. maybe X11 will work? */
>         }
>
> +       /* store off drm_device for use in pm ops */
> +       dev_set_drvdata(dev->dev, dev);
> +
>         drm_kms_helper_poll_init(dev);
>
>         return 0;
> @@ -393,6 +396,8 @@ static int dev_unload(struct drm_device *dev)
>         kfree(dev->dev_private);
>         dev->dev_private = NULL;
>
> +       dev_set_drvdata(dev->dev, NULL);
> +
>         return 0;
>  }
>
> @@ -558,10 +563,19 @@ static int pdev_remove(struct platform_device *device)
>         return 0;
>  }
>
> +#ifdef CONFIG_PM
> +static const struct dev_pm_ops omapdrm_pm_ops = {
> +       .resume = omap_gem_resume,
> +};
> +#endif
> +
>  struct platform_driver pdev = {
>                 .driver = {
>                         .name = DRIVER_NAME,
>                         .owner = THIS_MODULE,
> +#ifdef CONFIG_PM
> +                       .pm = &omapdrm_pm_ops,
> +#endif
>                 },
>                 .probe = pdev_probe,
>                 .remove = pdev_remove,
> diff --git a/drivers/staging/omapdrm/omap_drv.h b/drivers/staging/omapdrm/omap_drv.h
> index cd1f22b..f921027 100644
> --- a/drivers/staging/omapdrm/omap_drv.h
> +++ b/drivers/staging/omapdrm/omap_drv.h
> @@ -135,6 +135,10 @@ void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m);
>  void omap_gem_describe_objects(struct list_head *list, struct seq_file *m);
>  #endif
>
> +#ifdef CONFIG_PM
> +int omap_gem_resume(struct device *dev);
> +#endif
> +
>  int omap_irq_enable_vblank(struct drm_device *dev, int crtc);
>  void omap_irq_disable_vblank(struct drm_device *dev, int crtc);
>  irqreturn_t omap_irq_handler(DRM_IRQ_ARGS);
> diff --git a/drivers/staging/omapdrm/omap_gem.c b/drivers/staging/omapdrm/omap_gem.c
> index c38992b..08f1e292 100644
> --- a/drivers/staging/omapdrm/omap_gem.c
> +++ b/drivers/staging/omapdrm/omap_gem.c
> @@ -964,6 +964,34 @@ void *omap_gem_vaddr(struct drm_gem_object *obj)
>         return omap_obj->vaddr;
>  }
>
> +#ifdef CONFIG_PM
> +/* re-pin objects in DMM in resume path: */
> +int omap_gem_resume(struct device *dev)
> +{
> +       struct drm_device *drm_dev = dev_get_drvdata(dev);
> +       struct omap_drm_private *priv = drm_dev->dev_private;
> +       struct omap_gem_object *omap_obj;
> +       int ret = 0;
> +
> +       list_for_each_entry(omap_obj, &priv->obj_list, mm_list) {
> +               if (omap_obj->block) {
> +                       struct drm_gem_object *obj = &omap_obj->base;
> +                       uint32_t npages = obj->size >> PAGE_SHIFT;
> +                       WARN_ON(!omap_obj->pages);  /* this can't happen */
> +                       ret = tiler_pin(omap_obj->block,
> +                                       omap_obj->pages, npages,
> +                                       omap_obj->roll, true);
> +                       if (ret) {
> +                               dev_err(dev, "could not repin: %d\n", ret);
> +                               return ret;
> +                       }
> +               }
> +       }
> +
> +       return 0;
> +}
> +#endif
> +
>  #ifdef CONFIG_DEBUG_FS
>  void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m)
>  {
> --
> 1.7.5.4
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel


More information about the dri-devel mailing list