summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/omapdrm/omap_dmm_tiler.c34
-rw-r--r--drivers/staging/omapdrm/omap_drv.c14
-rw-r--r--drivers/staging/omapdrm/omap_drv.h4
-rw-r--r--drivers/staging/omapdrm/omap_gem.c28
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 59bf43899fc0..c42c5e500e02 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 dfdb4ba1e7c6..9d6a584113d2 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 cd1f22b0b124..f921027e7500 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 c38992b76fc9..08f1e292ed20 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)
{