Skip to content

Commit

Permalink
Merge branch 'drm-patches' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/git/airlied/drm-2.6

* 'drm-patches' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6:
  drm/sis: add pciid for SiS 662/671 chipset
  drm: add new rv380 pciid
  drm: add support for passing state into the suspend hooks.
  drm/i915: Fix hibernate save/restore of VGA attribute regs
  drm/i915 more registers for S3 (DSPCLK_GATE_D, CACHE_MODE_0, MI_ARB_STATE)
  drm/i915: restore pipeconf regs unconditionally
  drm/i915: save/restore interrupt state
  drm: convert drm from nopage to fault.
  i915: wrap chipset types requiring hw status set ioctl
  drm/radeon: add initial rs690 support to drm.
  • Loading branch information
Linus Torvalds committed Feb 20, 2008
2 parents cf8c0d1 + feac7af commit 3a93dc4
Show file tree
Hide file tree
Showing 9 changed files with 240 additions and 84 deletions.
2 changes: 1 addition & 1 deletion drivers/char/drm/drmP.h
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ struct drm_driver {
void (*postclose) (struct drm_device *, struct drm_file *);
void (*lastclose) (struct drm_device *);
int (*unload) (struct drm_device *);
int (*suspend) (struct drm_device *);
int (*suspend) (struct drm_device *, pm_message_t state);
int (*resume) (struct drm_device *);
int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv);
void (*dma_ready) (struct drm_device *);
Expand Down
3 changes: 3 additions & 0 deletions drivers/char/drm/drm_pciids.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
{0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
{0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
{0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
{0x1002, 0x5657, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
{0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
Expand Down Expand Up @@ -236,6 +237,7 @@
{0x1002, 0x7297, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV560|RADEON_NEW_MEMMAP}, \
{0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP}, \
{0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x791e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
{0, 0, 0}

#define r128_PCI_IDS \
Expand Down Expand Up @@ -313,6 +315,7 @@
{0x1039, 0x5300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1039, 0x6300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1039, 0x6330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
{0x1039, 0x6351, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x18CA, 0x0040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
{0x18CA, 0x0042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
Expand Down
2 changes: 1 addition & 1 deletion drivers/char/drm/drm_sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state)
printk(KERN_ERR "%s\n", __FUNCTION__);

if (drm_dev->driver->suspend)
return drm_dev->driver->suspend(drm_dev);
return drm_dev->driver->suspend(drm_dev, state);

return 0;
}
Expand Down
125 changes: 55 additions & 70 deletions drivers/char/drm/drm_vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma)
}

/**
* \c nopage method for AGP virtual memory.
* \c fault method for AGP virtual memory.
*
* \param vma virtual memory area.
* \param address access address.
Expand All @@ -76,8 +76,7 @@ static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma)
* map, get the page, increment the use count and return it.
*/
#if __OS_HAS_AGP
static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
unsigned long address)
static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct drm_file *priv = vma->vm_file->private_data;
struct drm_device *dev = priv->head->dev;
Expand All @@ -89,19 +88,24 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
* Find the right map
*/
if (!drm_core_has_AGP(dev))
goto vm_nopage_error;
goto vm_fault_error;

if (!dev->agp || !dev->agp->cant_use_aperture)
goto vm_nopage_error;
goto vm_fault_error;

if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash))
goto vm_nopage_error;
goto vm_fault_error;

r_list = drm_hash_entry(hash, struct drm_map_list, hash);
map = r_list->map;

if (map && map->type == _DRM_AGP) {
unsigned long offset = address - vma->vm_start;
/*
* Using vm_pgoff as a selector forces us to use this unusual
* addressing scheme.
*/
unsigned long offset = (unsigned long)vmf->virtual_address -
vma->vm_start;
unsigned long baddr = map->offset + offset;
struct drm_agp_mem *agpmem;
struct page *page;
Expand All @@ -123,30 +127,29 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
}

if (!agpmem)
goto vm_nopage_error;
goto vm_fault_error;

/*
* Get the page, inc the use count, and return it
*/
offset = (baddr - agpmem->bound) >> PAGE_SHIFT;
page = virt_to_page(__va(agpmem->memory->memory[offset]));
get_page(page);
vmf->page = page;

DRM_DEBUG
("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n",
baddr, __va(agpmem->memory->memory[offset]), offset,
page_count(page));

return page;
return 0;
}
vm_nopage_error:
return NOPAGE_SIGBUS; /* Disallow mremap */
vm_fault_error:
return VM_FAULT_SIGBUS; /* Disallow mremap */
}
#else /* __OS_HAS_AGP */
static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
unsigned long address)
static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
return NOPAGE_SIGBUS;
return VM_FAULT_SIGBUS;
}
#endif /* __OS_HAS_AGP */

