Message ID | 1355810564-1684-2-git-send-email-andy.gross@ti.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Tue, Dec 18, 2012 at 12:02 AM, Andy Gross <andy.gross@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@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@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@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel
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) {
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@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(-)