|
@@ -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);
|
|
|
|