diff options
author | Dave Airlie <airlied@redhat.com> | 2013-04-17 15:18:32 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-04-17 15:18:32 +1000 |
commit | 9f7bc6acf78af238a0b8ee0bb86ab62f1fc4f51f (patch) | |
tree | b1083136e21199935c9811bc9f41905f3c5f0499 /drivers/gpu/drm/gma500/gtt.c | |
parent | f18353eee7570412adca210b4968ecf2783754ba (diff) | |
parent | 1611f8457768716ba2397e0cdcc92c863cf9b58b (diff) | |
download | linux-9f7bc6acf78af238a0b8ee0bb86ab62f1fc4f51f.tar.bz2 |
Merge branch 'gma500-next' of git://github.com/patjak/drm-gma500 into drm-next
Patrik writes:
I haven't had much review or testing on other platforms than Poulsbo but
at least the following Cedarview bug has been squashed and no
regressions reported: https://bugs.freedesktop.org/show_bug.cgi?id=58527
* 'gma500-next' of git://github.com/patjak/drm-gma500:
drm/gma500: Add debugging info to psb_gtt_restore()
drm/gma500: Check connector status before restoring sdvo
gma500:fix build failure for 3.9-rc5
drm/gma500: Fix hibernation problems on sdvo encoders
drm/gma500: Add hooks for hibernation
drm/gma500: Activate the gtt rebuild on suspend/resume
drm/gma500: Add support for rebuilding the gtt
drm/gma500: Change fb name so pm-utils doesn't apply quirks
gma500: Make VGA and HDMI connector hotpluggable
drm/gma500: Clean up various defines
drm/gma500: Remove unnecessary function exposure
drm/gma500: Type clock limits directly into array and remove defines
drm/gma500: Calculate clock in one function instead of three identical
drm/gma500: Remove unused i8xx clock limits
gma500: medfield: Fix possible NULL pointer dereference
drivers: gpu: drm: gma500: Replaced calls kzalloc & memcpy with kmemdup
gma500: remove unused drm_psb_no_fb
Diffstat (limited to 'drivers/gpu/drm/gma500/gtt.c')
-rw-r--r-- | drivers/gpu/drm/gma500/gtt.c | 52 |
1 files changed, 44 insertions, 8 deletions
diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c index 054e26e769ec..1f82183536a3 100644 --- a/drivers/gpu/drm/gma500/gtt.c +++ b/drivers/gpu/drm/gma500/gtt.c @@ -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,31 @@ 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; + unsigned int restored = 0, total = 0, size = 0; + + /* 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); + size += range->resource.end - range->resource.start; + restored++; + } + r = r->sibling; + total++; + } + mutex_unlock(&dev_priv->gtt_mutex); + DRM_DEBUG_DRIVER("Restored %u of %u gtt ranges (%u KB)", restored, + total, (size / 1024)); + + return 0; +} |