Commit d339386c authored by Thomas Zimmermann's avatar Thomas Zimmermann Committed by Patrik Jakobsson

drm/gma500: Move GEM memory management functions to gem.c

Move GEM functions from gtt.c to gem.c. Adapt some names. No
functional changes.
Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Acked-by: default avatarPatrik Jakobsson <patrik.r.jakobsson@gmail.com>
Signed-off-by: default avatarPatrik Jakobsson <patrik.r.jakobsson@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220308195222.13471-11-tzimmermann@suse.de
parent 42ceddb6
...@@ -21,6 +21,10 @@ ...@@ -21,6 +21,10 @@
#include "gem.h" #include "gem.h"
#include "psb_drv.h" #include "psb_drv.h"
/*
* PSB GEM object
*/
int psb_gem_pin(struct psb_gem_object *pobj) int psb_gem_pin(struct psb_gem_object *pobj)
{ {
struct drm_gem_object *obj = &pobj->base; struct drm_gem_object *obj = &pobj->base;
...@@ -296,3 +300,132 @@ static vm_fault_t psb_gem_fault(struct vm_fault *vmf) ...@@ -296,3 +300,132 @@ static vm_fault_t psb_gem_fault(struct vm_fault *vmf)
return ret; return ret;
} }
/*
* Memory management
*/
/* Insert vram stolen pages into the GTT. */
static void psb_gem_mm_populate_stolen(struct drm_psb_private *pdev)
{
struct drm_device *dev = &pdev->dev;
unsigned int pfn_base;
unsigned int i, num_pages;
uint32_t pte;
pfn_base = pdev->stolen_base >> PAGE_SHIFT;
num_pages = pdev->vram_stolen_size >> PAGE_SHIFT;
drm_dbg(dev, "Set up %u 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, PSB_MMU_CACHED_MEMORY);
iowrite32(pte, pdev->gtt_map + i);
}
(void)ioread32(pdev->gtt_map + i - 1);
}
int psb_gem_mm_init(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
struct pci_dev *pdev = to_pci_dev(dev->dev);
unsigned long stolen_size, vram_stolen_size;
struct psb_gtt *pg;
int ret;
mutex_init(&dev_priv->mmap_mutex);
pg = &dev_priv->gtt;
pci_read_config_dword(pdev, PSB_BSM, &dev_priv->stolen_base);
vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - PAGE_SIZE;
stolen_size = vram_stolen_size;
dev_dbg(dev->dev, "Stolen memory base 0x%x, size %luK\n",
dev_priv->stolen_base, vram_stolen_size / 1024);
pg->stolen_size = stolen_size;
dev_priv->vram_stolen_size = vram_stolen_size;
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;
goto err_mutex_destroy;
}
psb_gem_mm_populate_stolen(dev_priv);
return 0;
err_mutex_destroy:
mutex_destroy(&dev_priv->mmap_mutex);
return ret;
}
void psb_gem_mm_fini(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
iounmap(dev_priv->vram_addr);
mutex_destroy(&dev_priv->mmap_mutex);
}
/* Re-insert all pinned GEM objects into GTT. */
static void psb_gem_mm_populate_resources(struct drm_psb_private *pdev)
{
unsigned int restored = 0, total = 0, size = 0;
struct resource *r = pdev->gtt_mem->child;
struct drm_device *dev = &pdev->dev;
struct psb_gem_object *pobj;
while (r) {
/*
* TODO: GTT restoration needs a refactoring, so that we don't have to touch
* struct psb_gem_object here. The type represents a GEM object and is
* not related to the GTT itself.
*/
pobj = container_of(r, struct psb_gem_object, resource);
if (pobj->pages) {
psb_gtt_insert_pages(pdev, &pobj->resource, pobj->pages);
size += resource_size(&pobj->resource);
++restored;
}
r = r->sibling;
++total;
}
drm_dbg(dev, "Restored %u of %u gtt ranges (%u KB)", restored, total, (size / 1024));
}
int psb_gem_mm_resume(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
struct pci_dev *pdev = to_pci_dev(dev->dev);
unsigned long stolen_size, vram_stolen_size;
struct psb_gtt *pg;
pg = &dev_priv->gtt;
pci_read_config_dword(pdev, PSB_BSM, &dev_priv->stolen_base);
vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - PAGE_SIZE;
stolen_size = vram_stolen_size;
dev_dbg(dev->dev, "Stolen memory base 0x%x, size %luK\n", dev_priv->stolen_base,
vram_stolen_size / 1024);
if (stolen_size != pg->stolen_size) {
dev_err(dev->dev, "GTT resume error.\n");
return -EINVAL;
}
psb_gem_mm_populate_stolen(dev_priv);
psb_gem_mm_populate_resources(dev_priv);
return 0;
}
...@@ -14,6 +14,10 @@ ...@@ -14,6 +14,10 @@
struct drm_device; struct drm_device;
/*
* PSB GEM object
*/
struct psb_gem_object { struct psb_gem_object {
struct drm_gem_object base; struct drm_gem_object base;
...@@ -36,4 +40,12 @@ psb_gem_create(struct drm_device *dev, u64 size, const char *name, bool stolen, ...@@ -36,4 +40,12 @@ psb_gem_create(struct drm_device *dev, u64 size, const char *name, bool stolen,
int psb_gem_pin(struct psb_gem_object *pobj); int psb_gem_pin(struct psb_gem_object *pobj);
void psb_gem_unpin(struct psb_gem_object *pobj); void psb_gem_unpin(struct psb_gem_object *pobj);
/*
* Memory management
*/
int psb_gem_mm_init(struct drm_device *dev);
void psb_gem_mm_fini(struct drm_device *dev);
int psb_gem_mm_resume(struct drm_device *dev);
#endif #endif
...@@ -49,7 +49,7 @@ int psb_gtt_allocate_resource(struct drm_psb_private *pdev, struct resource *res ...@@ -49,7 +49,7 @@ int psb_gtt_allocate_resource(struct drm_psb_private *pdev, struct resource *res
* *
* Set the GTT entry for the appropriate memory type. * Set the GTT entry for the appropriate memory type.
*/ */
static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type) uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)
{ {
uint32_t mask = PSB_PTE_VALID; uint32_t mask = PSB_PTE_VALID;
...@@ -125,15 +125,6 @@ void psb_gtt_remove_pages(struct drm_psb_private *pdev, const struct resource *r ...@@ -125,15 +125,6 @@ void psb_gtt_remove_pages(struct drm_psb_private *pdev, const struct resource *r
mutex_unlock(&pdev->gtt_mutex); mutex_unlock(&pdev->gtt_mutex);
} }
void psb_gem_mm_fini(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
iounmap(dev_priv->vram_addr);
mutex_destroy(&dev_priv->mmap_mutex);
}
void psb_gtt_fini(struct drm_device *dev) void psb_gtt_fini(struct drm_device *dev)
{ {
struct drm_psb_private *dev_priv = to_drm_psb_private(dev); struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
...@@ -164,55 +155,6 @@ static void psb_gtt_clear(struct drm_psb_private *pdev) ...@@ -164,55 +155,6 @@ static void psb_gtt_clear(struct drm_psb_private *pdev)
(void)ioread32(pdev->gtt_map + i - 1); (void)ioread32(pdev->gtt_map + i - 1);
} }
/* Insert vram stolen pages into the GTT. */
static void psb_gtt_populate_stolen(struct drm_psb_private *pdev)
{
struct drm_device *dev = &pdev->dev;
unsigned int pfn_base;
unsigned int i, num_pages;
uint32_t pte;
pfn_base = pdev->stolen_base >> PAGE_SHIFT;
num_pages = pdev->vram_stolen_size >> PAGE_SHIFT;
drm_dbg(dev, "Set up %u 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, PSB_MMU_CACHED_MEMORY);
iowrite32(pte, pdev->gtt_map + i);
}
(void)ioread32(pdev->gtt_map + i - 1);
}
/* Re-insert all pinned GEM objects into GTT. */
static void psb_gtt_populate_resources(struct drm_psb_private *pdev)
{
unsigned int restored = 0, total = 0, size = 0;
struct resource *r = pdev->gtt_mem->child;
struct drm_device *dev = &pdev->dev;
struct psb_gem_object *pobj;
while (r) {
/*
* TODO: GTT restoration needs a refactoring, so that we don't have to touch
* struct psb_gem_object here. The type represents a GEM object and is
* not related to the GTT itself.
*/
pobj = container_of(r, struct psb_gem_object, resource);
if (pobj->pages) {
psb_gtt_insert_pages(pdev, &pobj->resource, pobj->pages);
size += resource_size(&pobj->resource);
++restored;
}
r = r->sibling;
++total;
}
drm_dbg(dev, "Restored %u of %u gtt ranges (%u KB)", restored, total, (size / 1024));
}
int psb_gtt_init(struct drm_device *dev) int psb_gtt_init(struct drm_device *dev)
{ {
struct drm_psb_private *dev_priv = to_drm_psb_private(dev); struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
...@@ -300,45 +242,6 @@ int psb_gtt_init(struct drm_device *dev) ...@@ -300,45 +242,6 @@ int psb_gtt_init(struct drm_device *dev)
return ret; return ret;
} }
int psb_gem_mm_init(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
struct pci_dev *pdev = to_pci_dev(dev->dev);
unsigned long stolen_size, vram_stolen_size;
struct psb_gtt *pg;
int ret;
mutex_init(&dev_priv->mmap_mutex);
pg = &dev_priv->gtt;
pci_read_config_dword(pdev, PSB_BSM, &dev_priv->stolen_base);
vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - PAGE_SIZE;
stolen_size = vram_stolen_size;
dev_dbg(dev->dev, "Stolen memory base 0x%x, size %luK\n",
dev_priv->stolen_base, vram_stolen_size / 1024);
pg->stolen_size = stolen_size;
dev_priv->vram_stolen_size = vram_stolen_size;
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;
goto err_mutex_destroy;
}
psb_gtt_populate_stolen(dev_priv);
return 0;
err_mutex_destroy:
mutex_destroy(&dev_priv->mmap_mutex);
return ret;
}
int psb_gtt_resume(struct drm_device *dev) int psb_gtt_resume(struct drm_device *dev)
{ {
struct drm_psb_private *dev_priv = to_drm_psb_private(dev); struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
...@@ -421,31 +324,3 @@ int psb_gtt_resume(struct drm_device *dev) ...@@ -421,31 +324,3 @@ int psb_gtt_resume(struct drm_device *dev)
(void)PSB_RVDC32(PSB_PGETBL_CTL); (void)PSB_RVDC32(PSB_PGETBL_CTL);
return ret; return ret;
} }
int psb_gem_mm_resume(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
struct pci_dev *pdev = to_pci_dev(dev->dev);
unsigned long stolen_size, vram_stolen_size;
struct psb_gtt *pg;
pg = &dev_priv->gtt;
pci_read_config_dword(pdev, PSB_BSM, &dev_priv->stolen_base);
vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - PAGE_SIZE;
stolen_size = vram_stolen_size;
dev_dbg(dev->dev, "Stolen memory base 0x%x, size %luK\n", dev_priv->stolen_base,
vram_stolen_size / 1024);
if (stolen_size != pg->stolen_size) {
dev_err(dev->dev, "GTT resume error.\n");
return -EINVAL;
}
psb_gtt_populate_stolen(dev_priv);
psb_gtt_populate_resources(dev_priv);
return 0;
}
...@@ -33,12 +33,9 @@ int psb_gtt_allocate_resource(struct drm_psb_private *pdev, struct resource *res ...@@ -33,12 +33,9 @@ int psb_gtt_allocate_resource(struct drm_psb_private *pdev, struct resource *res
const char *name, resource_size_t size, resource_size_t align, const char *name, resource_size_t size, resource_size_t align,
bool stolen, u32 *offset); bool stolen, u32 *offset);
uint32_t psb_gtt_mask_pte(uint32_t pfn, int type);
void psb_gtt_insert_pages(struct drm_psb_private *pdev, const struct resource *res, void psb_gtt_insert_pages(struct drm_psb_private *pdev, const struct resource *res,
struct page **pages); struct page **pages);
void psb_gtt_remove_pages(struct drm_psb_private *pdev, const struct resource *res); void psb_gtt_remove_pages(struct drm_psb_private *pdev, const struct resource *res);
int psb_gem_mm_init(struct drm_device *dev);
void psb_gem_mm_fini(struct drm_device *dev);
int psb_gem_mm_resume(struct drm_device *dev);
#endif #endif
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
* Alan Cox <alan@linux.intel.com> * Alan Cox <alan@linux.intel.com>
*/ */
#include "gem.h"
#include "power.h" #include "power.h"
#include "psb_drv.h" #include "psb_drv.h"
#include "psb_reg.h" #include "psb_reg.h"
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <drm/drm_vblank.h> #include <drm/drm_vblank.h>
#include "framebuffer.h" #include "framebuffer.h"
#include "gem.h"
#include "intel_bios.h" #include "intel_bios.h"
#include "mid_bios.h" #include "mid_bios.h"
#include "power.h" #include "power.h"
......
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