summaryrefslogtreecommitdiff
path: root/linux-core
diff options
context:
space:
mode:
Diffstat (limited to 'linux-core')
-rw-r--r--linux-core/ati_pcigart.c6
-rw-r--r--linux-core/drmP.h6
-rw-r--r--linux-core/drm_agpsupport.c2
-rw-r--r--linux-core/drm_bo.c5
-rw-r--r--linux-core/drm_bo_move.c33
-rw-r--r--linux-core/drm_compat.c29
-rw-r--r--linux-core/drm_compat.h10
-rw-r--r--linux-core/drm_crtc.c38
-rw-r--r--linux-core/drm_drv.c18
-rw-r--r--linux-core/drm_edid.c28
-rw-r--r--linux-core/drm_fops.c3
-rw-r--r--linux-core/drm_irq.c4
-rw-r--r--linux-core/drm_objects.h8
-rw-r--r--linux-core/drm_scatter.c11
-rw-r--r--linux-core/drm_stub.c9
-rw-r--r--linux-core/drm_ttm.c21
-rw-r--r--linux-core/drm_vm.c19
-rw-r--r--linux-core/i915_drv.c15
-rw-r--r--linux-core/intel_fb.c31
19 files changed, 231 insertions, 65 deletions
diff --git a/linux-core/ati_pcigart.c b/linux-core/ati_pcigart.c
index 68029635..93519e5f 100644
--- a/linux-core/ati_pcigart.c
+++ b/linux-core/ati_pcigart.c
@@ -224,6 +224,12 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
}
}
+ if (gart_info->gart_table_location == DRM_ATI_GART_MAIN)
+ dma_sync_single_for_device(&dev->pdev->dev,
+ bus_address,
+ max_pages * sizeof(u32),
+ PCI_DMA_TODEVICE);
+
ret = 1;
#if defined(__i386__) || defined(__x86_64__)
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index 51b02dc8..47974856 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -106,6 +106,7 @@ struct drm_file;
#define DRIVER_IRQ_SHARED 0x80
#define DRIVER_DMA_QUEUE 0x100
#define DRIVER_FB_DMA 0x200
+#define DRIVER_MODESET 0x400
/*@}*/
@@ -760,9 +761,10 @@ struct drm_driver {
};
#define DRM_MINOR_UNASSIGNED 0
-#define DRM_MINOR_CONTROL 1
-#define DRM_MINOR_LEGACY 2
+#define DRM_MINOR_LEGACY 1
+#define DRM_MINOR_CONTROL 2
#define DRM_MINOR_RENDER 3
+
/**
* DRM minor structure. This structure represents a drm minor number.
*/
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.c b/linux-core/drm_bo.c
index b6115e8d..1d3f87e5 100644
--- a/linux-core/drm_bo.c
+++ b/linux-core/drm_bo.c
@@ -969,7 +969,7 @@ static int drm_bo_modify_proposed_flags (struct drm_buffer_object *bo,
return -EINVAL;
}
- if ((new_mask & DRM_BO_FLAG_NO_EVICT) && !DRM_SUSER(DRM_CURPROC)) {
+ if (bo->type != drm_bo_type_kernel && (new_mask & DRM_BO_FLAG_NO_EVICT) && !DRM_SUSER(DRM_CURPROC)) {
DRM_ERROR("DRM_BO_FLAG_NO_EVICT is only available to priviliged processes.\n");
return -EPERM;
}
@@ -1065,7 +1065,7 @@ static int drm_bo_busy(struct drm_buffer_object *bo)
return 0;
}
-static int drm_bo_evict_cached(struct drm_buffer_object *bo)
+int drm_bo_evict_cached(struct drm_buffer_object *bo)
{
int ret = 0;
@@ -1075,6 +1075,7 @@ static int drm_bo_evict_cached(struct drm_buffer_object *bo)
return ret;
}
+EXPORT_SYMBOL(drm_bo_evict_cached);
/*
* Wait until a buffer is unmapped.
*/
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..9b982662 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);
+#endif
+
diff --git a/linux-core/drm_compat.h b/linux-core/drm_compat.h
index f5f06017..03838a18 100644
--- a/linux-core/drm_compat.h
+++ b/linux-core/drm_compat.h
@@ -343,4 +343,14 @@ 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
+
+#if !defined(flush_agp_mappings)
+#define flush_agp_mappings() do {} while(0)
+#endif
+
#endif
diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c
index 1a4624c8..e0c85cef 100644
--- a/linux-core/drm_crtc.c
+++ b/linux-core/drm_crtc.c
@@ -48,7 +48,8 @@ static struct drm_prop_enum_list drm_dpms_enum_list[] =
{ DPMSModeOff, "Off" }
};
static struct drm_prop_enum_list drm_conn_enum_list[] =
-{ { ConnectorVGA, "VGA" },
+{ { ConnectorUnknown, "Unknown" },
+ { ConnectorVGA, "VGA" },
{ ConnectorDVII, "DVI-I" },
{ ConnectorDVID, "DVI-D" },
{ ConnectorDVIA, "DVI-A" },
@@ -419,14 +420,14 @@ bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
int saved_x, saved_y;
bool didLock = false;
struct drm_output *output;
+ bool ret = true;
adjusted_mode = drm_mode_duplicate(dev, mode);
crtc->enabled = drm_crtc_in_use(crtc);
- if (!crtc->enabled) {
+ if (!crtc->enabled)
return true;
- }
didLock = crtc->funcs->lock(crtc);
@@ -457,12 +458,12 @@ bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
if (output->crtc != crtc)
continue;
- if (!output->funcs->mode_fixup(output, mode, adjusted_mode)) {
+ if (!(ret = output->funcs->mode_fixup(output, mode, adjusted_mode))) {
goto done;
}
}
- if (!crtc->funcs->mode_fixup(crtc, mode, adjusted_mode)) {
+ if (!(ret = crtc->funcs->mode_fixup(crtc, mode, adjusted_mode))) {
goto done;
}
@@ -516,10 +517,16 @@ bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
// drm_crtc_set_screen_sub_pixel_order(dev);
done:
+ if (!ret) {
+ crtc->mode = saved_mode;
+ crtc->x = saved_x;
+ crtc->y = saved_y;
+ }
+
if (didLock)
crtc->funcs->unlock (crtc);
- return true;
+ return ret;
}
EXPORT_SYMBOL(drm_crtc_set_mode);
@@ -728,20 +735,20 @@ static int drm_mode_create_standard_output_properties(struct drm_device *dev)
"EDID", 0);
dev->mode_config.dpms_property =
- drm_property_create(dev, DRM_MODE_PROP_ENUM, "DPMS", 4);
-
+ drm_property_create(dev, DRM_MODE_PROP_ENUM,
+ "DPMS", ARRAY_SIZE(drm_dpms_enum_list));
for (i = 0; i < ARRAY_SIZE(drm_dpms_enum_list); i++)
drm_property_add_enum(dev->mode_config.dpms_property, i, drm_dpms_enum_list[i].type, drm_dpms_enum_list[i].name);
dev->mode_config.connector_type_property =
drm_property_create(dev, DRM_MODE_PROP_ENUM | DRM_MODE_PROP_IMMUTABLE,
- "Connector Type", 10);
+ "Connector Type", ARRAY_SIZE(drm_conn_enum_list));
for (i = 0; i < ARRAY_SIZE(drm_conn_enum_list); i++)
drm_property_add_enum(dev->mode_config.connector_type_property, i, drm_conn_enum_list[i].type, drm_conn_enum_list[i].name);
dev->mode_config.connector_num_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE | DRM_MODE_PROP_IMMUTABLE,
- "Connector ID", 2);
+ "Connector ID", 2);
dev->mode_config.connector_num_property->values[0] = 0;
dev->mode_config.connector_num_property->values[1] = 20;
@@ -776,7 +783,6 @@ static int drm_mode_create_standard_output_properties(struct drm_device *dev)
dev->mode_config.tv_bottom_margin_property->values[0] = 0;
dev->mode_config.tv_bottom_margin_property->values[1] = 100;
-
return 0;
}
@@ -1104,13 +1110,17 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info,
/* We should be able to check here if the fb has the same properties
* and then just flip_or_move it */
if (crtc->fb != fb)
- changed = true;
+ flip_or_move = true;
if (crtc_info->x != crtc->x || crtc_info->y != crtc->y)
flip_or_move = true;
- if (new_mode && !drm_mode_equal(new_mode, &crtc->mode))
+ if (new_mode && !drm_mode_equal(new_mode, &crtc->mode)) {
+ DRM_DEBUG("modes are different\n");
+ drm_mode_debug_printmodeline(dev, &crtc->mode);
+ drm_mode_debug_printmodeline(dev, new_mode);
changed = true;
+ }
list_for_each_entry(output, &dev->mode_config.output_list, head) {
save_crtcs[count++] = output->crtc;
@@ -1155,6 +1165,8 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info,
}
drm_disable_unused_functions(dev);
} else if (flip_or_move) {
+ if (crtc->fb != fb)
+ crtc->fb = fb;
crtc->funcs->mode_set_base(crtc, crtc_info->x, crtc_info->y);
}
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
index 4932ea59..434789dd 100644
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -187,7 +187,9 @@ int drm_lastclose(struct drm_device * dev)
DRM_DEBUG("\n");
-/* return 0; */
+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
+ drm_bo_driver_finish(dev);
+
/*
* We can't do much about this function failing.
*/
@@ -414,7 +416,8 @@ static void drm_cleanup(struct drm_device * dev)
drm_ht_remove(&dev->object_hash);
drm_put_minor(&dev->primary);
- drm_put_minor(&dev->control);
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ drm_put_minor(&dev->control);
if (drm_put_dev(dev))
DRM_ERROR("Cannot unload module\n");
}
@@ -424,13 +427,20 @@ int drm_minors_cleanup(int id, void *ptr, void *data)
struct drm_minor *minor = ptr;
struct drm_device *dev;
struct drm_driver *driver = data;
- if (id < 127 || id > 192)
- return 0;
dev = minor->dev;
if (minor->dev->driver != driver)
return 0;
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ if (minor->type != DRM_MINOR_CONTROL)
+ return 0;
+ } else {
+ if (minor->type != DRM_MINOR_LEGACY)
+ return 0;
+ }
+
+
if (dev)
pci_dev_put(dev->pdev);
drm_cleanup(dev);
diff --git a/linux-core/drm_edid.c b/linux-core/drm_edid.c
index 41aa8f5e..9762567b 100644
--- a/linux-core/drm_edid.c
+++ b/linux-core/drm_edid.c
@@ -223,8 +223,10 @@ static int add_established_modes(struct drm_output *output, struct edid *edid)
if (est_bits & (1<<i)) {
struct drm_display_mode *newmode;
newmode = drm_mode_duplicate(dev, &edid_est_modes[i]);
- drm_mode_probed_add(output, newmode);
- modes++;
+ if (newmode) {
+ drm_mode_probed_add(output, newmode);
+ modes++;
+ }
}
return modes;
@@ -251,8 +253,10 @@ static int add_standard_modes(struct drm_output *output, struct edid *edid)
continue;
newmode = drm_mode_std(dev, &edid->standard_timings[i]);
- drm_mode_probed_add(output, newmode);
- modes++;
+ if (newmode) {
+ drm_mode_probed_add(output, newmode);
+ modes++;
+ }
}
return modes;
@@ -283,11 +287,13 @@ static int add_detailed_info(struct drm_output *output, struct edid *edid)
if (timing->pixel_clock) {
newmode = drm_mode_detailed(dev, timing);
/* First detailed mode is preferred */
- if (i == 0 && edid->preferred_timing)
- newmode->type |= DRM_MODE_TYPE_PREFERRED;
- drm_mode_probed_add(output, newmode);
+ if (newmode) {
+ if (i == 0 && edid->preferred_timing)
+ newmode->type |= DRM_MODE_TYPE_PREFERRED;
+ drm_mode_probed_add(output, newmode);
- modes++;
+ modes++;
+ }
continue;
}
@@ -312,8 +318,10 @@ static int add_detailed_info(struct drm_output *output, struct edid *edid)
std = &data->data.timings[j];
newmode = drm_mode_std(dev, std);
- drm_mode_probed_add(output, newmode);
- modes++;
+ if (newmode) {
+ drm_mode_probed_add(output, newmode);
+ modes++;
+ }
}
break;
default:
diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c
index 5a74f424..fcadc544 100644
--- a/linux-core/drm_fops.c
+++ b/linux-core/drm_fops.c
@@ -481,7 +481,8 @@ int drm_release(struct inode *inode, struct file *filp)
}
mutex_unlock(&dev->ctxlist_mutex);
- drm_fb_release(filp);
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ drm_fb_release(filp);
file_priv->master = NULL;
diff --git a/linux-core/drm_irq.c b/linux-core/drm_irq.c
index 637f5e1d..6b740b18 100644
--- a/linux-core/drm_irq.c
+++ b/linux-core/drm_irq.c
@@ -306,6 +306,8 @@ int drm_control(struct drm_device *dev, void *data,
case DRM_INST_HANDLER:
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return 0;
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ return 0;
if (dev->if_version < DRM_IF_VERSION(1, 2) &&
ctl->irq != dev->irq)
return -EINVAL;
@@ -313,6 +315,8 @@ int drm_control(struct drm_device *dev, void *data,
case DRM_UNINST_HANDLER:
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return 0;
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ return 0;
return drm_irq_uninstall(dev);
default:
return -EINVAL;
diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h
index cce58178..8f81b665 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
*/
@@ -700,7 +700,7 @@ extern int drm_bo_do_validate(struct drm_buffer_object *bo,
uint64_t flags, uint64_t mask, uint32_t hint,
uint32_t fence_class,
struct drm_bo_info_rep *rep);
-
+extern int drm_bo_evict_cached(struct drm_buffer_object *bo);
/*
* Buffer object memory move- and map helpers.
* drm_bo_move.c
@@ -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_scatter.c b/linux-core/drm_scatter.c
index 77b9f95d..dfae4b84 100644
--- a/linux-core/drm_scatter.c
+++ b/linux-core/drm_scatter.c
@@ -36,6 +36,15 @@
#define DEBUG_SCATTER 0
+static inline void *drm_vmalloc_dma(unsigned long size)
+{
+#if defined(__powerpc__) && defined(CONFIG_NOT_COHERENT_CACHE)
+ return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL | _PAGE_NO_CACHE);
+#else
+ return vmalloc_32(size);
+#endif
+}
+
void drm_sg_cleanup(struct drm_sg_mem *entry)
{
struct page *page;
@@ -105,7 +114,7 @@ int drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather * request)
}
memset((void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr));
- entry->virtual = vmalloc_32(pages << PAGE_SHIFT);
+ entry->virtual = drm_vmalloc_dma(pages << PAGE_SHIFT);
if (!entry->virtual) {
drm_free(entry->busaddr,
entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES);
diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c
index 334c8f03..6856075b 100644
--- a/linux-core/drm_stub.c
+++ b/linux-core/drm_stub.c
@@ -343,8 +343,10 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
goto err_g3;
}
- if ((ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL)))
- goto err_g3;
+ /* only add the control node on a modesetting platform */
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ if ((ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL)))
+ goto err_g3;
if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY)))
goto err_g4;
@@ -361,7 +363,8 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
err_g5:
drm_put_minor(&dev->primary);
err_g4:
- drm_put_minor(&dev->control);
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ drm_put_minor(&dev->control);
err_g3:
if (!drm_fb_loaded)
pci_disable_device(pdev);
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");
diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c
index 15e1c0f5..ffda8284 100644
--- a/linux-core/drm_vm.c
+++ b/linux-core/drm_vm.c
@@ -59,17 +59,27 @@ pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma)
pgprot_val(tmp) |= _PAGE_NO_CACHE;
if (map_type == _DRM_REGISTERS)
pgprot_val(tmp) |= _PAGE_GUARDED;
-#endif
-#if defined(__ia64__)
+#elif defined(__ia64__)
if (efi_range_is_wc(vma->vm_start, vma->vm_end -
vma->vm_start))
tmp = pgprot_writecombine(tmp);
else
tmp = pgprot_noncached(tmp);
+#elif defined(__sparc__)
+ tmp = pgprot_noncached(tmp);
#endif
return tmp;
}
+static pgprot_t drm_dma_prot(uint32_t map_type, struct vm_area_struct *vma)
+{
+ pgprot_t tmp = vm_get_page_prot(vma->vm_flags);
+
+#if defined(__powerpc__) && defined(CONFIG_NOT_COHERENT_CACHE)
+ tmp |= _PAGE_NO_CACHE;
+#endif
+ return tmp;
+}
/**
* \c nopage method for AGP virtual memory.
@@ -628,9 +638,6 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
offset = dev->driver->get_reg_ofs(dev);
vma->vm_flags |= VM_IO; /* not in core dump */
vma->vm_page_prot = drm_io_prot(map->type, vma);
-#ifdef __sparc__
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-#endif
if (io_remap_pfn_range(vma, vma->vm_start,
(map->offset + offset) >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
@@ -649,6 +656,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
page_to_pfn(virt_to_page(map->handle)),
vma->vm_end - vma->vm_start, vma->vm_page_prot))
return -EAGAIN;
+ vma->vm_page_prot = drm_dma_prot(map->type, vma);
/* fall through to _DRM_SHM */
case _DRM_SHM:
vma->vm_ops = &drm_vm_shm_ops;
@@ -661,6 +669,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
vma->vm_ops = &drm_vm_sg_ops;
vma->vm_private_data = (void *)map;
vma->vm_flags |= VM_RESERVED;
+ vma->vm_page_prot = drm_dma_prot(map->type, vma);
break;
case _DRM_TTM:
return drm_bo_mmap_locked(vma, filp, map);
diff --git a/linux-core/i915_drv.c b/linux-core/i915_drv.c
index 6c12f1a1..0e65c0cd 100644
--- a/linux-core/i915_drv.c
+++ b/linux-core/i915_drv.c
@@ -39,14 +39,17 @@ static struct pci_device_id pciidlist[] = {
i915_PCI_IDS
};
+unsigned int i915_modeset = 0;
+module_param_named(modeset, i915_modeset, int, 0400);
+
#ifdef I915_HAVE_FENCE
extern struct drm_fence_driver i915_fence_driver;
#endif
#ifdef I915_HAVE_BUFFER
-static uint32_t i915_mem_prios[] = {DRM_BO_MEM_VRAM, DRM_BO_MEM_PRIV0, DRM_BO_MEM_TT, DRM_BO_MEM_LOCAL};
-static uint32_t i915_busy_prios[] = {DRM_BO_MEM_TT, DRM_BO_MEM_PRIV0, DRM_BO_MEM_VRAM, DRM_BO_MEM_LOCAL};
+static uint32_t i915_mem_prios[] = {DRM_BO_MEM_VRAM, DRM_BO_MEM_TT, DRM_BO_MEM_LOCAL};
+static uint32_t i915_busy_prios[] = {DRM_BO_MEM_TT, DRM_BO_MEM_VRAM, DRM_BO_MEM_LOCAL};
static struct drm_bo_driver i915_bo_driver = {
.mem_type_prio = i915_mem_prios,
@@ -563,8 +566,9 @@ static struct drm_driver driver = {
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
.load = i915_driver_load,
.unload = i915_driver_unload,
-/* .lastclose = i915_driver_lastclose,
- .preclose = i915_driver_preclose, */
+ .firstopen = i915_driver_firstopen,
+ .lastclose = i915_driver_lastclose,
+ .preclose = i915_driver_preclose,
.suspend = i915_suspend,
.resume = i915_resume,
.device_is_agp = i915_driver_device_is_agp,
@@ -624,6 +628,9 @@ static int probe(struct pci_dev *pdev, const struct pci_device_id *ent)
static int __init i915_init(void)
{
driver.num_ioctls = i915_max_ioctl;
+ if (i915_modeset == 1)
+ driver.driver_features |= DRIVER_MODESET;
+
return drm_init(&driver, pciidlist);
}
diff --git a/linux-core/intel_fb.c b/linux-core/intel_fb.c
index e33494c6..52ff3a67 100644
--- a/linux-core/intel_fb.c
+++ b/linux-core/intel_fb.c
@@ -228,6 +228,7 @@ static int intelfb_set_par(struct fb_info *info)
struct drm_output *output = NULL;
struct fb_var_screeninfo *var = &info->var;
int found = 0;
+ int changed = 0;
DRM_DEBUG("\n");
@@ -310,11 +311,22 @@ static int intelfb_set_par(struct fb_info *info)
}
/* re-attach fb */
- if (!par->crtc->fb)
+ if (!par->crtc->fb) {
par->crtc->fb = par->fb;
+ changed = 1;
+ }
- if (!drm_crtc_set_mode(par->crtc, drm_mode, var->xoffset, var->yoffset))
- return -EINVAL;
+ if (par->crtc->x != var->xoffset || par->crtc->y != var->yoffset)
+ changed = 1;
+
+ drm_mode_debug_printmodeline(dev, drm_mode);
+ drm_mode_debug_printmodeline(dev, &par->crtc->mode);
+ if (!drm_mode_equal(drm_mode, &par->crtc->mode))
+ changed = 1;
+
+ if (changed)
+ if (!drm_crtc_set_mode(par->crtc, drm_mode, var->xoffset, var->yoffset))
+ return -EINVAL;
return 0;
}
@@ -469,16 +481,21 @@ static int intelfb_pan_display(struct fb_var_screeninfo *var,
{
struct intelfb_par *par = info->par;
struct drm_crtc *crtc = par->crtc;
-
+ int changed = 0;
DRM_DEBUG("\n");
/* TODO add check size and pos*/
+ if (par->crtc->x != var->xoffset || par->crtc->y != var->yoffset)
+ changed = 1;
/* re-attach fb */
- if (!crtc->fb)
+ if (!crtc->fb) {
crtc->fb = par->fb;
+ changed = 1;
+ }
- drm_crtc_set_mode(crtc, &crtc->mode, var->xoffset, var->yoffset);
+ if (changed)
+ drm_crtc_set_mode(crtc, &crtc->mode, var->xoffset, var->yoffset);
info->var.xoffset = var->xoffset;
info->var.yoffset = var->yoffset;
@@ -572,7 +589,7 @@ int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc)
fb->bits_per_pixel = 32;
fb->pitch = fb->width * ((fb->bits_per_pixel + 1) / 8);
fb->depth = 24;
- ret = drm_buffer_object_create(dev, fb->pitch * fb->height * 4,
+ ret = drm_buffer_object_create(dev, fb->pitch * fb->height,
drm_bo_type_kernel,
DRM_BO_FLAG_READ |
DRM_BO_FLAG_WRITE |