Expand All @@ -160,28 +163,26 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
* Get the mapping, find the real physical page to map, get the page, and
* return it.
*/
static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma,
unsigned long address)
static int drm_do_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct drm_map *map = (struct drm_map *) vma->vm_private_data;
unsigned long offset;
unsigned long i;
struct page *page;

if (address > vma->vm_end)
return NOPAGE_SIGBUS; /* Disallow mremap */
if (!map)
return NOPAGE_SIGBUS; /* Nothing allocated */
return VM_FAULT_SIGBUS; /* Nothing allocated */

offset = address - vma->vm_start;
offset = (unsigned long)vmf->virtual_address - vma->vm_start;
i = (unsigned long)map->handle + offset;
page = vmalloc_to_page((void *)i);
if (!page)
return NOPAGE_SIGBUS;
return VM_FAULT_SIGBUS;
get_page(page);
vmf->page = page;

DRM_DEBUG("0x%lx\n", address);
return page;
DRM_DEBUG("shm_fault 0x%lx\n", offset);
return 0;
}

/**
Expand Down Expand Up @@ -263,16 +264,15 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
}

/**
* \c nopage method for DMA virtual memory.
* \c fault method for DMA virtual memory.
*
* \param vma virtual memory area.
* \param address access address.
* \return pointer to the page structure.
*
* Determine the page number from the page offset and get it from drm_device_dma::pagelist.
*/
static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
unsigned long address)
static int drm_do_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct drm_file *priv = vma->vm_file->private_data;
struct drm_device *dev = priv->head->dev;
Expand All @@ -282,33 +282,31 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
struct page *page;

if (!dma)
return NOPAGE_SIGBUS; /* Error */
if (address > vma->vm_end)
return NOPAGE_SIGBUS; /* Disallow mremap */
return VM_FAULT_SIGBUS; /* Error */
if (!dma->pagelist)
return NOPAGE_SIGBUS; /* Nothing allocated */
return VM_FAULT_SIGBUS; /* Nothing allocated */

offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
page_nr = offset >> PAGE_SHIFT;
offset = (unsigned long)vmf->virtual_address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
page_nr = offset >> PAGE_SHIFT; /* page_nr could just be vmf->pgoff */
page = virt_to_page((dma->pagelist[page_nr] + (offset & (~PAGE_MASK))));

get_page(page);
vmf->page = page;

DRM_DEBUG("0x%lx (page %lu)\n", address, page_nr);
return page;
DRM_DEBUG("dma_fault 0x%lx (page %lu)\n", offset, page_nr);
return 0;
}

/**
* \c nopage method for scatter-gather virtual memory.
* \c fault method for scatter-gather virtual memory.
*
* \param vma virtual memory area.
* \param address access address.
* \return pointer to the page structure.
*
* Determine the map offset from the page offset and get it from drm_sg_mem::pagelist.
*/
static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
unsigned long address)
static int drm_do_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct drm_map *map = (struct drm_map *) vma->vm_private_data;
struct drm_file *priv = vma->vm_file->private_data;
Expand All @@ -320,77 +318,64 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
struct page *page;

if (!entry)
return NOPAGE_SIGBUS; /* Error */
if (address > vma->vm_end)
return NOPAGE_SIGBUS; /* Disallow mremap */
return VM_FAULT_SIGBUS; /* Error */
if (!entry->pagelist)
return NOPAGE_SIGBUS; /* Nothing allocated */
return VM_FAULT_SIGBUS; /* Nothing allocated */

offset = address - vma->vm_start;
offset = (unsigned long)vmf->virtual_address - vma->vm_start;
map_offset = map->offset - (unsigned long)dev->sg->virtual;
page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
page = entry->pagelist[page_offset];
get_page(page);
vmf->page = page;

return page;
return 0;
}

static struct page *drm_vm_nopage(struct vm_area_struct *vma,
unsigned long address, int *type)
static int drm_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
if (type)
*type = VM_FAULT_MINOR;
return drm_do_vm_nopage(vma, address);
return drm_do_vm_fault(vma, vmf);
}

static struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
unsigned long address, int *type)
static int drm_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
if (type)
*type = VM_FAULT_MINOR;
return drm_do_vm_shm_nopage(vma, address);
return drm_do_vm_shm_fault(vma, vmf);
}

static struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
unsigned long address, int *type)
static int drm_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
if (type)
*type = VM_FAULT_MINOR;
return drm_do_vm_dma_nopage(vma, address);
return drm_do_vm_dma_fault(vma, vmf);
}

static struct page *drm_vm_sg_nopage(struct vm_area_struct *vma,
unsigned long address, int *type)
static int drm_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
if (type)
*type = VM_FAULT_MINOR;
return drm_do_vm_sg_nopage(vma, address);
return drm_do_vm_sg_fault(vma, vmf);
}

/** AGP virtual memory operations */
static struct vm_operations_struct drm_vm_ops = {
.nopage = drm_vm_nopage,
.fault = drm_vm_fault,
.open = drm_vm_open,
.close = drm_vm_close,
};

/** Shared virtual memory operations */
static struct vm_operations_struct drm_vm_shm_ops = {
.nopage = drm_vm_shm_nopage,
.fault = drm_vm_shm_fault,
.open = drm_vm_open,
.close = drm_vm_shm_close,
};

/** DMA virtual memory operations */
static struct vm_operations_struct drm_vm_dma_ops = {
.nopage = drm_vm_dma_nopage,
.fault = drm_vm_dma_fault,
.open = drm_vm_open,
.close = drm_vm_close,
};

/** Scatter-gather virtual memory operations */
static struct vm_operations_struct drm_vm_sg_ops = {
.nopage = drm_vm_sg_nopage,
.fault = drm_vm_sg_fault,
.open = drm_vm_open,
.close = drm_vm_close,
};
Expand Down Expand Up @@ -604,7 +589,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
/*
* On some platforms we can't talk to bus dma address from the CPU, so for
* memory of type DRM_AGP, we'll deal with sorting out the real physical
* pages and mappings in nopage()
* pages and mappings in fault()
*/
#if defined(__powerpc__)
pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
Expand Down Expand Up @@ -634,7 +619,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
break;
case _DRM_CONSISTENT:
/* Consistent memory is really like shared memory. But
* it's allocated in a different way, so avoid nopage */
* it's allocated in a different way, so avoid fault */
if (remap_pfn_range(vma, vma->vm_start,
page_to_pfn(virt_to_page(map->handle)),
vma->vm_end - vma->vm_start, vma->vm_page_prot))
Expand Down
5 changes: 4 additions & 1 deletion drivers/char/drm/i915_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
dev_priv->allow_batchbuffer = 1;

/* Program Hardware Status Page */
if (!IS_G33(dev)) {
if (!I915_NEED_GFX_HWS(dev)) {
dev_priv->status_page_dmah =
drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);

Expand Down Expand Up @@ -720,6 +720,9 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
drm_i915_private_t *dev_priv = dev->dev_private;
drm_i915_hws_addr_t *hws = data;

if (!I915_NEED_GFX_HWS(dev))
return -EINVAL;

if (!dev_priv) {
DRM_ERROR("called with no initialization\n");
return -EINVAL;
Expand Down
Loading

0 comments on commit 3a93dc4

Please sign in to comment.