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

drm/gma500: Split GTT init/resume/fini into GTT and GEM functions

The GTT init, fini and resume functions contain both, GTT and GEM,
code. Split each into a separate GTT and a GEM function. The GEM
code is responsible for mmap_mutex and the stolen memory area. The
rest of the functionality is left in GTT functions.
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-9-tzimmermann@suse.de
parent 6069fd81
...@@ -125,19 +125,26 @@ void psb_gtt_remove_pages(struct drm_psb_private *pdev, const struct resource *r ...@@ -125,19 +125,26 @@ 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);
struct pci_dev *pdev = to_pci_dev(dev->dev); struct pci_dev *pdev = to_pci_dev(dev->dev);
iounmap(dev_priv->vram_addr);
iounmap(dev_priv->gtt_map); iounmap(dev_priv->gtt_map);
pci_write_config_word(pdev, PSB_GMCH_CTRL, dev_priv->gmch_ctrl); pci_write_config_word(pdev, PSB_GMCH_CTRL, dev_priv->gmch_ctrl);
PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL); PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL);
(void)PSB_RVDC32(PSB_PGETBL_CTL); (void)PSB_RVDC32(PSB_PGETBL_CTL);
mutex_destroy(&dev_priv->mmap_mutex);
mutex_destroy(&dev_priv->gtt_mutex); mutex_destroy(&dev_priv->gtt_mutex);
} }
...@@ -211,12 +218,10 @@ int psb_gtt_init(struct drm_device *dev) ...@@ -211,12 +218,10 @@ 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);
struct pci_dev *pdev = to_pci_dev(dev->dev); struct pci_dev *pdev = to_pci_dev(dev->dev);
unsigned gtt_pages; unsigned gtt_pages;
unsigned long stolen_size, vram_stolen_size;
struct psb_gtt *pg; struct psb_gtt *pg;
int ret = 0; int ret = 0;
mutex_init(&dev_priv->gtt_mutex); mutex_init(&dev_priv->gtt_mutex);
mutex_init(&dev_priv->mmap_mutex);
pg = &dev_priv->gtt; pg = &dev_priv->gtt;
...@@ -274,49 +279,63 @@ int psb_gtt_init(struct drm_device *dev) ...@@ -274,49 +279,63 @@ int psb_gtt_init(struct drm_device *dev)
dev_priv->gtt_mem = &fudge; dev_priv->gtt_mem = &fudge;
} }
pg->gtt_pages = gtt_pages;
dev_priv->gtt_map = ioremap(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT);
if (!dev_priv->gtt_map) {
dev_err(dev->dev, "Failure to map gtt.\n");
ret = -ENOMEM;
goto err_gtt_disable;
}
psb_gtt_clear(dev_priv);
return 0;
err_gtt_disable:
pci_write_config_word(pdev, PSB_GMCH_CTRL, dev_priv->gmch_ctrl);
PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL);
(void)PSB_RVDC32(PSB_PGETBL_CTL);
mutex_destroy(&dev_priv->gtt_mutex);
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); pci_read_config_dword(pdev, PSB_BSM, &dev_priv->stolen_base);
vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - PAGE_SIZE;
- PAGE_SIZE;
stolen_size = vram_stolen_size; stolen_size = vram_stolen_size;
dev_dbg(dev->dev, "Stolen memory base 0x%x, size %luK\n", dev_dbg(dev->dev, "Stolen memory base 0x%x, size %luK\n",
dev_priv->stolen_base, vram_stolen_size / 1024); dev_priv->stolen_base, vram_stolen_size / 1024);
pg->gtt_pages = gtt_pages;
pg->stolen_size = stolen_size; pg->stolen_size = stolen_size;
dev_priv->vram_stolen_size = vram_stolen_size; dev_priv->vram_stolen_size = vram_stolen_size;
/*
* Map the GTT and the stolen memory area
*/
dev_priv->gtt_map = ioremap(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT);
if (!dev_priv->gtt_map) {
dev_err(dev->dev, "Failure to map gtt.\n");
ret = -ENOMEM;
goto err_gtt_disable;
}
dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, stolen_size); dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, 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;
goto err_iounmap; goto err_mutex_destroy;
} }
psb_gtt_clear(dev_priv);
psb_gtt_populate_stolen(dev_priv); psb_gtt_populate_stolen(dev_priv);
return 0; return 0;
err_iounmap: err_mutex_destroy:
iounmap(dev_priv->gtt_map);
err_gtt_disable:
pci_write_config_word(pdev, PSB_GMCH_CTRL, dev_priv->gmch_ctrl);
PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL);
(void)PSB_RVDC32(PSB_PGETBL_CTL);
mutex_destroy(&dev_priv->mmap_mutex); mutex_destroy(&dev_priv->mmap_mutex);
mutex_destroy(&dev_priv->gtt_mutex);
return ret; return ret;
} }
...@@ -325,9 +344,8 @@ static int psb_gtt_resume(struct drm_device *dev) ...@@ -325,9 +344,8 @@ static 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);
struct pci_dev *pdev = to_pci_dev(dev->dev); struct pci_dev *pdev = to_pci_dev(dev->dev);
unsigned int gtt_pages; unsigned int gtt_pages;
unsigned long stolen_size, vram_stolen_size;
struct psb_gtt *pg; struct psb_gtt *pg;
int ret = 0; int ret;
pg = &dev_priv->gtt; pg = &dev_priv->gtt;
...@@ -387,27 +405,15 @@ static int psb_gtt_resume(struct drm_device *dev) ...@@ -387,27 +405,15 @@ static int psb_gtt_resume(struct drm_device *dev)
dev_priv->gtt_mem = &fudge; dev_priv->gtt_mem = &fudge;
} }
pci_read_config_dword(pdev, PSB_BSM, &dev_priv->stolen_base); if (gtt_pages != pg->gtt_pages) {
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 ((gtt_pages != pg->gtt_pages) && (stolen_size != pg->stolen_size)) {
dev_err(dev->dev, "GTT resume error.\n"); dev_err(dev->dev, "GTT resume error.\n");
ret = -EINVAL; ret = -EINVAL;
goto err_gtt_disable; goto err_gtt_disable;
} }
pg->gtt_pages = gtt_pages; pg->gtt_pages = gtt_pages;
pg->stolen_size = stolen_size;
dev_priv->vram_stolen_size = vram_stolen_size;
psb_gtt_clear(dev_priv); psb_gtt_clear(dev_priv);
psb_gtt_populate_stolen(dev_priv);
return 0;
err_gtt_disable: err_gtt_disable:
pci_write_config_word(pdev, PSB_GMCH_CTRL, dev_priv->gmch_ctrl); pci_write_config_word(pdev, PSB_GMCH_CTRL, dev_priv->gmch_ctrl);
...@@ -416,11 +422,39 @@ static int psb_gtt_resume(struct drm_device *dev) ...@@ -416,11 +422,39 @@ static int psb_gtt_resume(struct drm_device *dev)
return ret; return ret;
} }
static 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);
return 0;
}
int psb_gtt_restore(struct drm_device *dev) int psb_gtt_restore(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);
psb_gtt_resume(dev); psb_gtt_resume(dev);
psb_gem_mm_resume(dev);
psb_gtt_populate_resources(dev_priv); psb_gtt_populate_resources(dev_priv);
......
...@@ -37,4 +37,7 @@ void psb_gtt_insert_pages(struct drm_psb_private *pdev, const struct resource *r ...@@ -37,4 +37,7 @@ void psb_gtt_insert_pages(struct drm_psb_private *pdev, const struct resource *r
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);
#endif #endif
...@@ -192,6 +192,7 @@ static void psb_driver_unload(struct drm_device *dev) ...@@ -192,6 +192,7 @@ static void psb_driver_unload(struct drm_device *dev)
psb_mmu_driver_takedown(dev_priv->mmu); psb_mmu_driver_takedown(dev_priv->mmu);
dev_priv->mmu = NULL; dev_priv->mmu = NULL;
} }
psb_gem_mm_fini(dev);
psb_gtt_fini(dev); psb_gtt_fini(dev);
if (dev_priv->scratch_page) { if (dev_priv->scratch_page) {
set_pages_wb(dev_priv->scratch_page, 1); set_pages_wb(dev_priv->scratch_page, 1);
...@@ -325,6 +326,9 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags) ...@@ -325,6 +326,9 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags)
set_pages_uc(dev_priv->scratch_page, 1); set_pages_uc(dev_priv->scratch_page, 1);
ret = psb_gtt_init(dev); ret = psb_gtt_init(dev);
if (ret)
goto out_err;
ret = psb_gem_mm_init(dev);
if (ret) if (ret)
goto out_err; goto out_err;
......
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