drm/gma500: Add support for rebuilding the gtt
Signed-off-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
This commit is contained in:
parent
f9d8149ac1
commit
070839ea54
2 changed files with 38 additions and 9 deletions
|
@ -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)
|
||||||
gtt_slot = psb_gtt_entry(dev, r);
|
gtt_slot = psb_gtt_entry(dev, r);
|
||||||
pages = r->pages;
|
pages = r->pages;
|
||||||
|
|
||||||
/* Make sure changes are visible to the GPU */
|
if (!resume) {
|
||||||
set_pages_array_wc(pages, r->npage);
|
/* Make sure changes are visible to the GPU */
|
||||||
|
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)
|
||||||
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)
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
uint32_t pte;
|
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;
|
pg = &dev_priv->gtt;
|
||||||
|
|
||||||
/* Enable the 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
|
* 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);
|
gtt_pages << PAGE_SHIFT);
|
||||||
if (!dev_priv->gtt_map) {
|
if (!dev_priv->gtt_map) {
|
||||||
dev_err(dev->dev, "Failure to map gtt.\n");
|
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;
|
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 @@ out_err:
|
||||||
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);
|
||||||
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
|
||||||
|
|
Loading…
Add table
Reference in a new issue