xgixp: Remove dependency on TTM fences

main
Ian Romanick 2008-06-10 22:18:14 -07:00
parent 4f3da2f200
commit b535567ee9
5 changed files with 117 additions and 15 deletions

View File

@ -148,7 +148,9 @@ int xgi_submit_cmdlist(struct drm_device * dev, void * data,
}
info->cmdring.last_ptr = xgi_find_pcie_virt(info, pCmdInfo->hw_addr);
#ifdef XGI_HAVE_FENCE
drm_fence_flush_old(info->dev, 0, info->next_sequence);
#endif /* XGI_HAVE_FENCE */
return 0;
}

View File

@ -37,7 +37,9 @@ static struct pci_device_id pciidlist[] = {
xgi_PCI_IDS
};
#ifdef XGI_HAVE_FENCE
extern struct drm_fence_driver xgi_fence_driver;
#endif /* XGI_HAVE_FENCE */
int xgi_bootstrap(struct drm_device *, void *, struct drm_file *);
@ -47,6 +49,8 @@ static struct drm_ioctl_desc xgi_ioctls[] = {
DRM_IOCTL_DEF(DRM_XGI_FREE, xgi_free_ioctl, DRM_AUTH),
DRM_IOCTL_DEF(DRM_XGI_SUBMIT_CMDLIST, xgi_submit_cmdlist, DRM_AUTH),
DRM_IOCTL_DEF(DRM_XGI_STATE_CHANGE, xgi_state_change_ioctl, DRM_AUTH|DRM_MASTER),
DRM_IOCTL_DEF(DRM_XGI_SET_FENCE, xgi_set_fence_ioctl, DRM_AUTH),
DRM_IOCTL_DEF(DRM_XGI_WAIT_FENCE, xgi_wait_fence_ioctl, DRM_AUTH),
};
static const int xgi_max_ioctl = DRM_ARRAY_SIZE(xgi_ioctls);
@ -58,6 +62,7 @@ static void xgi_driver_lastclose(struct drm_device * dev);
static void xgi_reclaim_buffers_locked(struct drm_device * dev,
struct drm_file * filp);
static irqreturn_t xgi_kern_isr(DRM_IRQ_ARGS);
static int xgi_kern_isr_postinstall(struct drm_device * dev);
static struct drm_driver driver = {
@ -70,7 +75,7 @@ static struct drm_driver driver = {
.lastclose = xgi_driver_lastclose,
.dma_quiescent = NULL,
.irq_preinstall = NULL,
.irq_postinstall = NULL,
.irq_postinstall = xgi_kern_isr_postinstall,
.irq_uninstall = NULL,
.irq_handler = xgi_kern_isr,
.reclaim_buffers = drm_core_reclaim_buffers,
@ -100,7 +105,9 @@ static struct drm_driver driver = {
.remove = __devexit_p(drm_cleanup_pci),
},
#ifdef XGI_HAVE_FENCE
.fence_driver = &xgi_fence_driver,
#endif /* XGI_HAVE_FENCE */
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
@ -355,7 +362,10 @@ irqreturn_t xgi_kern_isr(DRM_IRQ_ARGS)
DRM_WRITE32(info->mmio_map,
0x2800 + M2REG_AUTO_LINK_SETTING_ADDRESS,
cpu_to_le32(M2REG_AUTO_LINK_SETTING_COMMAND | irq_bits));
#ifdef XGI_HAVE_FENCE
xgi_fence_handler(dev);
#endif /* XGI_HAVE_FENCE */
DRM_WAKEUP(&info->fence_queue);
return IRQ_HANDLED;
} else {
return IRQ_NONE;
@ -363,6 +373,15 @@ irqreturn_t xgi_kern_isr(DRM_IRQ_ARGS)
}
int xgi_kern_isr_postinstall(struct drm_device * dev)
{
struct xgi_info *info = dev->dev_private;
DRM_INIT_WAITQUEUE(&info->fence_queue);
return 0;
}
int xgi_driver_load(struct drm_device *dev, unsigned long flags)
{
struct xgi_info *info = drm_alloc(sizeof(*info), DRM_MEM_DRIVER);

View File

@ -74,6 +74,7 @@ struct xgi_info {
struct xgi_cmdring_info cmdring;
DRM_SPINTYPE fence_lock;
wait_queue_head_t fence_queue;
unsigned complete_sequence;
unsigned next_sequence;
};
@ -98,12 +99,24 @@ extern void xgi_disable_mmio(struct xgi_info * info);
extern void xgi_enable_ge(struct xgi_info * info);
extern void xgi_disable_ge(struct xgi_info * info);
/* TTM-style fences.
*/
#ifdef XGI_HAVE_FENCE
extern void xgi_poke_flush(struct drm_device * dev, uint32_t class);
extern int xgi_fence_emit_sequence(struct drm_device * dev, uint32_t class,
uint32_t flags, uint32_t * sequence, uint32_t * native_type);
extern void xgi_fence_handler(struct drm_device * dev);
extern int xgi_fence_has_irq(struct drm_device *dev, uint32_t class,
uint32_t flags);
#endif /* XGI_HAVE_FENCE */
/* Non-TTM-style fences.
*/
extern int xgi_set_fence_ioctl(struct drm_device * dev, void * data,
struct drm_file * filp);
extern int xgi_wait_fence_ioctl(struct drm_device * dev, void * data,
struct drm_file * filp);
extern int xgi_alloc_ioctl(struct drm_device * dev, void * data,
struct drm_file * filp);

View File

@ -30,6 +30,76 @@
#include "xgi_misc.h"
#include "xgi_cmdlist.h"
static int xgi_low_level_fence_emit(struct drm_device *dev, u32 *sequence)
{
struct xgi_info *const info = dev->dev_private;
if (info == NULL) {
DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
DRM_SPINLOCK(&info->fence_lock);
info->next_sequence++;
if (info->next_sequence > BEGIN_BEGIN_IDENTIFICATION_MASK) {
info->next_sequence = 1;
}
*sequence = (u32) info->next_sequence;
DRM_SPINUNLOCK(&info->fence_lock);
xgi_emit_irq(info);
return 0;
}
#define GET_BEGIN_ID(i) (le32_to_cpu(DRM_READ32((i)->mmio_map, 0x2820)) \
& BEGIN_BEGIN_IDENTIFICATION_MASK)
static int xgi_low_level_fence_wait(struct drm_device *dev, unsigned *sequence)
{
struct xgi_info *const info = dev->dev_private;
unsigned int cur_fence;
int ret = 0;
if (info == NULL) {
DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
/* Assume that the user has missed the current sequence number
* by about a day rather than she wants to wait for years
* using fences.
*/
DRM_WAIT_ON(ret, info->fence_queue, 3 * DRM_HZ,
((((cur_fence = GET_BEGIN_ID(info))
- *sequence) & BEGIN_BEGIN_IDENTIFICATION_MASK)
<= (1 << 18)));
info->complete_sequence = cur_fence;
*sequence = cur_fence;
return ret;
}
int xgi_set_fence_ioctl(struct drm_device * dev, void * data,
struct drm_file * filp)
{
(void) filp;
return xgi_low_level_fence_emit(dev, (u32 *) data);
}
int xgi_wait_fence_ioctl(struct drm_device * dev, void * data,
struct drm_file * filp)
{
(void) filp;
return xgi_low_level_fence_wait(dev, (u32 *) data);
}
#ifdef XGI_HAVE_FENCE
static void xgi_fence_poll(struct drm_device * dev, uint32_t class,
uint32_t waiting_types)
{
@ -68,25 +138,18 @@ int xgi_fence_emit_sequence(struct drm_device * dev, uint32_t class,
uint32_t flags, uint32_t * sequence,
uint32_t * native_type)
{
struct xgi_info * info = dev->dev_private;
int err;
if ((info == NULL) || (class != 0))
(void) flags;
if (class != 0)
return -EINVAL;
err = xgi_low_level_fence_emit(dev, sequence);
if (err)
return err;
DRM_SPINLOCK(&info->fence_lock);
info->next_sequence++;
if (info->next_sequence > BEGIN_BEGIN_IDENTIFICATION_MASK) {
info->next_sequence = 1;
}
DRM_SPINUNLOCK(&info->fence_lock);
xgi_emit_irq(info);
*sequence = (uint32_t) info->next_sequence;
*native_type = DRM_FENCE_TYPE_EXE;
return 0;
}
@ -120,3 +183,4 @@ struct drm_fence_driver xgi_fence_driver = {
.wait = NULL
};
#endif /* XGI_HAVE_FENCE */

View File

@ -123,11 +123,15 @@ struct xgi_state_info {
#define DRM_XGI_FREE 2
#define DRM_XGI_SUBMIT_CMDLIST 3
#define DRM_XGI_STATE_CHANGE 4
#define DRM_XGI_SET_FENCE 5
#define DRM_XGI_WAIT_FENCE 6
#define XGI_IOCTL_BOOTSTRAP DRM_IOWR(DRM_COMMAND_BASE + DRM_XGI_BOOTSTRAP, struct xgi_bootstrap)
#define XGI_IOCTL_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_XGI_ALLOC, struct xgi_mem_alloc)
#define XGI_IOCTL_FREE DRM_IOW(DRM_COMMAND_BASE + DRM_XGI_FREE, __u32)
#define XGI_IOCTL_SUBMIT_CMDLIST DRM_IOW(DRM_COMMAND_BASE + DRM_XGI_SUBMIT_CMDLIST, struct xgi_cmd_info)
#define XGI_IOCTL_STATE_CHANGE DRM_IOW(DRM_COMMAND_BASE + DRM_XGI_STATE_CHANGE, struct xgi_state_info)
#define XGI_IOCTL_SET_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_XGI_SET_FENCE, u32)
#define XGI_IOCTL_WAIT_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_XGI_WAIT_FENCE, u32)
#endif /* _XGI_DRM_H_ */