diff options
author | Patrik Jakobsson <patrik.r.jakobsson@gmail.com> | 2014-01-04 22:11:17 +0100 |
---|---|---|
committer | Patrik Jakobsson <patrik.r.jakobsson@gmail.com> | 2014-03-17 20:11:53 +0100 |
commit | ae012bdc5799aafe88798f864bc05e90778229af (patch) | |
tree | f0b8360d13c718d2f3180e6d1c516405c25c4812 /drivers/gpu/drm/gma500/gtt.c | |
parent | 1c6b5d17d6ed124afd55027a72d64b6f6eca501e (diff) | |
download | op-kernel-dev-ae012bdc5799aafe88798f864bc05e90778229af.zip op-kernel-dev-ae012bdc5799aafe88798f864bc05e90778229af.tar.gz |
drm/gma500: Hook up the MMU
Properly init the MMU and add MMU entries when adding GTT entries
Signed-off-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/gma500/gtt.c')
-rw-r--r-- | drivers/gpu/drm/gma500/gtt.c | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c index 2db731f..a30f6ee 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); @@ -240,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); @@ -252,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: @@ -274,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); } @@ -497,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; @@ -512,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); } @@ -521,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); |