gma500: Add support for inserting and removing pages from the GART

There are two chunks of code we need to do this. The first one is the code
to insert and remove the pages from the GART, the second is the code to build
page table lists from the GEM object. Surprisingly this latter one doesn't seem
to have a nice GEM helper.

While we are at it we can begin dismantling the semi redundant struct pg,
and finish pruning out the old now unused gtt code as well as the last bits
of helper glue from the old driver base.

Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Alan Cox 2011-04-19 15:27:43 +01:00 committed by Greg Kroah-Hartman
parent f20ee24445
commit 6a62730c7a
10 changed files with 345 additions and 1005 deletions

View File

@ -17,7 +17,6 @@ psb_gfx-y += psb_bl.o \
psb_intel_modes.o \
psb_intel_sdvo.o \
psb_lid.o \
psb_pvr_glue.o \
psb_mmu.o \
psb_powermgmt.o \
psb_irq.o \

View File

@ -499,15 +499,15 @@ static int psb_driver_unload(struct drm_device *dev)
down_read(&pg->sem);
psb_mmu_remove_pfn_sequence(
psb_mmu_get_default_pd
(dev_priv->mmu),
pg->mmu_gatt_start,
pg->vram_stolen_size >> PAGE_SHIFT);
psb_mmu_get_default_pd
(dev_priv->mmu),
pg->mmu_gatt_start,
dev_priv->vram_stolen_size >> PAGE_SHIFT);
up_read(&pg->sem);
psb_mmu_driver_takedown(dev_priv->mmu);
dev_priv->mmu = NULL;
}
psb_gtt_takedown(dev_priv->pg, 1);
psb_gtt_takedown(dev);
if (dev_priv->scratch_page) {
__free_page(dev_priv->scratch_page);
dev_priv->scratch_page = NULL;
@ -592,15 +592,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
set_pages_uc(dev_priv->scratch_page, 1);
dev_priv->pg = psb_gtt_alloc(dev);
if (!dev_priv->pg)
goto out_err;
ret = psb_gtt_init(dev_priv->pg, 0);
if (ret)
goto out_err;
ret = psb_gtt_mm_init(dev_priv->pg);
ret = psb_gtt_init(dev, 0);
if (ret)
goto out_err;
@ -955,8 +947,8 @@ static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data,
struct drm_psb_private *dev_priv = psb_priv(dev);
struct drm_psb_stolen_memory_arg *arg = data;
arg->base = dev_priv->pg->stolen_base;
arg->size = dev_priv->pg->vram_stolen_size;
arg->base = dev_priv->stolen_base;
arg->size = dev_priv->vram_stolen_size;
return 0;
}

View File

@ -240,6 +240,13 @@ struct drm_psb_private {
/* GTT Memory manager */
struct psb_gtt_mm *gtt_mm;
struct page *scratch_page;
u32 *gtt_map;
uint32_t stolen_base;
void *vram_addr;
unsigned long vram_stolen_size;
int gtt_initialized;
u16 gmch_ctrl; /* Saved GTT setup */
u32 pge_ctl;
struct mutex gtt_mutex;
struct resource *gtt_mem; /* Our PCI resource */

View File

@ -37,7 +37,6 @@
#include "psb_intel_reg.h"
#include "psb_intel_drv.h"
#include "psb_fb.h"
#include "psb_pvr_glue.h"
static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb);
static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
@ -191,8 +190,7 @@ static int psbfb_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
struct psb_framebuffer *psbfb = vma->vm_private_data;
struct drm_device *dev = psbfb->base.dev;
struct drm_psb_private *dev_priv = dev->dev_private;
struct psb_gtt *pg = dev_priv->pg;
unsigned long phys_addr = (unsigned long)pg->stolen_base;
unsigned long phys_addr = (unsigned long)dev_priv->stolen_base;
page_num = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
@ -241,7 +239,6 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
char *fb_screen_base = NULL;
struct drm_device *dev = psbfb->base.dev;
struct drm_psb_private *dev_priv = dev->dev_private;
struct psb_gtt *pg = dev_priv->pg;
if (vma->vm_pgoff != 0)
return -EINVAL;
@ -254,10 +251,11 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
fb_screen_base = (char *)info->screen_base;
DRM_DEBUG("vm_pgoff 0x%lx, screen base %p vram_addr %p\n",
vma->vm_pgoff, fb_screen_base, pg->vram_addr);
vma->vm_pgoff, fb_screen_base,
dev_priv->vram_addr);
/* FIXME: ultimately this needs to become 'if entirely stolen memory' */
if (1 || fb_screen_base == pg->vram_addr) {
if (1 || fb_screen_base == dev_priv->vram_addr) {
vma->vm_ops = &psbfb_vm_ops;
vma->vm_private_data = (void *)psbfb;
vma->vm_flags |= VM_RESERVED | VM_IO |
@ -349,7 +347,6 @@ static int psbfb_create(struct psb_fbdev *fbdev,
{
struct drm_device *dev = fbdev->psb_fb_helper.dev;
struct drm_psb_private *dev_priv = dev->dev_private;
struct psb_gtt *pg = dev_priv->pg;
struct fb_info *info;
struct drm_framebuffer *fb;
struct psb_framebuffer *psbfb;
@ -409,7 +406,7 @@ static int psbfb_create(struct psb_fbdev *fbdev,
/* Accessed via stolen memory directly, This only works for stolem
memory however. Need to address this once we start using gtt
pages we allocate */
info->screen_base = (char *)pg->vram_addr + backing->offset;
info->screen_base = (char *)dev_priv->vram_addr + backing->offset;
info->screen_size = size;
memset(info->screen_base, 0, size);
@ -735,32 +732,19 @@ static void psb_setup_outputs(struct drm_device *dev)
}
}
/* FIXME: rewrite these in terms of the gtt_range and GEM objects
rather than faking them as we do now */
static void *psb_bo_from_handle(struct drm_device *dev,
struct drm_file *file_priv,
unsigned int handle)
{
void *psKernelMemInfo = NULL;
void * hKernelMemInfo = (void *)handle;
int ret;
ret = psb_get_meminfo_by_handle(hKernelMemInfo, &psKernelMemInfo);
if (ret) {
DRM_ERROR("Cannot get meminfo for handle 0x%x\n",
(u32)hKernelMemInfo);
return NULL;
}
return (void *)psKernelMemInfo;
return NULL;
}
static size_t psb_bo_size(struct drm_device *dev, void *bof)
{
#if 0
void *psKernelMemInfo = (void *)bof;
return (size_t)psKernelMemInfo->ui32AllocSize;
#else
return 0;
#endif
}
static size_t psb_bo_offset(struct drm_device *dev, void *bof)

File diff suppressed because it is too large Load Diff

View File

@ -22,66 +22,22 @@
#include <drm/drmP.h>
/*#include "img_types.h"*/
struct psb_gtt {
struct drm_device *dev;
int initialized;
uint32_t gatt_start;
uint32_t mmu_gatt_start;
uint32_t gtt_start;
uint32_t gtt_phys_start;
unsigned gtt_pages;
unsigned gatt_pages;
uint32_t stolen_base;
void *vram_addr;
uint32_t pge_ctl;
u16 gmch_ctrl;
unsigned long stolen_size;
unsigned long vram_stolen_size;
uint32_t *gtt_map;
struct rw_semaphore sem;
};
struct psb_gtt_mm {
struct drm_mm base;
struct drm_open_hash hash;
uint32_t count;
spinlock_t lock;
};
struct psb_gtt_hash_entry {
struct drm_open_hash ht;
uint32_t count;
struct drm_hash_item item;
};
struct psb_gtt_mem_mapping {
struct drm_mm_node *node;
struct drm_hash_item item;
};
/*Exported functions*/
extern int psb_gtt_init(struct psb_gtt *pg, int resume);
extern int psb_gtt_insert_pages(struct psb_gtt *pg, struct page **pages,
unsigned offset_pages, unsigned num_pages,
unsigned desired_tile_stride,
unsigned hw_tile_stride, int type);
extern int psb_gtt_remove_pages(struct psb_gtt *pg, unsigned offset_pages,
unsigned num_pages,
unsigned desired_tile_stride,
unsigned hw_tile_stride,
int rc_prot);
extern struct psb_gtt *psb_gtt_alloc(struct drm_device *dev);
extern void psb_gtt_takedown(struct psb_gtt *pg, int free);
extern int psb_gtt_map_meminfo(struct drm_device *dev,
void * hKernelMemInfo,
uint32_t *offset);
extern int psb_gtt_unmap_meminfo(struct drm_device *dev,
void * hKernelMemInfo);
extern int psb_gtt_mm_init(struct psb_gtt *pg);
extern void psb_gtt_mm_takedown(void);
extern int psb_gtt_init(struct drm_device *dev, int resume);
extern void psb_gtt_takedown(struct drm_device *dev);
/* Each gtt_range describes an allocation in the GTT area */
struct gtt_range {
@ -91,8 +47,12 @@ struct gtt_range {
struct drm_gem_object gem; /* GEM high level stuff */
int in_gart; /* Currently in the GART */
int stolen; /* Backed from stolen RAM */
struct page **pages; /* Backing pages if present */
};
extern int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r);
extern void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r);
extern struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
const char *name, int backed);
extern void psb_gtt_kref_put(struct gtt_range *gt);

View File

@ -1014,6 +1014,8 @@ static void psb_intel_crtc_restore(struct drm_crtc *crtc)
REG_WRITE(paletteReg + (i << 2), crtc_state->savePalette[i]);
}
#if 0
/* FIXME */
static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
struct drm_file *file_priv,
uint32_t handle,
@ -1092,7 +1094,7 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
addr = page_offset << PAGE_SHIFT;
addr += pg->stolen_base;
addr += dev_priv->stolen_base;
psb_intel_crtc->cursor_addr = addr;
@ -1146,6 +1148,7 @@ static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
}
return 0;
}
#endif
static void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
u16 *green, u16 *blue, uint32_t type, uint32_t size)
@ -1329,8 +1332,10 @@ static const struct drm_crtc_helper_funcs psb_intel_helper_funcs = {
const struct drm_crtc_funcs psb_intel_crtc_funcs = {
.save = psb_intel_crtc_save,
.restore = psb_intel_crtc_restore,
/* FIXME
.cursor_set = psb_intel_crtc_cursor_set,
.cursor_move = psb_intel_crtc_cursor_move,
*/
.gamma_set = psb_intel_crtc_gamma_set,
.set_config = psb_crtc_set_config,
.destroy = psb_intel_crtc_destroy,

View File

@ -269,7 +269,6 @@ static void gma_resume_display(struct pci_dev *pdev)
{
struct drm_device *dev = pci_get_drvdata(pdev);
struct drm_psb_private *dev_priv = dev->dev_private;
struct psb_gtt *pg = dev_priv->pg;
if (dev_priv->suspended == false)
return;
@ -277,9 +276,9 @@ static void gma_resume_display(struct pci_dev *pdev)
/* turn on the display power island */
power_up(dev);
PSB_WVDC32(pg->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
pci_write_config_word(pdev, PSB_GMCH_CTRL,
pg->gmch_ctrl | _PSB_GMCH_ENABLED);
dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
/* Don't reinitialize the GTT as it is unnecessary. The gtt is
* stored in memory so it will automatically be restored. All

View File

@ -1,73 +0,0 @@
/*
* Copyright (c) 2009, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include "psb_pvr_glue.h"
/**
* FIXME: should NOT use these file under env/linux directly
*/
int psb_get_meminfo_by_handle(void *hKernelMemInfo,
void **ppsKernelMemInfo)
{
return -EINVAL;
#if 0
void *psKernelMemInfo = IMG_NULL;
PVRSRV_PER_PROCESS_DATA *psPerProc = IMG_NULL;
PVRSRV_ERROR eError;
psPerProc = PVRSRVPerProcessData(task_tgid_nr(current));
eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
(IMG_VOID *)&psKernelMemInfo,
hKernelMemInfo,
PVRSRV_HANDLE_TYPE_MEM_INFO);
if (eError != PVRSRV_OK) {
DRM_ERROR("Cannot find kernel meminfo for handle 0x%x\n",
(u32)hKernelMemInfo);
return -EINVAL;
}
*ppsKernelMemInfo = psKernelMemInfo;
DRM_DEBUG("Got Kernel MemInfo for handle %lx\n",
(u32)hKernelMemInfo);
return 0;
#endif
}
int psb_get_pages_by_mem_handle(void *hOSMemHandle, struct page ***pages)
{
return -EINVAL;
#if 0
LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
struct page **page_list;
if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_ALLOC_PAGES) {
DRM_ERROR("MemArea type is not LINUX_MEM_AREA_ALLOC_PAGES\n");
return -EINVAL;
}
page_list = psLinuxMemArea->uData.sPageList.pvPageList;
if (!page_list) {
DRM_DEBUG("Page List is NULL\n");
return -ENOMEM;
}
*pages = page_list;
return 0;
#endif
}

View File

@ -1,25 +0,0 @@
/*
* Copyright (c) 2009, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include "psb_drv.h"
extern int psb_get_meminfo_by_handle(void * hKernelMemInfo,
void **ppsKernelMemInfo);
extern u32 psb_get_tgid(void);
extern int psb_get_pages_by_mem_handle(void * hOSMemHandle,
struct page ***pages);