diff options
Diffstat (limited to 'linux-core')
| -rw-r--r-- | linux-core/drm_agpsupport.c | 2 | ||||
| -rw-r--r-- | linux-core/drm_bo_move.c | 33 | ||||
| -rw-r--r-- | linux-core/drm_compat.c | 29 | ||||
| -rw-r--r-- | linux-core/drm_compat.h | 5 | ||||
| -rw-r--r-- | linux-core/drm_objects.h | 6 | ||||
| -rw-r--r-- | linux-core/drm_ttm.c | 21 | 
6 files changed, 84 insertions, 12 deletions
| diff --git a/linux-core/drm_agpsupport.c b/linux-core/drm_agpsupport.c index adcb93a5..0aa94a75 100644 --- a/linux-core/drm_agpsupport.c +++ b/linux-core/drm_agpsupport.c @@ -666,7 +666,7 @@ void drm_agp_chipset_flush(struct drm_device *dev)  {  	agp_flush_chipset(dev->agp->bridge);  } -EXPORT_SYMBOL(drm_agp_flush_chipset); +EXPORT_SYMBOL(drm_agp_chipset_flush);  #endif  #endif				/* __OS_HAS_AGP */ diff --git a/linux-core/drm_bo_move.c b/linux-core/drm_bo_move.c index db433d63..536ff5d3 100644 --- a/linux-core/drm_bo_move.c +++ b/linux-core/drm_bo_move.c @@ -596,3 +596,36 @@ void drm_bo_kunmap(struct drm_bo_kmap_obj *map)  	map->page = NULL;  }  EXPORT_SYMBOL(drm_bo_kunmap); + +int drm_bo_pfn_prot(struct drm_buffer_object *bo, +		    unsigned long dst_offset, +		    unsigned long *pfn, +		    pgprot_t *prot) +{ +	struct drm_bo_mem_reg *mem = &bo->mem; +	struct drm_device *dev = bo->dev; +	unsigned long bus_offset; +	unsigned long bus_size; +	unsigned long bus_base; +	struct drm_mem_type_manager *man = &dev->bm.man[mem->mem_type]; +	int ret; + +	ret = drm_bo_pci_offset(dev, mem, &bus_base, &bus_offset, +				&bus_size); +	if (ret) +		return -EINVAL; + +	if (bus_size != 0) +		*pfn = (bus_base + bus_offset + dst_offset) >> PAGE_SHIFT; +	else if (!bo->ttm) +		return -EINVAL; +	else +		*pfn = page_to_pfn(drm_ttm_get_page(bo->ttm, dst_offset >> PAGE_SHIFT)); + +	*prot = (mem->flags & DRM_BO_FLAG_CACHED) ? +		PAGE_KERNEL : drm_kernel_io_prot(man->drm_bus_maptype); + +	return 0; +} +EXPORT_SYMBOL(drm_bo_pfn_prot); + diff --git a/linux-core/drm_compat.c b/linux-core/drm_compat.c index e95269ec..b7b8e395 100644 --- a/linux-core/drm_compat.c +++ b/linux-core/drm_compat.c @@ -779,3 +779,32 @@ struct pci_dev * pci_get_bus_and_slot(unsigned int bus, unsigned int devfn)  }  EXPORT_SYMBOL(pci_get_bus_and_slot);  #endif + +#if defined(DRM_KMAP_ATOMIC_PROT_PFN) && defined(CONFIG_HIMEM) +#define drm_kmap_get_fixmap_pte(vaddr)					\ +	pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), vaddr), (vaddr)), (vaddr)) + +void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, +			   pgprot_t protection) +{ +	enum fixed_addresses idx; +	unsigned long vaddr; +	static pte_t *km_pte; +	static int initialized = 0; + +	if (unlikely(!initialized)) { +		km_pte = drm_kmap_get_fixmap_pte(__fix_to_virt(FIX_KMAP_BEGIN)); +		initialized = 1; +	} + +	pagefault_disable(); +	idx = type + KM_TYPE_NR*smp_processor_id(); +	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); +	set_pte(km_pte-idx, pfn_pte(pfn, protection)); + +	return (void*) vaddr; +} + +EXPORT_SYMBOL(kmap_atomic_prot_pfn); + + diff --git a/linux-core/drm_compat.h b/linux-core/drm_compat.h index f5f06017..86f1159a 100644 --- a/linux-core/drm_compat.h +++ b/linux-core/drm_compat.h @@ -343,4 +343,9 @@ extern struct pci_dev * pci_get_bus_and_slot(unsigned int bus, unsigned int devf  #define PM_EVENT_PRETHAW 3  #endif +#if (defined(CONFIG_X86) && defined(CONFIG_X86_32) && defined(CONFIG_HIMEM)) +#define DRM_KMAP_ATOMIC_PROT_PFN +extern void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, +				  pgprot_t protection); +#endif  #endif diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h index cce58178..802e72cf 100644 --- a/linux-core/drm_objects.h +++ b/linux-core/drm_objects.h @@ -383,7 +383,7 @@ extern int drm_ttm_destroy(struct drm_ttm *ttm);   * The array of page pointers was allocated with vmalloc   * instead of drm_calloc.   */ -#define DRM_TTM_PAGE_VMALLOC    (1 << 4) +#define DRM_TTM_PAGEDIR_VMALLOC (1 << 4)  /*   * This ttm is mapped from user space   */ @@ -741,6 +741,10 @@ static inline void *drm_bmo_virtual(struct drm_bo_kmap_obj *map, int *is_iomem)  extern void drm_bo_kunmap(struct drm_bo_kmap_obj *map);  extern int drm_bo_kmap(struct drm_buffer_object *bo, unsigned long start_page,  		       unsigned long num_pages, struct drm_bo_kmap_obj *map); +extern int drm_bo_pfn_prot(struct drm_buffer_object *bo, +			   unsigned long dst_offset, +			   unsigned long *pfn, +			   pgprot_t *prot);  /* diff --git a/linux-core/drm_ttm.c b/linux-core/drm_ttm.c index a9d87338..cc80b132 100644 --- a/linux-core/drm_ttm.c +++ b/linux-core/drm_ttm.c @@ -42,11 +42,12 @@ void drm_ttm_cache_flush(void)  }  EXPORT_SYMBOL(drm_ttm_cache_flush); -/* - * Use kmalloc if possible. Otherwise fall back to vmalloc. +/** + * Allocates storage for pointers to the pages that back the ttm. + * + * Uses kmalloc if possible. Otherwise falls back to vmalloc.   */ - -static void drm_ttm_alloc_pages(struct drm_ttm *ttm) +static void drm_ttm_alloc_page_directory(struct drm_ttm *ttm)  {  	unsigned long size = ttm->num_pages * sizeof(*ttm->pages);  	ttm->pages = NULL; @@ -60,19 +61,19 @@ static void drm_ttm_alloc_pages(struct drm_ttm *ttm)  	if (!ttm->pages) {  		ttm->pages = vmalloc_user(size);  		if (ttm->pages) -			ttm->page_flags |= DRM_TTM_PAGE_VMALLOC; +			ttm->page_flags |= DRM_TTM_PAGEDIR_VMALLOC;  	}  	if (!ttm->pages)  		drm_free_memctl(size);  } -static void drm_ttm_free_pages(struct drm_ttm *ttm) +static void drm_ttm_free_page_directory(struct drm_ttm *ttm)  {  	unsigned long size = ttm->num_pages * sizeof(*ttm->pages); -	if (ttm->page_flags & DRM_TTM_PAGE_VMALLOC) { +	if (ttm->page_flags & DRM_TTM_PAGEDIR_VMALLOC) {  		vfree(ttm->pages); -		ttm->page_flags &= ~DRM_TTM_PAGE_VMALLOC; +		ttm->page_flags &= ~DRM_TTM_PAGEDIR_VMALLOC;  	} else {  		drm_free(ttm->pages, size, DRM_MEM_TTM);  	} @@ -215,7 +216,7 @@ int drm_ttm_destroy(struct drm_ttm *ttm)  		else  			drm_ttm_free_alloced_pages(ttm); -		drm_ttm_free_pages(ttm); +		drm_ttm_free_page_directory(ttm);  	}  	drm_ctl_free(ttm, sizeof(*ttm), DRM_MEM_TTM); @@ -349,7 +350,7 @@ struct drm_ttm *drm_ttm_create(struct drm_device *dev, unsigned long size,  	 * Account also for AGP module memory usage.  	 */ -	drm_ttm_alloc_pages(ttm); +	drm_ttm_alloc_page_directory(ttm);  	if (!ttm->pages) {  		drm_ttm_destroy(ttm);  		DRM_ERROR("Failed allocating page table\n"); | 
