diff options
author | Thomas Hellstrom <unichrome@shipmail.org> | 2005-09-25 12:54:12 +0000 |
---|---|---|
committer | Thomas Hellstrom <unichrome@shipmail.org> | 2005-09-25 12:54:12 +0000 |
commit | 903e5701ffbc613373f3ad3c3b7e14d493ec9dbe (patch) | |
tree | 9d48674c71d81ca036b504af57307ad01180944c /shared-core/via_irq.c | |
parent | d4dec1db808095f42b6fd776b2582c6f27bebb9a (diff) |
Add the via PCI DMA blit code.
Diffstat (limited to 'shared-core/via_irq.c')
-rw-r--r-- | shared-core/via_irq.c | 55 |
1 files changed, 48 insertions, 7 deletions
diff --git a/shared-core/via_irq.c b/shared-core/via_irq.c index f87b2f2c..96be8e3d 100644 --- a/shared-core/via_irq.c +++ b/shared-core/via_irq.c @@ -50,6 +50,15 @@ #define VIA_IRQ_HQV1_ENABLE (1 << 25) #define VIA_IRQ_HQV0_PENDING (1 << 9) #define VIA_IRQ_HQV1_PENDING (1 << 10) +#define VIA_IRQ_DMA0_DD_ENABLE (1 << 20) +#define VIA_IRQ_DMA0_TD_ENABLE (1 << 21) +#define VIA_IRQ_DMA1_DD_ENABLE (1 << 22) +#define VIA_IRQ_DMA1_TD_ENABLE (1 << 23) +#define VIA_IRQ_DMA0_DD_PENDING (1 << 4) +#define VIA_IRQ_DMA0_TD_PENDING (1 << 5) +#define VIA_IRQ_DMA1_DD_PENDING (1 << 6) +#define VIA_IRQ_DMA1_TD_PENDING (1 << 7) + /* * Device-specific IRQs go here. This type might need to be extended with @@ -57,13 +66,26 @@ * Currently we activate the HQV interrupts of Unichrome Pro group A. */ + static maskarray_t via_pro_group_a_irqs[] = { {VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010, 0x00000000 }, - {VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010, 0x00000000 }}; + {VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010, 0x00000000 }, + {VIA_IRQ_DMA0_TD_ENABLE, VIA_IRQ_DMA0_TD_PENDING, VIA_PCI_DMA_CSR0, + VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}, + {VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1, + VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008} +}; static int via_num_pro_group_a = sizeof(via_pro_group_a_irqs)/sizeof(maskarray_t); - -static maskarray_t via_unichrome_irqs[] = {}; +static int via_irqmap_pro_group_a[] = {0, 1, -1, 2, -1, 3}; + +static maskarray_t via_unichrome_irqs[] = { + {VIA_IRQ_DMA0_TD_ENABLE, VIA_IRQ_DMA0_TD_PENDING, VIA_PCI_DMA_CSR0, + VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}, + {VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1, + VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008} +}; static int via_num_unichrome = sizeof(via_unichrome_irqs)/sizeof(maskarray_t); +static int via_irqmap_unichrome[] = {-1, -1, -1, 0, -1, 1}; static unsigned time_diff(struct timeval *now,struct timeval *then) @@ -111,9 +133,17 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) for (i=0; i<dev_priv->num_irqs; ++i) { if (status & cur_irq->pending_mask) { + DRM_DEBUG("Received IRQ %d\n", i); atomic_inc( &cur_irq->irq_received ); DRM_WAKEUP( &cur_irq->irq_queue ); handled = 1; +#ifdef VIA_HAVE_DMABLIT + if (dev_priv->irq_map[drm_via_irq_dma0_td] == i) { + via_dmablit_handler(dev, 0, 1); + } else if (dev_priv->irq_map[drm_via_irq_dma1_td] == i) { + via_dmablit_handler(dev, 1, 1); + } +#endif } cur_irq++; } @@ -167,7 +197,7 @@ int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) return ret; } -static int +int via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, unsigned int *sequence) { @@ -176,6 +206,7 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, drm_via_irq_t *cur_irq = dev_priv->via_irqs; int ret = 0; maskarray_t *masks = dev_priv->irq_masks; + int real_irq; DRM_DEBUG("%s\n", __FUNCTION__); @@ -184,14 +215,22 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, return DRM_ERR(EINVAL); } - if (irq >= dev_priv->num_irqs ) { + if (irq >= drm_via_irq_num ) { DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__, irq); return DRM_ERR(EINVAL); } - cur_irq += irq; + real_irq = dev_priv->irq_map[irq]; + + if (real_irq < 0) { + DRM_ERROR("%s Video IRQ %d is not available on this hardware.\n", __FUNCTION__, irq); + return DRM_ERR(EINVAL); + } + + + cur_irq += real_irq; - if (masks[irq][2] && !force_sequence) { + if (masks[real_irq][2] && !force_sequence) { DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ, ((VIA_READ(masks[irq][2]) & masks[irq][3]) == masks[irq][4])); cur_irq_sequence = atomic_read(&cur_irq->irq_received); @@ -226,6 +265,8 @@ void via_driver_irq_preinstall(drm_device_t * dev) via_pro_group_a_irqs : via_unichrome_irqs; dev_priv->num_irqs = (dev_priv->pro_group_a) ? via_num_pro_group_a : via_num_unichrome; + dev_priv->irq_map = (dev_priv->pro_group_a) ? + via_irqmap_pro_group_a : via_irqmap_unichrome; for(i=0; i < dev_priv->num_irqs; ++i) { atomic_set(&cur_irq->irq_received, 0); |