Commit ae012bdc authored by Patrik Jakobsson's avatar Patrik Jakobsson

drm/gma500: Hook up the MMU

Properly init the MMU and add MMU entries when adding GTT entries
Signed-off-by: default avatarPatrik Jakobsson <patrik.r.jakobsson@gmail.com>
parent 1c6b5d17
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include <linux/shmem_fs.h> #include <linux/shmem_fs.h>
#include "psb_drv.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, ...@@ -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 */ /* Write our page entries into the GTT itself */
for (i = r->roll; i < r->npage; i++) { 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++); iowrite32(pte, gtt_slot++);
} }
for (i = 0; i < r->roll; i++) { 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++); iowrite32(pte, gtt_slot++);
} }
/* Make sure all the entries are set before we return */ /* 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, ...@@ -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 * page table entries with the dummy page. This is protected via the gtt
* mutex which the caller must hold. * 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; struct drm_psb_private *dev_priv = dev->dev_private;
u32 __iomem *gtt_slot; u32 __iomem *gtt_slot;
...@@ -137,7 +140,8 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) ...@@ -137,7 +140,8 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
WARN_ON(r->stolen); WARN_ON(r->stolen);
gtt_slot = psb_gtt_entry(dev, r); 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++) for (i = 0; i < r->npage; i++)
iowrite32(pte, gtt_slot++); iowrite32(pte, gtt_slot++);
...@@ -176,11 +180,13 @@ void psb_gtt_roll(struct drm_device *dev, struct gtt_range *r, int roll) ...@@ -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); gtt_slot = psb_gtt_entry(dev, r);
for (i = r->roll; i < r->npage; i++) { 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++); iowrite32(pte, gtt_slot++);
} }
for (i = 0; i < r->roll; i++) { 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++); iowrite32(pte, gtt_slot++);
} }
ioread32(gtt_slot - 1); ioread32(gtt_slot - 1);
...@@ -240,6 +246,7 @@ int psb_gtt_pin(struct gtt_range *gt) ...@@ -240,6 +246,7 @@ int psb_gtt_pin(struct gtt_range *gt)
int ret = 0; int ret = 0;
struct drm_device *dev = gt->gem.dev; struct drm_device *dev = gt->gem.dev;
struct drm_psb_private *dev_priv = dev->dev_private; struct drm_psb_private *dev_priv = dev->dev_private;
u32 gpu_base = dev_priv->gtt.gatt_start;
mutex_lock(&dev_priv->gtt_mutex); mutex_lock(&dev_priv->gtt_mutex);
...@@ -252,6 +259,9 @@ int psb_gtt_pin(struct gtt_range *gt) ...@@ -252,6 +259,9 @@ int psb_gtt_pin(struct gtt_range *gt)
psb_gtt_detach_pages(gt); psb_gtt_detach_pages(gt);
goto out; 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++; gt->in_gart++;
out: out:
...@@ -274,16 +284,30 @@ void psb_gtt_unpin(struct gtt_range *gt) ...@@ -274,16 +284,30 @@ void psb_gtt_unpin(struct gtt_range *gt)
{ {
struct drm_device *dev = gt->gem.dev; struct drm_device *dev = gt->gem.dev;
struct drm_psb_private *dev_priv = dev->dev_private; 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); 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); WARN_ON(!gt->in_gart);
gt->in_gart--; gt->in_gart--;
if (gt->in_gart == 0 && gt->stolen == 0) { 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_remove(dev, gt);
psb_gtt_detach_pages(gt); psb_gtt_detach_pages(gt);
} }
out:
mutex_unlock(&dev_priv->gtt_mutex); mutex_unlock(&dev_priv->gtt_mutex);
} }
...@@ -497,6 +521,7 @@ int psb_gtt_init(struct drm_device *dev, int resume) ...@@ -497,6 +521,7 @@ int psb_gtt_init(struct drm_device *dev, int resume)
if (!resume) if (!resume)
dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base,
stolen_size); 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;
...@@ -512,7 +537,7 @@ int psb_gtt_init(struct drm_device *dev, int resume) ...@@ -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", dev_dbg(dev->dev, "Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n",
num_pages, pfn_base << PAGE_SHIFT, 0); num_pages, pfn_base << PAGE_SHIFT, 0);
for (i = 0; i < num_pages; ++i) { 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); iowrite32(pte, dev_priv->gtt_map + i);
} }
...@@ -521,7 +546,7 @@ int psb_gtt_init(struct drm_device *dev, int resume) ...@@ -521,7 +546,7 @@ int psb_gtt_init(struct drm_device *dev, int resume)
*/ */
pfn_base = page_to_pfn(dev_priv->scratch_page); 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) for (; i < gtt_pages; ++i)
iowrite32(pte, dev_priv->gtt_map + i); iowrite32(pte, dev_priv->gtt_map + i);
......
...@@ -192,12 +192,18 @@ static int psb_do_init(struct drm_device *dev) ...@@ -192,12 +192,18 @@ static int psb_do_init(struct drm_device *dev)
PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0); PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0);
PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK1); PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK1);
PSB_RSGX32(PSB_CR_BIF_BANK1); PSB_RSGX32(PSB_CR_BIF_BANK1);
PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_MMU_ER_MASK,
/* Do not bypass any MMU access, let them pagefault instead */
PSB_WSGX32((PSB_RSGX32(PSB_CR_BIF_CTRL) & ~_PSB_MMU_ER_MASK),
PSB_CR_BIF_CTRL); PSB_CR_BIF_CTRL);
PSB_RSGX32(PSB_CR_BIF_CTRL);
psb_spank(dev_priv); psb_spank(dev_priv);
/* mmu_gatt ?? */ /* mmu_gatt ?? */
PSB_WSGX32(pg->gatt_start, PSB_CR_BIF_TWOD_REQ_BASE); PSB_WSGX32(pg->gatt_start, PSB_CR_BIF_TWOD_REQ_BASE);
PSB_RSGX32(PSB_CR_BIF_TWOD_REQ_BASE); /* Post */
return 0; return 0;
out_err: out_err:
return ret; return ret;
...@@ -277,6 +283,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) ...@@ -277,6 +283,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
int ret = -ENOMEM; int ret = -ENOMEM;
struct drm_connector *connector; struct drm_connector *connector;
struct gma_encoder *gma_encoder; struct gma_encoder *gma_encoder;
struct psb_gtt *pg;
dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
if (dev_priv == NULL) if (dev_priv == NULL)
...@@ -286,6 +293,8 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) ...@@ -286,6 +293,8 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
dev_priv->dev = dev; dev_priv->dev = dev;
dev->dev_private = (void *) dev_priv; dev->dev_private = (void *) dev_priv;
pg = &dev_priv->gtt;
pci_set_master(dev->pdev); pci_set_master(dev->pdev);
dev_priv->num_pipe = dev_priv->ops->pipes; dev_priv->num_pipe = dev_priv->ops->pipes;
...@@ -355,13 +364,21 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) ...@@ -355,13 +364,21 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
if (!dev_priv->pf_pd) if (!dev_priv->pf_pd)
goto out_err; goto out_err;
psb_mmu_set_pd_context(psb_mmu_get_default_pd(dev_priv->mmu), 0);
psb_mmu_set_pd_context(dev_priv->pf_pd, 1);
ret = psb_do_init(dev); ret = psb_do_init(dev);
if (ret) if (ret)
return ret; return ret;
/* Add stolen memory to SGX MMU */
down_read(&pg->sem);
ret = psb_mmu_insert_pfn_sequence(psb_mmu_get_default_pd(dev_priv->mmu),
dev_priv->stolen_base >> PAGE_SHIFT,
pg->gatt_start,
pg->stolen_size >> PAGE_SHIFT, 0);
up_read(&pg->sem);
psb_mmu_set_pd_context(psb_mmu_get_default_pd(dev_priv->mmu), 0);
psb_mmu_set_pd_context(dev_priv->pf_pd, 1);
PSB_WSGX32(0x20000000, PSB_CR_PDS_EXEC_BASE); PSB_WSGX32(0x20000000, PSB_CR_PDS_EXEC_BASE);
PSB_WSGX32(0x30000000, PSB_CR_BIF_3D_REQ_BASE); PSB_WSGX32(0x30000000, PSB_CR_BIF_3D_REQ_BASE);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment