Merge branch 'modesetting-101' of ssh://git.freedesktop.org/git/mesa/drm into modesetting-101
commit
a7e6ca62ad
|
@ -2809,18 +2809,13 @@ int drmBOWaitIdle(int fd, drmBO *buf, unsigned hint)
|
||||||
|
|
||||||
int drmBOBusy(int fd, drmBO *buf, int *busy)
|
int drmBOBusy(int fd, drmBO *buf, int *busy)
|
||||||
{
|
{
|
||||||
if (!(buf->flags & DRM_BO_FLAG_SHAREABLE) &&
|
int ret = drmBOInfo(fd, buf);
|
||||||
!(buf->replyFlags & DRM_BO_REP_BUSY)) {
|
|
||||||
*busy = 0;
|
if (ret)
|
||||||
return 0;
|
return ret;
|
||||||
}
|
|
||||||
else {
|
*busy = (buf->replyFlags & DRM_BO_REP_BUSY);
|
||||||
int ret = drmBOInfo(fd, buf);
|
return 0;
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
*busy = (buf->replyFlags & DRM_BO_REP_BUSY);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int drmMMInit(int fd, unsigned long pOffset, unsigned long pSize,
|
int drmMMInit(int fd, unsigned long pOffset, unsigned long pSize,
|
||||||
|
|
|
@ -36,11 +36,15 @@
|
||||||
* platforms find which headers to include to get uint32_t
|
* platforms find which headers to include to get uint32_t
|
||||||
*/
|
*/
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "xf86drmMode.h"
|
#include "xf86drmMode.h"
|
||||||
#include "xf86drm.h"
|
#include "xf86drm.h"
|
||||||
#include <drm.h>
|
#include <drm.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#define U642VOID(x) ((void *)(unsigned long)(x))
|
#define U642VOID(x) ((void *)(unsigned long)(x))
|
||||||
#define VOID2U64(x) ((uint64_t)(unsigned long)(x))
|
#define VOID2U64(x) ((uint64_t)(unsigned long)(x))
|
||||||
|
@ -66,27 +70,6 @@ void* drmAllocCpy(void *array, int count, int entry_size)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate crtc and output ids.
|
|
||||||
*
|
|
||||||
* Will generate ids starting from 1 up to count if count is greater then 0.
|
|
||||||
*/
|
|
||||||
static uint32_t* drmAllocGenerate(int count)
|
|
||||||
{
|
|
||||||
uint32_t *r;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if(0 <= count)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!(r = drmMalloc(count*sizeof(*r))))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (i = 0; i < count; r[i] = ++i);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A couple of free functions.
|
* A couple of free functions.
|
||||||
*/
|
*/
|
||||||
|
@ -143,7 +126,6 @@ void drmModeFreeOutput(drmModeOutputPtr ptr)
|
||||||
drmModeResPtr drmModeGetResources(int fd)
|
drmModeResPtr drmModeGetResources(int fd)
|
||||||
{
|
{
|
||||||
struct drm_mode_card_res res;
|
struct drm_mode_card_res res;
|
||||||
int i;
|
|
||||||
drmModeResPtr r = 0;
|
drmModeResPtr r = 0;
|
||||||
|
|
||||||
memset(&res, 0, sizeof(struct drm_mode_card_res));
|
memset(&res, 0, sizeof(struct drm_mode_card_res));
|
||||||
|
@ -201,7 +183,8 @@ uint32_t drmModeGetHotplug(int fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
|
int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
|
||||||
uint8_t bpp, uint32_t pitch, drmBO *bo, uint32_t *buf_id)
|
uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
|
||||||
|
uint32_t *buf_id)
|
||||||
{
|
{
|
||||||
struct drm_mode_fb_cmd f;
|
struct drm_mode_fb_cmd f;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -211,9 +194,9 @@ int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
|
||||||
f.pitch = pitch;
|
f.pitch = pitch;
|
||||||
f.bpp = bpp;
|
f.bpp = bpp;
|
||||||
f.depth = depth;
|
f.depth = depth;
|
||||||
f.handle = bo->handle;
|
f.handle = bo_handle;
|
||||||
|
|
||||||
if (ret = ioctl(fd, DRM_IOCTL_MODE_ADDFB, &f))
|
if ((ret = ioctl(fd, DRM_IOCTL_MODE_ADDFB, &f)))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
*buf_id = f.buffer_id;
|
*buf_id = f.buffer_id;
|
||||||
|
@ -260,7 +243,6 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
|
||||||
{
|
{
|
||||||
struct drm_mode_crtc crtc;
|
struct drm_mode_crtc crtc;
|
||||||
drmModeCrtcPtr r;
|
drmModeCrtcPtr r;
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
crtc.count_outputs = 0;
|
crtc.count_outputs = 0;
|
||||||
crtc.outputs = 0;
|
crtc.outputs = 0;
|
||||||
|
@ -293,10 +275,6 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
|
||||||
r->possibles = crtc.possibles;
|
r->possibles = crtc.possibles;
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
err_allocs:
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -450,8 +428,7 @@ drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id)
|
||||||
{
|
{
|
||||||
struct drm_mode_get_property prop;
|
struct drm_mode_get_property prop;
|
||||||
drmModePropertyPtr r;
|
drmModePropertyPtr r;
|
||||||
struct drm_mode_property_blob *blob_tmp;
|
|
||||||
int i;
|
|
||||||
prop.prop_id = property_id;
|
prop.prop_id = property_id;
|
||||||
prop.count_enum_blobs = 0;
|
prop.count_enum_blobs = 0;
|
||||||
prop.count_values = 0;
|
prop.count_values = 0;
|
||||||
|
@ -566,8 +543,71 @@ int drmModeOutputSetProperty(int fd, uint32_t output_id, uint32_t property_id,
|
||||||
osp.prop_id = property_id;
|
osp.prop_id = property_id;
|
||||||
osp.value = value;
|
osp.value = value;
|
||||||
|
|
||||||
if (ret = ioctl(fd, DRM_IOCTL_MODE_SETPROPERTY, &osp))
|
if ((ret = ioctl(fd, DRM_IOCTL_MODE_SETPROPERTY, &osp)))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* checks if a modesetting capable driver has attached to the pci id
|
||||||
|
* returns 0 if modesetting supported.
|
||||||
|
* -EINVAL or invalid bus id
|
||||||
|
* -ENOSYS if no modesetting support
|
||||||
|
*/
|
||||||
|
int drmCheckModesettingSupported(const char *busid)
|
||||||
|
{
|
||||||
|
#ifdef __linux__
|
||||||
|
char pci_dev_dir[1024];
|
||||||
|
int domain, bus, dev, func;
|
||||||
|
DIR *sysdir;
|
||||||
|
struct dirent *dent;
|
||||||
|
int found = 0, ret;
|
||||||
|
|
||||||
|
ret = sscanf(busid, "pci:%04x:%02x:%02x.%d", &domain, &bus, &dev, &func);
|
||||||
|
if (ret != 4)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
sprintf(pci_dev_dir, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/drm",
|
||||||
|
domain, bus, dev, func);
|
||||||
|
|
||||||
|
sysdir = opendir(pci_dev_dir);
|
||||||
|
if (sysdir) {
|
||||||
|
dent = readdir(sysdir);
|
||||||
|
while (dent) {
|
||||||
|
if (!strncmp(dent->d_name, "controlD", 8)) {
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dent = readdir(sysdir);
|
||||||
|
}
|
||||||
|
closedir(sysdir);
|
||||||
|
if (found)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(pci_dev_dir, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/",
|
||||||
|
domain, bus, dev, func);
|
||||||
|
|
||||||
|
sysdir = opendir(pci_dev_dir);
|
||||||
|
if (!sysdir)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
dent = readdir(sysdir);
|
||||||
|
while (dent) {
|
||||||
|
if (!strncmp(dent->d_name, "drm:controlD", 12)) {
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dent = readdir(sysdir);
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(sysdir);
|
||||||
|
if (found)
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
return -ENOSYS;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -177,7 +177,7 @@ extern drmModeFBPtr drmModeGetFB(int fd, uint32_t bufferId);
|
||||||
* Creates a new framebuffer with an buffer object as its scanout buffer.
|
* Creates a new framebuffer with an buffer object as its scanout buffer.
|
||||||
*/
|
*/
|
||||||
extern int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
|
extern int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
|
||||||
uint8_t bpp, uint32_t pitch, drmBO *bo,
|
uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
|
||||||
uint32_t *buf_id);
|
uint32_t *buf_id);
|
||||||
/**
|
/**
|
||||||
* Destroies the given framebuffer.
|
* Destroies the given framebuffer.
|
||||||
|
@ -243,3 +243,4 @@ extern drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd, uint32_t blob_id);
|
||||||
extern void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr);
|
extern void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr);
|
||||||
extern int drmModeOutputSetProperty(int fd, uint32_t output_id, uint32_t property_id,
|
extern int drmModeOutputSetProperty(int fd, uint32_t output_id, uint32_t property_id,
|
||||||
uint64_t value);
|
uint64_t value);
|
||||||
|
extern int drmCheckModesettingSupported(const char *busid);
|
||||||
|
|
|
@ -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;
|
ret = 1;
|
||||||
|
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
|
|
|
@ -106,6 +106,7 @@ struct drm_file;
|
||||||
#define DRIVER_IRQ_SHARED 0x80
|
#define DRIVER_IRQ_SHARED 0x80
|
||||||
#define DRIVER_DMA_QUEUE 0x100
|
#define DRIVER_DMA_QUEUE 0x100
|
||||||
#define DRIVER_FB_DMA 0x200
|
#define DRIVER_FB_DMA 0x200
|
||||||
|
#define DRIVER_MODESET 0x400
|
||||||
|
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
@ -760,9 +761,10 @@ struct drm_driver {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DRM_MINOR_UNASSIGNED 0
|
#define DRM_MINOR_UNASSIGNED 0
|
||||||
#define DRM_MINOR_CONTROL 1
|
#define DRM_MINOR_LEGACY 1
|
||||||
#define DRM_MINOR_LEGACY 2
|
#define DRM_MINOR_CONTROL 2
|
||||||
#define DRM_MINOR_RENDER 3
|
#define DRM_MINOR_RENDER 3
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DRM minor structure. This structure represents a drm minor number.
|
* DRM minor structure. This structure represents a drm minor number.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -666,7 +666,7 @@ void drm_agp_chipset_flush(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
agp_flush_chipset(dev->agp->bridge);
|
agp_flush_chipset(dev->agp->bridge);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_agp_flush_chipset);
|
EXPORT_SYMBOL(drm_agp_chipset_flush);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __OS_HAS_AGP */
|
#endif /* __OS_HAS_AGP */
|
||||||
|
|
|
@ -969,7 +969,7 @@ static int drm_bo_modify_proposed_flags (struct drm_buffer_object *bo,
|
||||||
return -EINVAL;
|
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");
|
DRM_ERROR("DRM_BO_FLAG_NO_EVICT is only available to priviliged processes.\n");
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
}
|
}
|
||||||
|
@ -1065,7 +1065,7 @@ static int drm_bo_busy(struct drm_buffer_object *bo)
|
||||||
return 0;
|
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;
|
int ret = 0;
|
||||||
|
|
||||||
|
@ -1075,6 +1075,7 @@ static int drm_bo_evict_cached(struct drm_buffer_object *bo)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(drm_bo_evict_cached);
|
||||||
/*
|
/*
|
||||||
* Wait until a buffer is unmapped.
|
* Wait until a buffer is unmapped.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -596,3 +596,36 @@ void drm_bo_kunmap(struct drm_bo_kmap_obj *map)
|
||||||
map->page = NULL;
|
map->page = NULL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_bo_kunmap);
|
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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
EXPORT_SYMBOL(pci_get_bus_and_slot);
|
||||||
#endif
|
#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
|
||||||
|
|
||||||
|
|
|
@ -343,4 +343,14 @@ extern struct pci_dev * pci_get_bus_and_slot(unsigned int bus, unsigned int devf
|
||||||
#define PM_EVENT_PRETHAW 3
|
#define PM_EVENT_PRETHAW 3
|
||||||
#endif
|
#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
|
#endif
|
||||||
|
|
|
@ -48,7 +48,8 @@ static struct drm_prop_enum_list drm_dpms_enum_list[] =
|
||||||
{ DPMSModeOff, "Off" }
|
{ DPMSModeOff, "Off" }
|
||||||
};
|
};
|
||||||
static struct drm_prop_enum_list drm_conn_enum_list[] =
|
static struct drm_prop_enum_list drm_conn_enum_list[] =
|
||||||
{ { ConnectorVGA, "VGA" },
|
{ { ConnectorUnknown, "Unknown" },
|
||||||
|
{ ConnectorVGA, "VGA" },
|
||||||
{ ConnectorDVII, "DVI-I" },
|
{ ConnectorDVII, "DVI-I" },
|
||||||
{ ConnectorDVID, "DVI-D" },
|
{ ConnectorDVID, "DVI-D" },
|
||||||
{ ConnectorDVIA, "DVI-A" },
|
{ 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;
|
int saved_x, saved_y;
|
||||||
bool didLock = false;
|
bool didLock = false;
|
||||||
struct drm_output *output;
|
struct drm_output *output;
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
adjusted_mode = drm_mode_duplicate(dev, mode);
|
adjusted_mode = drm_mode_duplicate(dev, mode);
|
||||||
|
|
||||||
crtc->enabled = drm_crtc_in_use(crtc);
|
crtc->enabled = drm_crtc_in_use(crtc);
|
||||||
|
|
||||||
if (!crtc->enabled) {
|
if (!crtc->enabled)
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
didLock = crtc->funcs->lock(crtc);
|
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)
|
if (output->crtc != crtc)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!output->funcs->mode_fixup(output, mode, adjusted_mode)) {
|
if (!(ret = output->funcs->mode_fixup(output, mode, adjusted_mode))) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!crtc->funcs->mode_fixup(crtc, mode, adjusted_mode)) {
|
if (!(ret = crtc->funcs->mode_fixup(crtc, mode, adjusted_mode))) {
|
||||||
goto done;
|
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);
|
// drm_crtc_set_screen_sub_pixel_order(dev);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
if (!ret) {
|
||||||
|
crtc->mode = saved_mode;
|
||||||
|
crtc->x = saved_x;
|
||||||
|
crtc->y = saved_y;
|
||||||
|
}
|
||||||
|
|
||||||
if (didLock)
|
if (didLock)
|
||||||
crtc->funcs->unlock (crtc);
|
crtc->funcs->unlock (crtc);
|
||||||
|
|
||||||
return true;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_crtc_set_mode);
|
EXPORT_SYMBOL(drm_crtc_set_mode);
|
||||||
|
|
||||||
|
@ -728,20 +735,20 @@ static int drm_mode_create_standard_output_properties(struct drm_device *dev)
|
||||||
"EDID", 0);
|
"EDID", 0);
|
||||||
|
|
||||||
dev->mode_config.dpms_property =
|
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++)
|
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);
|
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 =
|
dev->mode_config.connector_type_property =
|
||||||
drm_property_create(dev, DRM_MODE_PROP_ENUM | DRM_MODE_PROP_IMMUTABLE,
|
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++)
|
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);
|
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 =
|
dev->mode_config.connector_num_property =
|
||||||
drm_property_create(dev, DRM_MODE_PROP_RANGE | DRM_MODE_PROP_IMMUTABLE,
|
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[0] = 0;
|
||||||
dev->mode_config.connector_num_property->values[1] = 20;
|
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[0] = 0;
|
||||||
dev->mode_config.tv_bottom_margin_property->values[1] = 100;
|
dev->mode_config.tv_bottom_margin_property->values[1] = 100;
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
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
|
/* We should be able to check here if the fb has the same properties
|
||||||
* and then just flip_or_move it */
|
* and then just flip_or_move it */
|
||||||
if (crtc->fb != fb)
|
if (crtc->fb != fb)
|
||||||
changed = true;
|
flip_or_move = true;
|
||||||
|
|
||||||
if (crtc_info->x != crtc->x || crtc_info->y != crtc->y)
|
if (crtc_info->x != crtc->x || crtc_info->y != crtc->y)
|
||||||
flip_or_move = true;
|
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;
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
list_for_each_entry(output, &dev->mode_config.output_list, head) {
|
list_for_each_entry(output, &dev->mode_config.output_list, head) {
|
||||||
save_crtcs[count++] = output->crtc;
|
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);
|
drm_disable_unused_functions(dev);
|
||||||
} else if (flip_or_move) {
|
} else if (flip_or_move) {
|
||||||
|
if (crtc->fb != fb)
|
||||||
|
crtc->fb = fb;
|
||||||
crtc->funcs->mode_set_base(crtc, crtc_info->x, crtc_info->y);
|
crtc->funcs->mode_set_base(crtc, crtc_info->x, crtc_info->y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -187,7 +187,9 @@ int drm_lastclose(struct drm_device * dev)
|
||||||
|
|
||||||
DRM_DEBUG("\n");
|
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.
|
* 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_ht_remove(&dev->object_hash);
|
||||||
|
|
||||||
drm_put_minor(&dev->primary);
|
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))
|
if (drm_put_dev(dev))
|
||||||
DRM_ERROR("Cannot unload module\n");
|
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_minor *minor = ptr;
|
||||||
struct drm_device *dev;
|
struct drm_device *dev;
|
||||||
struct drm_driver *driver = data;
|
struct drm_driver *driver = data;
|
||||||
if (id < 127 || id > 192)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
dev = minor->dev;
|
dev = minor->dev;
|
||||||
if (minor->dev->driver != driver)
|
if (minor->dev->driver != driver)
|
||||||
return 0;
|
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)
|
if (dev)
|
||||||
pci_dev_put(dev->pdev);
|
pci_dev_put(dev->pdev);
|
||||||
drm_cleanup(dev);
|
drm_cleanup(dev);
|
||||||
|
|
|
@ -223,8 +223,10 @@ static int add_established_modes(struct drm_output *output, struct edid *edid)
|
||||||
if (est_bits & (1<<i)) {
|
if (est_bits & (1<<i)) {
|
||||||
struct drm_display_mode *newmode;
|
struct drm_display_mode *newmode;
|
||||||
newmode = drm_mode_duplicate(dev, &edid_est_modes[i]);
|
newmode = drm_mode_duplicate(dev, &edid_est_modes[i]);
|
||||||
drm_mode_probed_add(output, newmode);
|
if (newmode) {
|
||||||
modes++;
|
drm_mode_probed_add(output, newmode);
|
||||||
|
modes++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return modes;
|
return modes;
|
||||||
|
@ -251,8 +253,10 @@ static int add_standard_modes(struct drm_output *output, struct edid *edid)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
newmode = drm_mode_std(dev, &edid->standard_timings[i]);
|
newmode = drm_mode_std(dev, &edid->standard_timings[i]);
|
||||||
drm_mode_probed_add(output, newmode);
|
if (newmode) {
|
||||||
modes++;
|
drm_mode_probed_add(output, newmode);
|
||||||
|
modes++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return modes;
|
return modes;
|
||||||
|
@ -283,11 +287,13 @@ static int add_detailed_info(struct drm_output *output, struct edid *edid)
|
||||||
if (timing->pixel_clock) {
|
if (timing->pixel_clock) {
|
||||||
newmode = drm_mode_detailed(dev, timing);
|
newmode = drm_mode_detailed(dev, timing);
|
||||||
/* First detailed mode is preferred */
|
/* First detailed mode is preferred */
|
||||||
if (i == 0 && edid->preferred_timing)
|
if (newmode) {
|
||||||
newmode->type |= DRM_MODE_TYPE_PREFERRED;
|
if (i == 0 && edid->preferred_timing)
|
||||||
drm_mode_probed_add(output, newmode);
|
newmode->type |= DRM_MODE_TYPE_PREFERRED;
|
||||||
|
drm_mode_probed_add(output, newmode);
|
||||||
|
|
||||||
modes++;
|
modes++;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,8 +318,10 @@ static int add_detailed_info(struct drm_output *output, struct edid *edid)
|
||||||
|
|
||||||
std = &data->data.timings[j];
|
std = &data->data.timings[j];
|
||||||
newmode = drm_mode_std(dev, std);
|
newmode = drm_mode_std(dev, std);
|
||||||
drm_mode_probed_add(output, newmode);
|
if (newmode) {
|
||||||
modes++;
|
drm_mode_probed_add(output, newmode);
|
||||||
|
modes++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -481,7 +481,8 @@ int drm_release(struct inode *inode, struct file *filp)
|
||||||
}
|
}
|
||||||
mutex_unlock(&dev->ctxlist_mutex);
|
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;
|
file_priv->master = NULL;
|
||||||
|
|
||||||
|
|
|
@ -306,6 +306,8 @@ int drm_control(struct drm_device *dev, void *data,
|
||||||
case DRM_INST_HANDLER:
|
case DRM_INST_HANDLER:
|
||||||
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
|
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
|
||||||
return 0;
|
return 0;
|
||||||
|
if (drm_core_check_feature(dev, DRIVER_MODESET))
|
||||||
|
return 0;
|
||||||
if (dev->if_version < DRM_IF_VERSION(1, 2) &&
|
if (dev->if_version < DRM_IF_VERSION(1, 2) &&
|
||||||
ctl->irq != dev->irq)
|
ctl->irq != dev->irq)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -313,6 +315,8 @@ int drm_control(struct drm_device *dev, void *data,
|
||||||
case DRM_UNINST_HANDLER:
|
case DRM_UNINST_HANDLER:
|
||||||
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
|
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
|
||||||
return 0;
|
return 0;
|
||||||
|
if (drm_core_check_feature(dev, DRIVER_MODESET))
|
||||||
|
return 0;
|
||||||
return drm_irq_uninstall(dev);
|
return drm_irq_uninstall(dev);
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -383,7 +383,7 @@ extern int drm_ttm_destroy(struct drm_ttm *ttm);
|
||||||
* The array of page pointers was allocated with vmalloc
|
* The array of page pointers was allocated with vmalloc
|
||||||
* instead of drm_calloc.
|
* 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
|
* 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,
|
uint64_t flags, uint64_t mask, uint32_t hint,
|
||||||
uint32_t fence_class,
|
uint32_t fence_class,
|
||||||
struct drm_bo_info_rep *rep);
|
struct drm_bo_info_rep *rep);
|
||||||
|
extern int drm_bo_evict_cached(struct drm_buffer_object *bo);
|
||||||
/*
|
/*
|
||||||
* Buffer object memory move- and map helpers.
|
* Buffer object memory move- and map helpers.
|
||||||
* drm_bo_move.c
|
* 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 void drm_bo_kunmap(struct drm_bo_kmap_obj *map);
|
||||||
extern int drm_bo_kmap(struct drm_buffer_object *bo, unsigned long start_page,
|
extern int drm_bo_kmap(struct drm_buffer_object *bo, unsigned long start_page,
|
||||||
unsigned long num_pages, struct drm_bo_kmap_obj *map);
|
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);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -36,6 +36,15 @@
|
||||||
|
|
||||||
#define DEBUG_SCATTER 0
|
#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)
|
void drm_sg_cleanup(struct drm_sg_mem *entry)
|
||||||
{
|
{
|
||||||
struct page *page;
|
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));
|
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) {
|
if (!entry->virtual) {
|
||||||
drm_free(entry->busaddr,
|
drm_free(entry->busaddr,
|
||||||
entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES);
|
entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES);
|
||||||
|
|
|
@ -343,8 +343,10 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
|
||||||
goto err_g3;
|
goto err_g3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL)))
|
/* only add the control node on a modesetting platform */
|
||||||
goto err_g3;
|
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)))
|
if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY)))
|
||||||
goto err_g4;
|
goto err_g4;
|
||||||
|
@ -361,7 +363,8 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
|
||||||
err_g5:
|
err_g5:
|
||||||
drm_put_minor(&dev->primary);
|
drm_put_minor(&dev->primary);
|
||||||
err_g4:
|
err_g4:
|
||||||
drm_put_minor(&dev->control);
|
if (drm_core_check_feature(dev, DRIVER_MODESET))
|
||||||
|
drm_put_minor(&dev->control);
|
||||||
err_g3:
|
err_g3:
|
||||||
if (!drm_fb_loaded)
|
if (!drm_fb_loaded)
|
||||||
pci_disable_device(pdev);
|
pci_disable_device(pdev);
|
||||||
|
|
|
@ -42,11 +42,12 @@ void drm_ttm_cache_flush(void)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_ttm_cache_flush);
|
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_page_directory(struct drm_ttm *ttm)
|
||||||
static void drm_ttm_alloc_pages(struct drm_ttm *ttm)
|
|
||||||
{
|
{
|
||||||
unsigned long size = ttm->num_pages * sizeof(*ttm->pages);
|
unsigned long size = ttm->num_pages * sizeof(*ttm->pages);
|
||||||
ttm->pages = NULL;
|
ttm->pages = NULL;
|
||||||
|
@ -60,19 +61,19 @@ static void drm_ttm_alloc_pages(struct drm_ttm *ttm)
|
||||||
if (!ttm->pages) {
|
if (!ttm->pages) {
|
||||||
ttm->pages = vmalloc_user(size);
|
ttm->pages = vmalloc_user(size);
|
||||||
if (ttm->pages)
|
if (ttm->pages)
|
||||||
ttm->page_flags |= DRM_TTM_PAGE_VMALLOC;
|
ttm->page_flags |= DRM_TTM_PAGEDIR_VMALLOC;
|
||||||
}
|
}
|
||||||
if (!ttm->pages)
|
if (!ttm->pages)
|
||||||
drm_free_memctl(size);
|
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);
|
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);
|
vfree(ttm->pages);
|
||||||
ttm->page_flags &= ~DRM_TTM_PAGE_VMALLOC;
|
ttm->page_flags &= ~DRM_TTM_PAGEDIR_VMALLOC;
|
||||||
} else {
|
} else {
|
||||||
drm_free(ttm->pages, size, DRM_MEM_TTM);
|
drm_free(ttm->pages, size, DRM_MEM_TTM);
|
||||||
}
|
}
|
||||||
|
@ -215,7 +216,7 @@ int drm_ttm_destroy(struct drm_ttm *ttm)
|
||||||
else
|
else
|
||||||
drm_ttm_free_alloced_pages(ttm);
|
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);
|
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.
|
* Account also for AGP module memory usage.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
drm_ttm_alloc_pages(ttm);
|
drm_ttm_alloc_page_directory(ttm);
|
||||||
if (!ttm->pages) {
|
if (!ttm->pages) {
|
||||||
drm_ttm_destroy(ttm);
|
drm_ttm_destroy(ttm);
|
||||||
DRM_ERROR("Failed allocating page table\n");
|
DRM_ERROR("Failed allocating page table\n");
|
||||||
|
|
|
@ -59,17 +59,27 @@ pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma)
|
||||||
pgprot_val(tmp) |= _PAGE_NO_CACHE;
|
pgprot_val(tmp) |= _PAGE_NO_CACHE;
|
||||||
if (map_type == _DRM_REGISTERS)
|
if (map_type == _DRM_REGISTERS)
|
||||||
pgprot_val(tmp) |= _PAGE_GUARDED;
|
pgprot_val(tmp) |= _PAGE_GUARDED;
|
||||||
#endif
|
#elif defined(__ia64__)
|
||||||
#if defined(__ia64__)
|
|
||||||
if (efi_range_is_wc(vma->vm_start, vma->vm_end -
|
if (efi_range_is_wc(vma->vm_start, vma->vm_end -
|
||||||
vma->vm_start))
|
vma->vm_start))
|
||||||
tmp = pgprot_writecombine(tmp);
|
tmp = pgprot_writecombine(tmp);
|
||||||
else
|
else
|
||||||
tmp = pgprot_noncached(tmp);
|
tmp = pgprot_noncached(tmp);
|
||||||
|
#elif defined(__sparc__)
|
||||||
|
tmp = pgprot_noncached(tmp);
|
||||||
#endif
|
#endif
|
||||||
return tmp;
|
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.
|
* \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);
|
offset = dev->driver->get_reg_ofs(dev);
|
||||||
vma->vm_flags |= VM_IO; /* not in core dump */
|
vma->vm_flags |= VM_IO; /* not in core dump */
|
||||||
vma->vm_page_prot = drm_io_prot(map->type, vma);
|
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,
|
if (io_remap_pfn_range(vma, vma->vm_start,
|
||||||
(map->offset + offset) >> PAGE_SHIFT,
|
(map->offset + offset) >> PAGE_SHIFT,
|
||||||
vma->vm_end - vma->vm_start,
|
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)),
|
page_to_pfn(virt_to_page(map->handle)),
|
||||||
vma->vm_end - vma->vm_start, vma->vm_page_prot))
|
vma->vm_end - vma->vm_start, vma->vm_page_prot))
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
vma->vm_page_prot = drm_dma_prot(map->type, vma);
|
||||||
/* fall through to _DRM_SHM */
|
/* fall through to _DRM_SHM */
|
||||||
case _DRM_SHM:
|
case _DRM_SHM:
|
||||||
vma->vm_ops = &drm_vm_shm_ops;
|
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_ops = &drm_vm_sg_ops;
|
||||||
vma->vm_private_data = (void *)map;
|
vma->vm_private_data = (void *)map;
|
||||||
vma->vm_flags |= VM_RESERVED;
|
vma->vm_flags |= VM_RESERVED;
|
||||||
|
vma->vm_page_prot = drm_dma_prot(map->type, vma);
|
||||||
break;
|
break;
|
||||||
case _DRM_TTM:
|
case _DRM_TTM:
|
||||||
return drm_bo_mmap_locked(vma, filp, map);
|
return drm_bo_mmap_locked(vma, filp, map);
|
||||||
|
|
|
@ -39,14 +39,17 @@ static struct pci_device_id pciidlist[] = {
|
||||||
i915_PCI_IDS
|
i915_PCI_IDS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
unsigned int i915_modeset = 0;
|
||||||
|
module_param_named(modeset, i915_modeset, int, 0400);
|
||||||
|
|
||||||
#ifdef I915_HAVE_FENCE
|
#ifdef I915_HAVE_FENCE
|
||||||
extern struct drm_fence_driver i915_fence_driver;
|
extern struct drm_fence_driver i915_fence_driver;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef I915_HAVE_BUFFER
|
#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_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_PRIV0, DRM_BO_MEM_VRAM, 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 = {
|
static struct drm_bo_driver i915_bo_driver = {
|
||||||
.mem_type_prio = i915_mem_prios,
|
.mem_type_prio = i915_mem_prios,
|
||||||
|
@ -563,8 +566,9 @@ static struct drm_driver driver = {
|
||||||
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
|
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
|
||||||
.load = i915_driver_load,
|
.load = i915_driver_load,
|
||||||
.unload = i915_driver_unload,
|
.unload = i915_driver_unload,
|
||||||
/* .lastclose = i915_driver_lastclose,
|
.firstopen = i915_driver_firstopen,
|
||||||
.preclose = i915_driver_preclose, */
|
.lastclose = i915_driver_lastclose,
|
||||||
|
.preclose = i915_driver_preclose,
|
||||||
.suspend = i915_suspend,
|
.suspend = i915_suspend,
|
||||||
.resume = i915_resume,
|
.resume = i915_resume,
|
||||||
.device_is_agp = i915_driver_device_is_agp,
|
.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)
|
static int __init i915_init(void)
|
||||||
{
|
{
|
||||||
driver.num_ioctls = i915_max_ioctl;
|
driver.num_ioctls = i915_max_ioctl;
|
||||||
|
if (i915_modeset == 1)
|
||||||
|
driver.driver_features |= DRIVER_MODESET;
|
||||||
|
|
||||||
return drm_init(&driver, pciidlist);
|
return drm_init(&driver, pciidlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -228,6 +228,7 @@ static int intelfb_set_par(struct fb_info *info)
|
||||||
struct drm_output *output = NULL;
|
struct drm_output *output = NULL;
|
||||||
struct fb_var_screeninfo *var = &info->var;
|
struct fb_var_screeninfo *var = &info->var;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
|
int changed = 0;
|
||||||
|
|
||||||
DRM_DEBUG("\n");
|
DRM_DEBUG("\n");
|
||||||
|
|
||||||
|
@ -310,11 +311,22 @@ static int intelfb_set_par(struct fb_info *info)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* re-attach fb */
|
/* re-attach fb */
|
||||||
if (!par->crtc->fb)
|
if (!par->crtc->fb) {
|
||||||
par->crtc->fb = par->fb;
|
par->crtc->fb = par->fb;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!drm_crtc_set_mode(par->crtc, drm_mode, var->xoffset, var->yoffset))
|
if (par->crtc->x != var->xoffset || par->crtc->y != var->yoffset)
|
||||||
return -EINVAL;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -469,16 +481,21 @@ static int intelfb_pan_display(struct fb_var_screeninfo *var,
|
||||||
{
|
{
|
||||||
struct intelfb_par *par = info->par;
|
struct intelfb_par *par = info->par;
|
||||||
struct drm_crtc *crtc = par->crtc;
|
struct drm_crtc *crtc = par->crtc;
|
||||||
|
int changed = 0;
|
||||||
DRM_DEBUG("\n");
|
DRM_DEBUG("\n");
|
||||||
|
|
||||||
/* TODO add check size and pos*/
|
/* TODO add check size and pos*/
|
||||||
|
if (par->crtc->x != var->xoffset || par->crtc->y != var->yoffset)
|
||||||
|
changed = 1;
|
||||||
|
|
||||||
/* re-attach fb */
|
/* re-attach fb */
|
||||||
if (!crtc->fb)
|
if (!crtc->fb) {
|
||||||
crtc->fb = par->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.xoffset = var->xoffset;
|
||||||
info->var.yoffset = var->yoffset;
|
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->bits_per_pixel = 32;
|
||||||
fb->pitch = fb->width * ((fb->bits_per_pixel + 1) / 8);
|
fb->pitch = fb->width * ((fb->bits_per_pixel + 1) / 8);
|
||||||
fb->depth = 24;
|
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_type_kernel,
|
||||||
DRM_BO_FLAG_READ |
|
DRM_BO_FLAG_READ |
|
||||||
DRM_BO_FLAG_WRITE |
|
DRM_BO_FLAG_WRITE |
|
||||||
|
|
|
@ -645,8 +645,14 @@ struct drm_set_version {
|
||||||
|
|
||||||
#define DRM_FENCE_FLAG_EMIT 0x00000001
|
#define DRM_FENCE_FLAG_EMIT 0x00000001
|
||||||
#define DRM_FENCE_FLAG_SHAREABLE 0x00000002
|
#define DRM_FENCE_FLAG_SHAREABLE 0x00000002
|
||||||
|
/**
|
||||||
|
* On hardware with no interrupt events for operation completion,
|
||||||
|
* indicates that the kernel should sleep while waiting for any blocking
|
||||||
|
* operation to complete rather than spinning.
|
||||||
|
*
|
||||||
|
* Has no effect otherwise.
|
||||||
|
*/
|
||||||
#define DRM_FENCE_FLAG_WAIT_LAZY 0x00000004
|
#define DRM_FENCE_FLAG_WAIT_LAZY 0x00000004
|
||||||
#define DRM_FENCE_FLAG_WAIT_IGNORE_SIGNALS 0x00000008
|
|
||||||
#define DRM_FENCE_FLAG_NO_USER 0x00000010
|
#define DRM_FENCE_FLAG_NO_USER 0x00000010
|
||||||
|
|
||||||
/* Reserved for driver use */
|
/* Reserved for driver use */
|
||||||
|
@ -795,13 +801,12 @@ struct drm_fence_arg {
|
||||||
* with it as a result of this operation
|
* with it as a result of this operation
|
||||||
*/
|
*/
|
||||||
#define DRM_BO_HINT_DONT_FENCE 0x00000004
|
#define DRM_BO_HINT_DONT_FENCE 0x00000004
|
||||||
/*
|
/**
|
||||||
* Sleep while waiting for the operation to complete.
|
* On hardware with no interrupt events for operation completion,
|
||||||
* Without this flag, the kernel will, instead, spin
|
* indicates that the kernel should sleep while waiting for any blocking
|
||||||
* until this operation has completed. I'm not sure
|
* operation to complete rather than spinning.
|
||||||
* why you would ever want this, so please always
|
*
|
||||||
* provide DRM_BO_HINT_WAIT_LAZY to any operation
|
* Has no effect otherwise.
|
||||||
* which may block
|
|
||||||
*/
|
*/
|
||||||
#define DRM_BO_HINT_WAIT_LAZY 0x00000008
|
#define DRM_BO_HINT_WAIT_LAZY 0x00000008
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -66,6 +66,11 @@ void i915_kernel_lost_context(struct drm_device * dev)
|
||||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
struct drm_i915_ring_buffer *ring = &(dev_priv->ring);
|
struct drm_i915_ring_buffer *ring = &(dev_priv->ring);
|
||||||
|
|
||||||
|
/* we should never lose context on the ring with modesetting
|
||||||
|
* as we don't expose it to userspace */
|
||||||
|
if (drm_core_check_feature(dev, DRIVER_MODESET))
|
||||||
|
return;
|
||||||
|
|
||||||
ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
|
ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
|
||||||
ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
|
ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
|
||||||
ring->space = ring->head - (ring->tail + 8);
|
ring->space = ring->head - (ring->tail + 8);
|
||||||
|
@ -75,6 +80,11 @@ void i915_kernel_lost_context(struct drm_device * dev)
|
||||||
|
|
||||||
int i915_dma_cleanup(struct drm_device * dev)
|
int i915_dma_cleanup(struct drm_device * dev)
|
||||||
{
|
{
|
||||||
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
|
|
||||||
|
if (drm_core_check_feature(dev, DRIVER_MODESET))
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* Make sure interrupts are disabled here because the uninstall ioctl
|
/* Make sure interrupts are disabled here because the uninstall ioctl
|
||||||
* may not have been called from userspace and after dev_private
|
* may not have been called from userspace and after dev_private
|
||||||
* is freed, it's too late.
|
* is freed, it's too late.
|
||||||
|
@ -82,6 +92,28 @@ int i915_dma_cleanup(struct drm_device * dev)
|
||||||
if (dev->irq)
|
if (dev->irq)
|
||||||
drm_irq_uninstall(dev);
|
drm_irq_uninstall(dev);
|
||||||
|
|
||||||
|
if (dev_priv->ring.virtual_start) {
|
||||||
|
drm_core_ioremapfree(&dev_priv->ring.map, dev);
|
||||||
|
dev_priv->ring.virtual_start = 0;
|
||||||
|
dev_priv->ring.map.handle = 0;
|
||||||
|
dev_priv->ring.map.size = 0;
|
||||||
|
dev_priv->ring.Size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev_priv->status_page_dmah) {
|
||||||
|
drm_pci_free(dev, dev_priv->status_page_dmah);
|
||||||
|
dev_priv->status_page_dmah = NULL;
|
||||||
|
/* Need to rewrite hardware status page */
|
||||||
|
I915_WRITE(0x02080, 0x1ffff000);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev_priv->status_gfx_addr) {
|
||||||
|
dev_priv->status_gfx_addr = 0;
|
||||||
|
drm_core_ioremapfree(&dev_priv->hws_map, dev);
|
||||||
|
I915_WRITE(0x02080, 0x1ffff000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,13 +185,17 @@ static int i915_initialize(struct drm_device * dev,
|
||||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
|
struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
|
||||||
|
|
||||||
dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
|
if (!drm_core_check_feature(dev, DRIVER_MODESET)) {
|
||||||
if (!dev_priv->mmio_map) {
|
if (init->mmio_offset != 0)
|
||||||
i915_dma_cleanup(dev);
|
dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
|
||||||
DRM_ERROR("can not find mmio map!\n");
|
if (!dev_priv->mmio_map) {
|
||||||
return -EINVAL;
|
i915_dma_cleanup(dev);
|
||||||
|
DRM_ERROR("can not find mmio map!\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef I915_HAVE_BUFFER
|
#ifdef I915_HAVE_BUFFER
|
||||||
dev_priv->max_validate_buffers = I915_MAX_VALIDATE_BUFFERS;
|
dev_priv->max_validate_buffers = I915_MAX_VALIDATE_BUFFERS;
|
||||||
#endif
|
#endif
|
||||||
|
@ -246,6 +282,9 @@ static int i915_dma_resume(struct drm_device * dev)
|
||||||
|
|
||||||
DRM_DEBUG("\n");
|
DRM_DEBUG("\n");
|
||||||
|
|
||||||
|
if (drm_core_check_feature(dev, DRIVER_MODESET))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!dev_priv->mmio_map) {
|
if (!dev_priv->mmio_map) {
|
||||||
DRM_ERROR("can not find mmio map!\n");
|
DRM_ERROR("can not find mmio map!\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -765,6 +804,8 @@ struct i915_relocatee_info {
|
||||||
unsigned page_offset;
|
unsigned page_offset;
|
||||||
struct drm_bo_kmap_obj kmap;
|
struct drm_bo_kmap_obj kmap;
|
||||||
int is_iomem;
|
int is_iomem;
|
||||||
|
int idle;
|
||||||
|
int evicted;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct drm_i915_validate_buffer {
|
struct drm_i915_validate_buffer {
|
||||||
|
@ -820,6 +861,14 @@ int i915_apply_reloc(struct drm_file *file_priv, int num_buffers,
|
||||||
drm_bo_kunmap(&relocatee->kmap);
|
drm_bo_kunmap(&relocatee->kmap);
|
||||||
relocatee->data_page = NULL;
|
relocatee->data_page = NULL;
|
||||||
relocatee->offset = new_cmd_offset;
|
relocatee->offset = new_cmd_offset;
|
||||||
|
|
||||||
|
if (unlikely(!relocatee->idle)) {
|
||||||
|
ret = drm_bo_wait(relocatee->buf, 0, 0, 0);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
relocatee->idle = 1;
|
||||||
|
}
|
||||||
|
|
||||||
ret = drm_bo_kmap(relocatee->buf, new_cmd_offset >> PAGE_SHIFT,
|
ret = drm_bo_kmap(relocatee->buf, new_cmd_offset >> PAGE_SHIFT,
|
||||||
1, &relocatee->kmap);
|
1, &relocatee->kmap);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -829,6 +878,12 @@ int i915_apply_reloc(struct drm_file *file_priv, int num_buffers,
|
||||||
relocatee->data_page = drm_bmo_virtual(&relocatee->kmap,
|
relocatee->data_page = drm_bmo_virtual(&relocatee->kmap,
|
||||||
&relocatee->is_iomem);
|
&relocatee->is_iomem);
|
||||||
relocatee->page_offset = (relocatee->offset & PAGE_MASK);
|
relocatee->page_offset = (relocatee->offset & PAGE_MASK);
|
||||||
|
|
||||||
|
if (!relocatee->evicted &&
|
||||||
|
relocatee->buf->mem.flags & DRM_BO_FLAG_CACHED_MAPPED) {
|
||||||
|
drm_bo_evict_cached(relocatee->buf);
|
||||||
|
relocatee->evicted = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val = buffers[buf_index].buffer->offset;
|
val = buffers[buf_index].buffer->offset;
|
||||||
|
@ -963,10 +1018,6 @@ static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle,
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock (&relocatee.buf->mutex);
|
mutex_lock (&relocatee.buf->mutex);
|
||||||
ret = drm_bo_wait (relocatee.buf, 0, 0, FALSE);
|
|
||||||
if (ret)
|
|
||||||
goto out_err1;
|
|
||||||
|
|
||||||
while (reloc_user_ptr) {
|
while (reloc_user_ptr) {
|
||||||
ret = i915_process_relocs(file_priv, buf_handle, &reloc_user_ptr, &relocatee, buffers, buf_count);
|
ret = i915_process_relocs(file_priv, buf_handle, &reloc_user_ptr, &relocatee, buffers, buf_count);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -1430,6 +1481,16 @@ drm_i915_mmio_entry_t mmio_table[] = {
|
||||||
I915_MMIO_MAY_READ|I915_MMIO_MAY_WRITE,
|
I915_MMIO_MAY_READ|I915_MMIO_MAY_WRITE,
|
||||||
0x30010,
|
0x30010,
|
||||||
6
|
6
|
||||||
|
},
|
||||||
|
[MMIO_REGS_FENCE] = {
|
||||||
|
I915_MMIO_MAY_READ|I915_MMIO_MAY_WRITE,
|
||||||
|
0x2000,
|
||||||
|
8
|
||||||
|
},
|
||||||
|
[MMIO_REGS_FENCE_NEW] = {
|
||||||
|
I915_MMIO_MAY_READ|I915_MMIO_MAY_WRITE,
|
||||||
|
0x3000,
|
||||||
|
16
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -328,6 +328,8 @@ typedef struct drm_i915_vblank_swap {
|
||||||
#define MMIO_REGS_PS_DEPTH_COUNT 8
|
#define MMIO_REGS_PS_DEPTH_COUNT 8
|
||||||
#define MMIO_REGS_DOVSTA 9
|
#define MMIO_REGS_DOVSTA 9
|
||||||
#define MMIO_REGS_GAMMA 10
|
#define MMIO_REGS_GAMMA 10
|
||||||
|
#define MMIO_REGS_FENCE 11
|
||||||
|
#define MMIO_REGS_FENCE_NEW 12
|
||||||
|
|
||||||
typedef struct drm_i915_mmio_entry {
|
typedef struct drm_i915_mmio_entry {
|
||||||
unsigned int flag;
|
unsigned int flag;
|
||||||
|
|
|
@ -153,105 +153,112 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
|
||||||
DRM_DEBUG("fb_base: 0x%08lx\n", dev->mode_config.fb_base);
|
DRM_DEBUG("fb_base: 0x%08lx\n", dev->mode_config.fb_base);
|
||||||
|
|
||||||
ret = drm_addmap(dev, dev_priv->mmiobase, dev_priv->mmiolen,
|
ret = drm_addmap(dev, dev_priv->mmiobase, dev_priv->mmiolen,
|
||||||
_DRM_REGISTERS, _DRM_READ_ONLY|_DRM_DRIVER, &dev_priv->mmio_map);
|
_DRM_REGISTERS, _DRM_KERNEL|_DRM_READ_ONLY|_DRM_DRIVER, &dev_priv->mmio_map);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
DRM_ERROR("Cannot add mapping for MMIO registers\n");
|
DRM_ERROR("Cannot add mapping for MMIO registers\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
|
||||||
|
intel_init_chipset_flush_compat(dev);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the memory manager for local and AGP space
|
* Initialize the memory manager for local and AGP space
|
||||||
*/
|
*/
|
||||||
drm_bo_driver_init(dev);
|
drm_bo_driver_init(dev);
|
||||||
|
|
||||||
i915_probe_agp(dev->pdev, &agp_size, &prealloc_size);
|
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
|
||||||
printk("setting up %ld bytes of VRAM space\n", prealloc_size);
|
i915_probe_agp(dev->pdev, &agp_size, &prealloc_size);
|
||||||
printk("setting up %ld bytes of TT space\n", (agp_size - prealloc_size));
|
printk("setting up %ld bytes of VRAM space\n", prealloc_size);
|
||||||
drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, prealloc_size >> PAGE_SHIFT, 1);
|
printk("setting up %ld bytes of TT space\n", (agp_size - prealloc_size));
|
||||||
drm_bo_init_mm(dev, DRM_BO_MEM_TT, prealloc_size >> PAGE_SHIFT, (agp_size - prealloc_size) >> PAGE_SHIFT, 1);
|
drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, prealloc_size >> PAGE_SHIFT, 1);
|
||||||
|
drm_bo_init_mm(dev, DRM_BO_MEM_TT, prealloc_size >> PAGE_SHIFT, (agp_size - prealloc_size) >> PAGE_SHIFT, 1);
|
||||||
|
|
||||||
I915_WRITE(LP_RING + RING_LEN, 0);
|
I915_WRITE(LP_RING + RING_LEN, 0);
|
||||||
I915_WRITE(LP_RING + RING_HEAD, 0);
|
I915_WRITE(LP_RING + RING_HEAD, 0);
|
||||||
I915_WRITE(LP_RING + RING_TAIL, 0);
|
I915_WRITE(LP_RING + RING_TAIL, 0);
|
||||||
|
|
||||||
size = PRIMARY_RINGBUFFER_SIZE;
|
size = PRIMARY_RINGBUFFER_SIZE;
|
||||||
ret = drm_buffer_object_create(dev, size, drm_bo_type_kernel,
|
ret = drm_buffer_object_create(dev, size, drm_bo_type_kernel,
|
||||||
DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE |
|
DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE |
|
||||||
DRM_BO_FLAG_MEM_VRAM |
|
DRM_BO_FLAG_MEM_VRAM |
|
||||||
DRM_BO_FLAG_NO_EVICT,
|
DRM_BO_FLAG_NO_EVICT,
|
||||||
DRM_BO_HINT_DONT_FENCE, 0x1, 0,
|
DRM_BO_HINT_DONT_FENCE, 0x1, 0,
|
||||||
&dev_priv->ring_buffer);
|
&dev_priv->ring_buffer);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
DRM_ERROR("Unable to allocate or pin ring buffer\n");
|
DRM_ERROR("Unable to allocate or pin ring buffer\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remap the buffer object properly */
|
/* remap the buffer object properly */
|
||||||
dev_priv->ring.Start = dev_priv->ring_buffer->offset;
|
dev_priv->ring.Start = dev_priv->ring_buffer->offset;
|
||||||
dev_priv->ring.End = dev_priv->ring.Start + size;
|
dev_priv->ring.End = dev_priv->ring.Start + size;
|
||||||
dev_priv->ring.Size = size;
|
dev_priv->ring.Size = size;
|
||||||
dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
|
dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
|
||||||
|
|
||||||
/* FIXME: need wrapper with PCI mem checks */
|
/* FIXME: need wrapper with PCI mem checks */
|
||||||
ret = drm_mem_reg_ioremap(dev, &dev_priv->ring_buffer->mem,
|
ret = drm_mem_reg_ioremap(dev, &dev_priv->ring_buffer->mem,
|
||||||
(void **) &dev_priv->ring.virtual_start);
|
(void **) &dev_priv->ring.virtual_start);
|
||||||
if (ret)
|
if (ret)
|
||||||
DRM_ERROR("error mapping ring buffer: %d\n", ret);
|
DRM_ERROR("error mapping ring buffer: %d\n", ret);
|
||||||
|
|
||||||
DRM_DEBUG("ring start %08lX, %p, %08lX\n", dev_priv->ring.Start,
|
DRM_DEBUG("ring start %08lX, %p, %08lX\n", dev_priv->ring.Start,
|
||||||
dev_priv->ring.virtual_start, dev_priv->ring.Size);
|
dev_priv->ring.virtual_start, dev_priv->ring.Size);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
memset((void *)(dev_priv->ring.virtual_start), 0, dev_priv->ring.Size);
|
memset((void *)(dev_priv->ring.virtual_start), 0, dev_priv->ring.Size);
|
||||||
|
|
||||||
I915_WRITE(LP_RING + RING_START, dev_priv->ring.Start);
|
I915_WRITE(LP_RING + RING_START, dev_priv->ring.Start);
|
||||||
I915_WRITE(LP_RING + RING_LEN,
|
I915_WRITE(LP_RING + RING_LEN,
|
||||||
((dev_priv->ring.Size - 4096) & RING_NR_PAGES) |
|
((dev_priv->ring.Size - 4096) & RING_NR_PAGES) |
|
||||||
(RING_NO_REPORT | RING_VALID));
|
(RING_NO_REPORT | RING_VALID));
|
||||||
|
|
||||||
/* We are using separate values as placeholders for mechanisms for
|
/* We are using separate values as placeholders for mechanisms for
|
||||||
* private backbuffer/depthbuffer usage.
|
* private backbuffer/depthbuffer usage.
|
||||||
*/
|
*/
|
||||||
dev_priv->use_mi_batchbuffer_start = 0;
|
dev_priv->use_mi_batchbuffer_start = 0;
|
||||||
|
|
||||||
/* Allow hardware batchbuffers unless told otherwise.
|
/* Allow hardware batchbuffers unless told otherwise.
|
||||||
*/
|
*/
|
||||||
dev_priv->allow_batchbuffer = 1;
|
dev_priv->allow_batchbuffer = 1;
|
||||||
|
|
||||||
/* Program Hardware Status Page */
|
/* Program Hardware Status Page */
|
||||||
if (!IS_G33(dev)) {
|
if (!IS_G33(dev)) {
|
||||||
dev_priv->status_page_dmah =
|
dev_priv->status_page_dmah =
|
||||||
drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
|
drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
|
||||||
|
|
||||||
if (!dev_priv->status_page_dmah) {
|
if (!dev_priv->status_page_dmah) {
|
||||||
dev->dev_private = (void *)dev_priv;
|
dev->dev_private = (void *)dev_priv;
|
||||||
i915_dma_cleanup(dev);
|
i915_dma_cleanup(dev);
|
||||||
DRM_ERROR("Can not allocate hardware status page\n");
|
DRM_ERROR("Can not allocate hardware status page\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
|
||||||
|
dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
|
||||||
|
|
||||||
|
memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
|
||||||
|
|
||||||
|
I915_WRITE(I915REG_HWS_PGA, dev_priv->dma_status_page);
|
||||||
}
|
}
|
||||||
dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
|
DRM_DEBUG("Enabled hardware status page\n");
|
||||||
dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
|
|
||||||
|
|
||||||
memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
|
dev_priv->wq = create_singlethread_workqueue("i915");
|
||||||
|
if (dev_priv == 0) {
|
||||||
|
DRM_DEBUG("Error\n");
|
||||||
|
}
|
||||||
|
|
||||||
I915_WRITE(I915REG_HWS_PGA, dev_priv->dma_status_page);
|
intel_modeset_init(dev);
|
||||||
|
drm_initial_config(dev, false);
|
||||||
|
|
||||||
|
drm_mm_print(&dev->bm.man[DRM_BO_MEM_VRAM].manager, "VRAM");
|
||||||
|
drm_mm_print(&dev->bm.man[DRM_BO_MEM_TT].manager, "TT");
|
||||||
|
|
||||||
|
drm_irq_install(dev);
|
||||||
}
|
}
|
||||||
DRM_DEBUG("Enabled hardware status page\n");
|
|
||||||
|
|
||||||
dev_priv->wq = create_singlethread_workqueue("i915");
|
|
||||||
if (dev_priv == 0) {
|
|
||||||
DRM_DEBUG("Error\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
intel_modeset_init(dev);
|
|
||||||
drm_initial_config(dev, false);
|
|
||||||
|
|
||||||
drm_mm_print(&dev->bm.man[DRM_BO_MEM_VRAM].manager, "VRAM");
|
|
||||||
drm_mm_print(&dev->bm.man[DRM_BO_MEM_TT].manager, "TT");
|
|
||||||
|
|
||||||
drm_irq_install(dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -262,7 +269,11 @@ int i915_driver_unload(struct drm_device *dev)
|
||||||
|
|
||||||
I915_WRITE(LP_RING + RING_LEN, 0);
|
I915_WRITE(LP_RING + RING_LEN, 0);
|
||||||
|
|
||||||
intel_modeset_cleanup(dev);
|
|
||||||
|
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
|
||||||
|
drm_irq_uninstall(dev);
|
||||||
|
intel_modeset_cleanup(dev);
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (dev_priv->ring.virtual_start) {
|
if (dev_priv->ring.virtual_start) {
|
||||||
|
@ -298,25 +309,33 @@ int i915_driver_unload(struct drm_device *dev)
|
||||||
I915_WRITE(I915REG_HWS_PGA, 0x1ffff000);
|
I915_WRITE(I915REG_HWS_PGA, 0x1ffff000);
|
||||||
}
|
}
|
||||||
|
|
||||||
drm_mem_reg_iounmap(dev, &dev_priv->ring_buffer->mem,
|
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
|
||||||
dev_priv->ring.virtual_start);
|
drm_mem_reg_iounmap(dev, &dev_priv->ring_buffer->mem,
|
||||||
|
dev_priv->ring.virtual_start);
|
||||||
|
|
||||||
DRM_DEBUG("usage is %d\n", atomic_read(&dev_priv->ring_buffer->usage));
|
DRM_DEBUG("usage is %d\n", atomic_read(&dev_priv->ring_buffer->usage));
|
||||||
mutex_lock(&dev->struct_mutex);
|
mutex_lock(&dev->struct_mutex);
|
||||||
drm_bo_usage_deref_locked(&dev_priv->ring_buffer);
|
drm_bo_usage_deref_locked(&dev_priv->ring_buffer);
|
||||||
|
|
||||||
if (drm_bo_clean_mm(dev, DRM_BO_MEM_TT, 1)) {
|
if (drm_bo_clean_mm(dev, DRM_BO_MEM_TT, 1)) {
|
||||||
DRM_ERROR("Memory manager type 3 not clean. "
|
DRM_ERROR("Memory manager type 3 not clean. "
|
||||||
"Delaying takedown\n");
|
"Delaying takedown\n");
|
||||||
|
}
|
||||||
|
if (drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM, 1)) {
|
||||||
|
DRM_ERROR("Memory manager type 3 not clean. "
|
||||||
|
"Delaying takedown\n");
|
||||||
|
}
|
||||||
|
mutex_unlock(&dev->struct_mutex);
|
||||||
}
|
}
|
||||||
if (drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM, 1)) {
|
|
||||||
DRM_ERROR("Memory manager type 3 not clean. "
|
|
||||||
"Delaying takedown\n");
|
|
||||||
}
|
|
||||||
mutex_unlock(&dev->struct_mutex);
|
|
||||||
|
|
||||||
drm_bo_driver_finish(dev);
|
drm_bo_driver_finish(dev);
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
|
||||||
|
intel_init_chipset_flush_compat(dev);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
DRM_DEBUG("%p\n", dev_priv->mmio_map);
|
DRM_DEBUG("%p\n", dev_priv->mmio_map);
|
||||||
drm_rmmap(dev, dev_priv->mmio_map);
|
drm_rmmap(dev, dev_priv->mmio_map);
|
||||||
|
|
||||||
|
@ -363,3 +382,32 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master)
|
||||||
|
|
||||||
master->driver_priv = NULL;
|
master->driver_priv = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
|
if (drm_core_check_feature(dev, DRIVER_MODESET))
|
||||||
|
i915_mem_release(dev, file_priv, dev_priv->agp_heap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void i915_driver_lastclose(struct drm_device * dev)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
|
|
||||||
|
if (drm_core_check_feature(dev, DRIVER_MODESET))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (dev_priv->agp_heap)
|
||||||
|
i915_mem_takedown(&(dev_priv->agp_heap));
|
||||||
|
|
||||||
|
i915_dma_cleanup(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
int i915_driver_firstopen(struct drm_device *dev)
|
||||||
|
{
|
||||||
|
if (drm_core_check_feature(dev, DRIVER_MODESET))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
drm_bo_driver_init(dev);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -415,6 +415,13 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
|
||||||
if (i915_in_vblank(dev, pipe))
|
if (i915_in_vblank(dev, pipe))
|
||||||
count++;
|
count++;
|
||||||
#endif
|
#endif
|
||||||
|
/* count may be reset by other driver(e.g. 2D driver),
|
||||||
|
we have no way to know if it is wrapped or resetted
|
||||||
|
when count is zero. do a rough guess.
|
||||||
|
*/
|
||||||
|
if (count == 0 && dev->last_vblank[pipe] < dev->max_vblank_count/2)
|
||||||
|
dev->last_vblank[pipe] = 0;
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -291,7 +291,7 @@ int testFrameBufferAdd(int fd, drmModeResPtr res)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
printf("\tAdding FB\n");
|
printf("\tAdding FB\n");
|
||||||
ret = drmModeAddFB(fd, 800, 600, 32, 8, 0, &bo, &fb);
|
ret = drmModeAddFB(fd, 800, 600, 32, 8, 0, bo->handle, &fb);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_bo;
|
goto err_bo;
|
||||||
|
|
||||||
|
|
|
@ -429,7 +429,7 @@ void demoUpdateRes(struct demo_driver *driver)
|
||||||
int demoFindConnectedOutputs(struct demo_driver *driver, drmModeOutputPtr *out, size_t max_out)
|
int demoFindConnectedOutputs(struct demo_driver *driver, drmModeOutputPtr *out, size_t max_out)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int i;
|
int i,j;
|
||||||
int fd = driver->fd;
|
int fd = driver->fd;
|
||||||
drmModeResPtr res = driver->res;
|
drmModeResPtr res = driver->res;
|
||||||
|
|
||||||
|
@ -441,11 +441,21 @@ int demoFindConnectedOutputs(struct demo_driver *driver, drmModeOutputPtr *out,
|
||||||
if (!output)
|
if (!output)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (output->connection != DRM_MODE_CONNECTED) {
|
if (output->connection == DRM_MODE_DISCONNECTED) {
|
||||||
drmModeFreeOutput(output);
|
drmModeFreeOutput(output);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < output->count_props; j++) {
|
||||||
|
drmModePropertyPtr prop;
|
||||||
|
|
||||||
|
prop = drmModeGetProperty(fd, output->props[j]);
|
||||||
|
|
||||||
|
printf("Property: %s\n",prop->name);
|
||||||
|
if (prop->count_enums)
|
||||||
|
printf("%s\n",prop->enums[output->prop_values[j]].name);
|
||||||
|
}
|
||||||
|
|
||||||
out[count++] = output;
|
out[count++] = output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,7 +493,7 @@ drmModeFBPtr createFB(int fd, drmModeResPtr res)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = drmModeAddFB(fd, SIZE_X, SIZE_Y, 32, 32, PITCH * 4, &bo, &fb);
|
ret = drmModeAddFB(fd, SIZE_X, SIZE_Y, 32, 32, PITCH * 4, bo.handle, &fb);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_bo;
|
goto err_bo;
|
||||||
|
|
Loading…
Reference in New Issue