Commit 2a56a884 authored by Dave Jones's avatar Dave Jones Committed by Dave Jones

[DRM] add support for new multiple agp bridge agpgart api

From: Michael Werner <werner@mrcoffee.engr.sgi.com>

This patch adds drm support for new multiple agp bridge agpgart api.
Signed-off-by: default avatarMike Werner <werner@sgi.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarDave Jones <davej@redhat.com>
parent 3c6ab8c2
...@@ -497,6 +497,7 @@ typedef struct drm_agp_head { ...@@ -497,6 +497,7 @@ typedef struct drm_agp_head {
DRM_AGP_KERN agp_info; /**< AGP device information */ DRM_AGP_KERN agp_info; /**< AGP device information */
drm_agp_mem_t *memory; /**< memory entries */ drm_agp_mem_t *memory; /**< memory entries */
unsigned long mode; /**< AGP mode */ unsigned long mode; /**< AGP mode */
struct agp_bridge_data *bridge;
int enabled; /**< whether the AGP bus as been enabled */ int enabled; /**< whether the AGP bus as been enabled */
int acquired; /**< whether the AGP device has been acquired */ int acquired; /**< whether the AGP device has been acquired */
unsigned long base; unsigned long base;
...@@ -807,7 +808,7 @@ extern void *drm_ioremap_nocache(unsigned long offset, unsigned long size, ...@@ -807,7 +808,7 @@ extern void *drm_ioremap_nocache(unsigned long offset, unsigned long size,
drm_device_t *dev); drm_device_t *dev);
extern void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev); extern void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev);
extern DRM_AGP_MEM *drm_alloc_agp(int pages, u32 type); extern DRM_AGP_MEM *drm_alloc_agp(struct agp_bridge_data *bridge, int pages, u32 type);
extern int drm_free_agp(DRM_AGP_MEM *handle, int pages); extern int drm_free_agp(DRM_AGP_MEM *handle, int pages);
extern int drm_bind_agp(DRM_AGP_MEM *handle, unsigned int start); extern int drm_bind_agp(DRM_AGP_MEM *handle, unsigned int start);
extern int drm_unbind_agp(DRM_AGP_MEM *handle); extern int drm_unbind_agp(DRM_AGP_MEM *handle);
...@@ -930,10 +931,10 @@ extern int drm_vblank_wait(drm_device_t *dev, unsigned int *vbl_seq); ...@@ -930,10 +931,10 @@ extern int drm_vblank_wait(drm_device_t *dev, unsigned int *vbl_seq);
extern void drm_vbl_send_signals( drm_device_t *dev ); extern void drm_vbl_send_signals( drm_device_t *dev );
/* AGP/GART support (drm_agpsupport.h) */ /* AGP/GART support (drm_agpsupport.h) */
extern drm_agp_head_t *drm_agp_init(void); extern drm_agp_head_t *drm_agp_init(drm_device_t *dev);
extern int drm_agp_acquire(struct inode *inode, struct file *filp, extern int drm_agp_acquire(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg); unsigned int cmd, unsigned long arg);
extern void drm_agp_do_release(void); extern void drm_agp_do_release(drm_device_t *dev);
extern int drm_agp_release(struct inode *inode, struct file *filp, extern int drm_agp_release(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg); unsigned int cmd, unsigned long arg);
extern int drm_agp_enable(struct inode *inode, struct file *filp, extern int drm_agp_enable(struct inode *inode, struct file *filp,
...@@ -948,7 +949,7 @@ extern int drm_agp_unbind(struct inode *inode, struct file *filp, ...@@ -948,7 +949,7 @@ extern int drm_agp_unbind(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg); unsigned int cmd, unsigned long arg);
extern int drm_agp_bind(struct inode *inode, struct file *filp, extern int drm_agp_bind(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg); unsigned int cmd, unsigned long arg);
extern DRM_AGP_MEM *drm_agp_allocate_memory(size_t pages, u32 type); extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size_t pages, u32 type);
extern int drm_agp_free_memory(DRM_AGP_MEM *handle); extern int drm_agp_free_memory(DRM_AGP_MEM *handle);
extern int drm_agp_bind_memory(DRM_AGP_MEM *handle, off_t start); extern int drm_agp_bind_memory(DRM_AGP_MEM *handle, off_t start);
extern int drm_agp_unbind_memory(DRM_AGP_MEM *handle); extern int drm_agp_unbind_memory(DRM_AGP_MEM *handle);
......
...@@ -92,14 +92,13 @@ int drm_agp_acquire(struct inode *inode, struct file *filp, ...@@ -92,14 +92,13 @@ int drm_agp_acquire(struct inode *inode, struct file *filp,
{ {
drm_file_t *priv = filp->private_data; drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev; drm_device_t *dev = priv->dev;
int retcode;
if (!dev->agp) if (!dev->agp)
return -ENODEV; return -ENODEV;
if (dev->agp->acquired) if (dev->agp->acquired)
return -EBUSY; return -EBUSY;
if ((retcode = agp_backend_acquire())) if (!(dev->agp->bridge = agp_backend_acquire(dev->pdev)))
return retcode; return -ENODEV;
dev->agp->acquired = 1; dev->agp->acquired = 1;
return 0; return 0;
} }
...@@ -123,7 +122,7 @@ int drm_agp_release(struct inode *inode, struct file *filp, ...@@ -123,7 +122,7 @@ int drm_agp_release(struct inode *inode, struct file *filp,
if (!dev->agp || !dev->agp->acquired) if (!dev->agp || !dev->agp->acquired)
return -EINVAL; return -EINVAL;
agp_backend_release(); agp_backend_release(dev->agp->bridge);
dev->agp->acquired = 0; dev->agp->acquired = 0;
return 0; return 0;
...@@ -134,9 +133,9 @@ int drm_agp_release(struct inode *inode, struct file *filp, ...@@ -134,9 +133,9 @@ int drm_agp_release(struct inode *inode, struct file *filp,
* *
* Calls agp_backend_release(). * Calls agp_backend_release().
*/ */
void drm_agp_do_release(void) void drm_agp_do_release(drm_device_t *dev)
{ {
agp_backend_release(); agp_backend_release(dev->agp->bridge);
} }
/** /**
...@@ -165,7 +164,7 @@ int drm_agp_enable(struct inode *inode, struct file *filp, ...@@ -165,7 +164,7 @@ int drm_agp_enable(struct inode *inode, struct file *filp,
return -EFAULT; return -EFAULT;
dev->agp->mode = mode.mode; dev->agp->mode = mode.mode;
agp_enable(mode.mode); agp_enable(dev->agp->bridge, mode.mode);
dev->agp->base = dev->agp->agp_info.aper_base; dev->agp->base = dev->agp->agp_info.aper_base;
dev->agp->enabled = 1; dev->agp->enabled = 1;
return 0; return 0;
...@@ -207,7 +206,7 @@ int drm_agp_alloc(struct inode *inode, struct file *filp, ...@@ -207,7 +206,7 @@ int drm_agp_alloc(struct inode *inode, struct file *filp,
pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE; pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
type = (u32) request.type; type = (u32) request.type;
if (!(memory = drm_alloc_agp(pages, type))) { if (!(memory = drm_alloc_agp(dev->agp->bridge, pages, type))) {
drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
return -ENOMEM; return -ENOMEM;
} }
...@@ -381,14 +380,19 @@ int drm_agp_free(struct inode *inode, struct file *filp, ...@@ -381,14 +380,19 @@ int drm_agp_free(struct inode *inode, struct file *filp,
* \return pointer to a drm_agp_head structure. * \return pointer to a drm_agp_head structure.
* *
*/ */
drm_agp_head_t *drm_agp_init(void) drm_agp_head_t *drm_agp_init(drm_device_t *dev)
{ {
drm_agp_head_t *head = NULL; drm_agp_head_t *head = NULL;
if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS))) if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS)))
return NULL; return NULL;
memset((void *)head, 0, sizeof(*head)); memset((void *)head, 0, sizeof(*head));
agp_copy_info(&head->agp_info); if (!(head->bridge = agp_backend_acquire(dev->pdev))) {
drm_free(head, sizeof(*head), DRM_MEM_AGPLISTS);
return NULL;
}
agp_copy_info(head->bridge, &head->agp_info);
agp_backend_release(head->bridge);
if (head->agp_info.chipset == NOT_SUPPORTED) { if (head->agp_info.chipset == NOT_SUPPORTED) {
drm_free(head, sizeof(*head), DRM_MEM_AGPLISTS); drm_free(head, sizeof(*head), DRM_MEM_AGPLISTS);
return NULL; return NULL;
...@@ -406,9 +410,9 @@ drm_agp_head_t *drm_agp_init(void) ...@@ -406,9 +410,9 @@ drm_agp_head_t *drm_agp_init(void)
} }
/** Calls agp_allocate_memory() */ /** Calls agp_allocate_memory() */
DRM_AGP_MEM *drm_agp_allocate_memory(size_t pages, u32 type) DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size_t pages, u32 type)
{ {
return agp_allocate_memory(pages, type); return agp_allocate_memory(bridge, pages, type);
} }
/** Calls agp_free_memory() */ /** Calls agp_free_memory() */
......
...@@ -185,7 +185,7 @@ int drm_takedown( drm_device_t *dev ) ...@@ -185,7 +185,7 @@ int drm_takedown( drm_device_t *dev )
} }
dev->agp->memory = NULL; dev->agp->memory = NULL;
if ( dev->agp->acquired ) drm_agp_do_release(); if ( dev->agp->acquired ) drm_agp_do_release(dev);
dev->agp->acquired = 0; dev->agp->acquired = 0;
dev->agp->enabled = 0; dev->agp->enabled = 0;
......
...@@ -155,9 +155,9 @@ void drm_free_pages(unsigned long address, int order, int area) ...@@ -155,9 +155,9 @@ void drm_free_pages(unsigned long address, int order, int area)
#if __OS_HAS_AGP #if __OS_HAS_AGP
/** Wrapper around agp_allocate_memory() */ /** Wrapper around agp_allocate_memory() */
DRM_AGP_MEM *drm_alloc_agp(int pages, u32 type) DRM_AGP_MEM *drm_alloc_agp(struct agp_bridge_data *bridge, int pages, u32 type)
{ {
return drm_agp_allocate_memory(pages, type); return drm_agp_allocate_memory(bridge, pages, type);
} }
/** Wrapper around agp_free_memory() */ /** Wrapper around agp_free_memory() */
......
...@@ -91,7 +91,7 @@ static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct ...@@ -91,7 +91,7 @@ static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct
goto error_out_unreg; goto error_out_unreg;
if (drm_core_has_AGP(dev)) { if (drm_core_has_AGP(dev)) {
dev->agp = drm_agp_init(); dev->agp = drm_agp_init(dev);
if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) && (dev->agp == NULL)) { if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) && (dev->agp == NULL)) {
DRM_ERROR( "Cannot initialize the agpgart module.\n" ); DRM_ERROR( "Cannot initialize the agpgart module.\n" );
retcode = -EINVAL; retcode = -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment