Commit 070839ea authored by Patrik Jakobsson's avatar Patrik Jakobsson

drm/gma500: Add support for rebuilding the gtt

Signed-off-by: default avatarPatrik Jakobsson <patrik.r.jakobsson@gmail.com>
parent f9d8149a
...@@ -80,7 +80,8 @@ static u32 __iomem *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r) ...@@ -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 * the GTT. This is protected via the gtt mutex which the caller
* must hold. * 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 __iomem *gtt_slot;
u32 pte; u32 pte;
...@@ -97,8 +98,10 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r) ...@@ -97,8 +98,10 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
gtt_slot = psb_gtt_entry(dev, r); gtt_slot = psb_gtt_entry(dev, r);
pages = r->pages; pages = r->pages;
if (!resume) {
/* Make sure changes are visible to the GPU */ /* Make sure changes are visible to the GPU */
set_pages_array_wc(pages, r->npage); set_pages_array_wc(pages, r->npage);
}
/* Write our page entries into the GTT itself */ /* Write our page entries into the GTT itself */
for (i = r->roll; i < r->npage; i++) { for (i = r->roll; i < r->npage; i++) {
...@@ -269,7 +272,7 @@ int psb_gtt_pin(struct gtt_range *gt) ...@@ -269,7 +272,7 @@ int psb_gtt_pin(struct gtt_range *gt)
ret = psb_gtt_attach_pages(gt); ret = psb_gtt_attach_pages(gt);
if (ret < 0) if (ret < 0)
goto out; goto out;
ret = psb_gtt_insert(dev, gt); ret = psb_gtt_insert(dev, gt, 0);
if (ret < 0) { if (ret < 0) {
psb_gtt_detach_pages(gt); psb_gtt_detach_pages(gt);
goto out; goto out;
...@@ -421,9 +424,11 @@ int psb_gtt_init(struct drm_device *dev, int resume) ...@@ -421,9 +424,11 @@ int psb_gtt_init(struct drm_device *dev, int resume)
int ret = 0; int ret = 0;
uint32_t pte; uint32_t pte;
if (!resume) {
mutex_init(&dev_priv->gtt_mutex); mutex_init(&dev_priv->gtt_mutex);
psb_gtt_alloc(dev); psb_gtt_alloc(dev);
}
pg = &dev_priv->gtt; pg = &dev_priv->gtt;
/* Enable the GTT */ /* Enable the GTT */
...@@ -505,6 +510,7 @@ int psb_gtt_init(struct drm_device *dev, int resume) ...@@ -505,6 +510,7 @@ int psb_gtt_init(struct drm_device *dev, int resume)
/* /*
* Map the GTT and the stolen memory area * Map the GTT and the stolen memory area
*/ */
if (!resume)
dev_priv->gtt_map = ioremap_nocache(pg->gtt_phys_start, dev_priv->gtt_map = ioremap_nocache(pg->gtt_phys_start,
gtt_pages << PAGE_SHIFT); gtt_pages << PAGE_SHIFT);
if (!dev_priv->gtt_map) { if (!dev_priv->gtt_map) {
...@@ -513,7 +519,9 @@ int psb_gtt_init(struct drm_device *dev, int resume) ...@@ -513,7 +519,9 @@ int psb_gtt_init(struct drm_device *dev, int resume)
goto out_err; 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) { if (!dev_priv->vram_addr) {
dev_err(dev->dev, "Failure to map stolen base.\n"); dev_err(dev->dev, "Failure to map stolen base.\n");
ret = -ENOMEM; ret = -ENOMEM;
...@@ -549,3 +557,24 @@ int psb_gtt_init(struct drm_device *dev, int resume) ...@@ -549,3 +557,24 @@ int psb_gtt_init(struct drm_device *dev, int resume)
psb_gtt_takedown(dev); psb_gtt_takedown(dev);
return ret; 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;
}
...@@ -60,5 +60,5 @@ extern int psb_gtt_pin(struct gtt_range *gt); ...@@ -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_unpin(struct gtt_range *gt);
extern void psb_gtt_roll(struct drm_device *dev, extern void psb_gtt_roll(struct drm_device *dev,
struct gtt_range *gt, int roll); struct gtt_range *gt, int roll);
extern int psb_gtt_restore(struct drm_device *dev);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment