From: <th...@ke...> - 2008-03-16 10:46:28
|
linux-core/via_dmablit.c | 2 +- shared-core/via_dma.c | 47 +++++++++++++++++++++++++++++++++++++++++------ shared-core/via_irq.c | 10 ++++++++++ 3 files changed, 52 insertions(+), 7 deletions(-) New commits: commit 3a3a9485aadced820f7619ef7f2a11e72782769f Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> Date: Sun Mar 16 11:44:35 2008 +0100 [via] Remove some leftover vars. diff --git a/shared-core/via_dma.c b/shared-core/via_dma.c index 6335710..ffdb7bf 100644 --- a/shared-core/via_dma.c +++ b/shared-core/via_dma.c @@ -406,18 +406,19 @@ static int via_hook_segment(drm_via_private_t * dev_priv, int paused, count; volatile uint32_t *paused_at = dev_priv->last_pause_ptr; uint32_t reader,ptr; - uint32_t data; - cycles_t time; paused = 0; via_flush_write_combine(); (void) *(volatile uint32_t *)(via_get_dma(dev_priv) -1); + *paused_at = pause_addr_lo; via_flush_write_combine(); (void) *paused_at; + reader = *(dev_priv->hw_addr_ptr); ptr = ((volatile char *)paused_at - dev_priv->dma_ptr) + dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4; + dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1; if ((ptr - reader) <= dev_priv->dma_diff ) { commit b81d7b3b8d7ca83a9b79d2dbea22f00e78180516 Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> Date: Sun Mar 16 11:39:18 2008 +0100 [via] Allow a little larger stride for SG DMA DownloadFromScreen. diff --git a/linux-core/via_dmablit.c b/linux-core/via_dmablit.c index a6a2178..b5f9f05 100644 --- a/linux-core/via_dmablit.c +++ b/linux-core/via_dmablit.c @@ -618,7 +618,7 @@ via_build_sg_info(struct drm_device *dev, drm_via_sg_info_t *vsg, drm_via_dmabli * (Not a big limitation anyway.) */ - if ((xfer->mem_stride - xfer->line_length) >= PAGE_SIZE) { + if ((xfer->mem_stride - xfer->line_length) > 2*PAGE_SIZE) { DRM_ERROR("Too large system memory stride. Stride: %d, " "Length: %d\n", xfer->mem_stride, xfer->line_length); return -EINVAL; commit 7d3d15e67de27f7c47859f36bb55002f0c9d52d6 Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> Date: Sun Mar 16 11:37:17 2008 +0100 [via] The millionth fixup for the millionth-1 attempt to stabilize the AGP DMA command submission. It's worth remembering that all new bright ideas on how to make this command reader work properly and according to docs will probably fail :( Bring in some old code. diff --git a/shared-core/via_dma.c b/shared-core/via_dma.c index 431738a..6335710 100644 --- a/shared-core/via_dma.c +++ b/shared-core/via_dma.c @@ -406,6 +406,8 @@ static int via_hook_segment(drm_via_private_t * dev_priv, int paused, count; volatile uint32_t *paused_at = dev_priv->last_pause_ptr; uint32_t reader,ptr; + uint32_t data; + cycles_t time; paused = 0; via_flush_write_combine(); @@ -423,10 +425,17 @@ static int via_hook_segment(drm_via_private_t * dev_priv, while (!(paused = (VIA_READ(0x41c) & 0x80000000)) && count--); } + paused = VIA_READ(0x41c) & 0x80000000; if (paused && !no_pci_fire) { + uint32_t diff; reader = *(dev_priv->hw_addr_ptr); - if ((ptr - reader) == dev_priv->dma_diff) { - + diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff; + diff &= (dev_priv->dma_high - 1); + if (diff != 0 && diff < (dev_priv->dma_high >> 1)) { + DRM_ERROR("Paused at incorrect address. " + "0x%08x, 0x%08x 0x%08x\n", + ptr, reader, dev_priv->dma_diff); + } else if (diff == 0) { /* * There is a concern that these writes may stall the PCI bus * if the GPU is not idle. However, idling the GPU first @@ -571,14 +580,14 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv) uint32_t pause_addr_lo, pause_addr_hi; uint32_t jump_addr_lo, jump_addr_hi; volatile uint32_t *last_pause_ptr; - + uint32_t dma_low_save1, dma_low_save2; + agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi, &jump_addr_lo, 0); dev_priv->dma_wrap = dev_priv->dma_low; - /* * Wrap command buffer to the beginning. */ @@ -590,15 +599,40 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv) via_dummy_bitblt(dev_priv); via_dummy_bitblt(dev_priv); - last_pause_ptr = via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, - &pause_addr_lo, 0) -1; + + last_pause_ptr = + via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, + &pause_addr_lo, 0) - 1; via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, &pause_addr_lo, 0); + *last_pause_ptr = pause_addr_lo; + dma_low_save1 = dev_priv->dma_low; + + /* + * Now, set a trap that will pause the regulator if it tries to rerun the old + * command buffer. (Which may happen if via_hook_segment detecs a command regulator pause + * and reissues the jump command over PCI, while the regulator has already taken the jump + * and actually paused at the current buffer end). + * There appears to be no other way to detect this condition, since the hw_addr_pointer + * does not seem to get updated immediately when a jump occurs. + */ + last_pause_ptr = + via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, + &pause_addr_lo, 0) - 1; + via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, + &pause_addr_lo, 0); + *last_pause_ptr = pause_addr_lo; + + dma_low_save2 = dev_priv->dma_low; + dev_priv->dma_low = dma_low_save1; via_hook_segment(dev_priv, jump_addr_hi, jump_addr_lo, 0); + dev_priv->dma_low = dma_low_save2; + via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0); } + static void via_cmdbuf_rewind(drm_via_private_t * dev_priv) { via_cmdbuf_jump(dev_priv); commit 563fe9dcd4d08de8864ade161258df891f3db471 Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> Date: Sun Mar 16 11:29:57 2008 +0100 [via] Fix driver after vblank-rework merge. diff --git a/shared-core/via_irq.c b/shared-core/via_irq.c index b8e652e..c3279f8 100644 --- a/shared-core/via_irq.c +++ b/shared-core/via_irq.c @@ -190,11 +190,20 @@ int via_enable_vblank(struct drm_device *dev, int crtc) status = VIA_READ(VIA_REG_INTERRUPT); VIA_WRITE(VIA_REG_INTERRUPT, status & VIA_IRQ_VBLANK_ENABLE); + + VIA_WRITE8(0x83d4, 0x11); + VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); + return 0; } void via_disable_vblank(struct drm_device *dev, int crtc) { + drm_via_private_t *dev_priv = dev->dev_private; + + VIA_WRITE8(0x83d4, 0x11); + VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30); + if (crtc != 0) DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc); } @@ -311,6 +320,7 @@ int via_driver_irq_postinstall(struct drm_device * dev) if (!dev_priv) return -EINVAL; + drm_vblank_init(dev, 1); status = VIA_READ(VIA_REG_INTERRUPT); VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL | dev_priv->irq_enable_mask); |