summaryrefslogtreecommitdiff
path: root/linux-core
diff options
context:
space:
mode:
authorDave Airlie <airlied@panoply-rh.(none)>2008-03-05 10:37:02 +1000
committerDave Airlie <airlied@panoply-rh.(none)>2008-03-05 10:37:02 +1000
commit43891ff2d0176f013796b3c2a340b7d379d703ee (patch)
tree734cdcd6e6c36997f1db92d41b92e4557ebf13b1 /linux-core
parent81db48536c9d7bb23c448af6a6f1de81df755585 (diff)
parenta6a2f2c8c491617de702dc7d62bb55cbada4d42b (diff)
Merge remote branch 'origin/master' into modesetting-101
Conflicts: linux-core/drm_compat.c
Diffstat (limited to 'linux-core')
-rw-r--r--linux-core/drm_agpsupport.c2
-rw-r--r--linux-core/drm_bo_move.c33
-rw-r--r--linux-core/drm_compat.c29
-rw-r--r--linux-core/drm_compat.h5
-rw-r--r--linux-core/drm_objects.h6
-rw-r--r--linux-core/drm_ttm.c21
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");