diff options
Diffstat (limited to 'drivers/gpu/drm/gma500/gtt.c')
| -rw-r--r-- | drivers/gpu/drm/gma500/gtt.c | 46 | 
1 files changed, 36 insertions, 10 deletions
diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c index 92babac362e..592d205a008 100644 --- a/drivers/gpu/drm/gma500/gtt.c +++ b/drivers/gpu/drm/gma500/gtt.c @@ -22,6 +22,7 @@  #include <drm/drmP.h>  #include <linux/shmem_fs.h>  #include "psb_drv.h" +#include "blitter.h"  /* @@ -105,11 +106,13 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r,  	/* Write our page entries into the GTT itself */  	for (i = r->roll; i < r->npage; i++) { -		pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0); +		pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), +				       PSB_MMU_CACHED_MEMORY);  		iowrite32(pte, gtt_slot++);  	}  	for (i = 0; i < r->roll; i++) { -		pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0); +		pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), +				       PSB_MMU_CACHED_MEMORY);  		iowrite32(pte, gtt_slot++);  	}  	/* Make sure all the entries are set before we return */ @@ -127,7 +130,7 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r,   *	page table entries with the dummy page. This is protected via the gtt   *	mutex which the caller must hold.   */ -static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) +void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)  {  	struct drm_psb_private *dev_priv = dev->dev_private;  	u32 __iomem *gtt_slot; @@ -137,7 +140,8 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)  	WARN_ON(r->stolen);  	gtt_slot = psb_gtt_entry(dev, r); -	pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), 0); +	pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), +			       PSB_MMU_CACHED_MEMORY);  	for (i = 0; i < r->npage; i++)  		iowrite32(pte, gtt_slot++); @@ -176,11 +180,13 @@ void psb_gtt_roll(struct drm_device *dev, struct gtt_range *r, int roll)  	gtt_slot = psb_gtt_entry(dev, r);  	for (i = r->roll; i < r->npage; i++) { -		pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0); +		pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), +				       PSB_MMU_CACHED_MEMORY);  		iowrite32(pte, gtt_slot++);  	}  	for (i = 0; i < r->roll; i++) { -		pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0); +		pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), +				       PSB_MMU_CACHED_MEMORY);  		iowrite32(pte, gtt_slot++);  	}  	ioread32(gtt_slot - 1); @@ -204,6 +210,7 @@ static int psb_gtt_attach_pages(struct gtt_range *gt)  	if (IS_ERR(pages))  		return PTR_ERR(pages); +	gt->npage = gt->gem.size / PAGE_SIZE;  	gt->pages = pages;  	return 0; @@ -239,6 +246,7 @@ int psb_gtt_pin(struct gtt_range *gt)  	int ret = 0;  	struct drm_device *dev = gt->gem.dev;  	struct drm_psb_private *dev_priv = dev->dev_private; +	u32 gpu_base = dev_priv->gtt.gatt_start;  	mutex_lock(&dev_priv->gtt_mutex); @@ -251,6 +259,9 @@ int psb_gtt_pin(struct gtt_range *gt)  			psb_gtt_detach_pages(gt);  			goto out;  		} +		psb_mmu_insert_pages(psb_mmu_get_default_pd(dev_priv->mmu), +				     gt->pages, (gpu_base + gt->offset), +				     gt->npage, 0, 0, PSB_MMU_CACHED_MEMORY);  	}  	gt->in_gart++;  out: @@ -273,16 +284,30 @@ void psb_gtt_unpin(struct gtt_range *gt)  {  	struct drm_device *dev = gt->gem.dev;  	struct drm_psb_private *dev_priv = dev->dev_private; +	u32 gpu_base = dev_priv->gtt.gatt_start; +	int ret; +	/* While holding the gtt_mutex no new blits can be initiated */  	mutex_lock(&dev_priv->gtt_mutex); +	/* Wait for any possible usage of the memory to be finished */ +	ret = gma_blt_wait_idle(dev_priv); +	if (ret) { +		DRM_ERROR("Failed to idle the blitter, unpin failed!"); +		goto out; +	} +  	WARN_ON(!gt->in_gart);  	gt->in_gart--;  	if (gt->in_gart == 0 && gt->stolen == 0) { +		psb_mmu_remove_pages(psb_mmu_get_default_pd(dev_priv->mmu), +				     (gpu_base + gt->offset), gt->npage, 0, 0);  		psb_gtt_remove(dev, gt);  		psb_gtt_detach_pages(gt);  	} + +out:  	mutex_unlock(&dev_priv->gtt_mutex);  } @@ -305,7 +330,7 @@ void psb_gtt_unpin(struct gtt_range *gt)   *	as in use.   */  struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, -						const char *name, int backed) +				      const char *name, int backed, u32 align)  {  	struct drm_psb_private *dev_priv = dev->dev_private;  	struct gtt_range *gt; @@ -333,7 +358,7 @@ struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,  	/* Ensure this is set for non GEM objects */  	gt->gem.dev = dev;  	ret = allocate_resource(dev_priv->gtt_mem, >->resource, -				len, start, end, PAGE_SIZE, NULL, NULL); +				len, start, end, align, NULL, NULL);  	if (ret == 0) {  		gt->offset = gt->resource.start - r->start;  		return gt; @@ -496,6 +521,7 @@ int psb_gtt_init(struct drm_device *dev, int resume)  	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; @@ -511,7 +537,7 @@ int psb_gtt_init(struct drm_device *dev, int resume)  	dev_dbg(dev->dev, "Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n",  		num_pages, pfn_base << PAGE_SHIFT, 0);  	for (i = 0; i < num_pages; ++i) { -		pte = psb_gtt_mask_pte(pfn_base + i, 0); +		pte = psb_gtt_mask_pte(pfn_base + i, PSB_MMU_CACHED_MEMORY);  		iowrite32(pte, dev_priv->gtt_map + i);  	} @@ -520,7 +546,7 @@ int psb_gtt_init(struct drm_device *dev, int resume)  	 */  	pfn_base = page_to_pfn(dev_priv->scratch_page); -	pte = psb_gtt_mask_pte(pfn_base, 0); +	pte = psb_gtt_mask_pte(pfn_base, PSB_MMU_CACHED_MEMORY);  	for (; i < gtt_pages; ++i)  		iowrite32(pte, dev_priv->gtt_map + i);  | 
