drm/gma500: Add support for rebuilding the gtt
authorPatrik Jakobsson <patrik.r.jakobsson@gmail.com>
Fri, 5 Apr 2013 21:56:18 +0000 (23:56 +0200)
committerPatrik Jakobsson <patrik.r.jakobsson@gmail.com>
Sun, 7 Apr 2013 15:09:05 +0000 (17:09 +0200)
Signed-off-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
drivers/gpu/drm/gma500/gtt.c
drivers/gpu/drm/gma500/gtt.h

index 04a371aceb349359bd405ff787174cbb154ab3e1..2f12fafc8931eea2ff7ff339fcd4f824523547f5 100644 (file)
@@ -80,7 +80,8 @@ static u32 __iomem *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
  *     the GTT. This is protected via the gtt mutex which the caller
  *     must hold.
  */
-static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
+static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r,
+                         int resume)
 {
        u32 __iomem *gtt_slot;
        u32 pte;
@@ -97,8 +98,10 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
        gtt_slot = psb_gtt_entry(dev, r);
        pages = r->pages;
 
-       /* Make sure changes are visible to the GPU */
-       set_pages_array_wc(pages, r->npage);
+       if (!resume) {
+               /* Make sure changes are visible to the GPU */
+               set_pages_array_wc(pages, r->npage);
+       }
 
        /* Write our page entries into the GTT itself */
        for (i = r->roll; i < r->npage; i++) {
@@ -269,7 +272,7 @@ int psb_gtt_pin(struct gtt_range *gt)
                ret = psb_gtt_attach_pages(gt);
                if (ret < 0)
                        goto out;
-               ret = psb_gtt_insert(dev, gt);
+               ret = psb_gtt_insert(dev, gt, 0);
                if (ret < 0) {
                        psb_gtt_detach_pages(gt);
                        goto out;
@@ -421,9 +424,11 @@ int psb_gtt_init(struct drm_device *dev, int resume)
        int ret = 0;
        uint32_t pte;
 
-       mutex_init(&dev_priv->gtt_mutex);
+       if (!resume) {
+               mutex_init(&dev_priv->gtt_mutex);
+               psb_gtt_alloc(dev);
+       }
 
-       psb_gtt_alloc(dev);
        pg = &dev_priv->gtt;
 
        /* Enable the GTT */
@@ -505,7 +510,8 @@ int psb_gtt_init(struct drm_device *dev, int resume)
        /*
         *      Map the GTT and the stolen memory area
         */
-       dev_priv->gtt_map = ioremap_nocache(pg->gtt_phys_start,
+       if (!resume)
+               dev_priv->gtt_map = ioremap_nocache(pg->gtt_phys_start,
                                                gtt_pages << PAGE_SHIFT);
        if (!dev_priv->gtt_map) {
                dev_err(dev->dev, "Failure to map gtt.\n");
@@ -513,7 +519,9 @@ int psb_gtt_init(struct drm_device *dev, int resume)
                goto out_err;
        }
 
-       dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, stolen_size);
+       if (!resume)
+               dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base,
+                                                stolen_size);
        if (!dev_priv->vram_addr) {
                dev_err(dev->dev, "Failure to map stolen base.\n");
                ret = -ENOMEM;
@@ -549,3 +557,24 @@ out_err:
        psb_gtt_takedown(dev);
        return ret;
 }
+
+int psb_gtt_restore(struct drm_device *dev)
+{
+       struct drm_psb_private *dev_priv = dev->dev_private;
+       struct resource *r = dev_priv->gtt_mem->child;
+       struct gtt_range *range;
+
+       /* On resume, the gtt_mutex is already initialized */
+       mutex_lock(&dev_priv->gtt_mutex);
+       psb_gtt_init(dev, 1);
+
+       while (r != NULL) {
+               range = container_of(r, struct gtt_range, resource);
+               if (range->pages)
+                       psb_gtt_insert(dev, range, 1);
+               r = r->sibling;
+       }
+       mutex_unlock(&dev_priv->gtt_mutex);
+
+       return 0;
+}
index aa1742387f5a6ed2f3c9c990f8b1f1a29e3cf7fa..6191d10acf33286f9f768e57aad30c59ef49bbfc 100644 (file)
@@ -60,5 +60,5 @@ extern int psb_gtt_pin(struct gtt_range *gt);
 extern void psb_gtt_unpin(struct gtt_range *gt);
 extern void psb_gtt_roll(struct drm_device *dev,
                                        struct gtt_range *gt, int roll);
-
+extern int psb_gtt_restore(struct drm_device *dev);
 #endif