diff options
author | David Miller <davem@davemloft.net> | 2009-02-12 05:15:37 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-03-13 00:24:00 -0400 |
commit | b07fa022ecf1e04fd0623877affe9e10bf45ac86 (patch) | |
tree | 59d17e4b898db739701552030519ca7e0004ab6c /drivers/gpu | |
parent | 296c6ae0e9b5ced1060b43a68b5f7e41a18509f6 (diff) |
drm: radeon: Fix ring_rptr accesses.
The memory behind ring_rptr can either be in ioremapped memory
or a vmalloc() normal kernel memory buffer.
However, the code unconditionally uses DRM_{READ,WRITE}32() (and thus
readl() and writel()) to access it.
Basically, if RADEON_IS_AGP then it's ioremap()'d memory else it's
vmalloc'd memory.
Adjust all of the ring_rptr access code as needed.
While we're here, kill the 'scratch' pointer in drm_radeon_private.
It's only used in the one place where it is initialized.
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Dave Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_cp.c | 70 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_drv.h | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_state.c | 6 |
3 files changed, 70 insertions, 23 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index 34c0b3f0c29e..8a8a82a2c170 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c | |||
@@ -43,6 +43,52 @@ | |||
43 | static int radeon_do_cleanup_cp(struct drm_device * dev); | 43 | static int radeon_do_cleanup_cp(struct drm_device * dev); |
44 | static void radeon_do_cp_start(drm_radeon_private_t * dev_priv); | 44 | static void radeon_do_cp_start(drm_radeon_private_t * dev_priv); |
45 | 45 | ||
46 | static u32 radeon_read_ring_rptr(drm_radeon_private_t *dev_priv, u32 off) | ||
47 | { | ||
48 | u32 val; | ||
49 | |||
50 | if (dev_priv->flags & RADEON_IS_AGP) { | ||
51 | val = DRM_READ32(dev_priv->ring_rptr, off); | ||
52 | } else { | ||
53 | val = *(((volatile u32 *) | ||
54 | dev_priv->ring_rptr->handle) + | ||
55 | (off / sizeof(u32))); | ||
56 | val = le32_to_cpu(val); | ||
57 | } | ||
58 | return val; | ||
59 | } | ||
60 | |||
61 | u32 radeon_get_ring_head(drm_radeon_private_t *dev_priv) | ||
62 | { | ||
63 | if (dev_priv->writeback_works) | ||
64 | return radeon_read_ring_rptr(dev_priv, 0); | ||
65 | else | ||
66 | return RADEON_READ(RADEON_CP_RB_RPTR); | ||
67 | } | ||
68 | |||
69 | static void radeon_write_ring_rptr(drm_radeon_private_t *dev_priv, u32 off, u32 val) | ||
70 | { | ||
71 | if (dev_priv->flags & RADEON_IS_AGP) | ||
72 | DRM_WRITE32(dev_priv->ring_rptr, off, val); | ||
73 | else | ||
74 | *(((volatile u32 *) dev_priv->ring_rptr->handle) + | ||
75 | (off / sizeof(u32))) = cpu_to_le32(val); | ||
76 | } | ||
77 | |||
78 | void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val) | ||
79 | { | ||
80 | radeon_write_ring_rptr(dev_priv, 0, val); | ||
81 | } | ||
82 | |||
83 | u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index) | ||
84 | { | ||
85 | if (dev_priv->writeback_works) | ||
86 | return radeon_read_ring_rptr(dev_priv, | ||
87 | RADEON_SCRATCHOFF(index)); | ||
88 | else | ||
89 | return RADEON_READ(RADEON_SCRATCH_REG0 + 4*index); | ||
90 | } | ||
91 | |||
46 | static u32 R500_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) | 92 | static u32 R500_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) |
47 | { | 93 | { |
48 | u32 ret; | 94 | u32 ret; |
@@ -649,10 +695,6 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, | |||
649 | RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR) | 695 | RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR) |
650 | + RADEON_SCRATCH_REG_OFFSET); | 696 | + RADEON_SCRATCH_REG_OFFSET); |
651 | 697 | ||
652 | dev_priv->scratch = ((__volatile__ u32 *) | ||
653 | dev_priv->ring_rptr->handle + | ||
654 | (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); | ||
655 | |||
656 | RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); | 698 | RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); |
657 | 699 | ||
658 | /* Turn on bus mastering */ | 700 | /* Turn on bus mastering */ |
@@ -670,13 +712,13 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, | |||
670 | RADEON_WRITE(RADEON_BUS_CNTL, tmp); | 712 | RADEON_WRITE(RADEON_BUS_CNTL, tmp); |
671 | } /* PCIE cards appears to not need this */ | 713 | } /* PCIE cards appears to not need this */ |
672 | 714 | ||
673 | dev_priv->scratch[0] = 0; | 715 | radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(0), 0); |
674 | RADEON_WRITE(RADEON_LAST_FRAME_REG, 0); | 716 | RADEON_WRITE(RADEON_LAST_FRAME_REG, 0); |
675 | 717 | ||
676 | dev_priv->scratch[1] = 0; | 718 | radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1), 0); |
677 | RADEON_WRITE(RADEON_LAST_DISPATCH_REG, 0); | 719 | RADEON_WRITE(RADEON_LAST_DISPATCH_REG, 0); |
678 | 720 | ||
679 | dev_priv->scratch[2] = 0; | 721 | radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(2), 0); |
680 | RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0); | 722 | RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0); |
681 | 723 | ||
682 | /* reset sarea copies of these */ | 724 | /* reset sarea copies of these */ |
@@ -708,12 +750,15 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv) | |||
708 | /* Writeback doesn't seem to work everywhere, test it here and possibly | 750 | /* Writeback doesn't seem to work everywhere, test it here and possibly |
709 | * enable it if it appears to work | 751 | * enable it if it appears to work |
710 | */ | 752 | */ |
711 | DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0); | 753 | radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1), 0); |
754 | |||
712 | RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef); | 755 | RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef); |
713 | 756 | ||
714 | for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { | 757 | for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { |
715 | if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) == | 758 | u32 val; |
716 | 0xdeadbeef) | 759 | |
760 | val = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1)); | ||
761 | if (val == 0xdeadbeef) | ||
717 | break; | 762 | break; |
718 | DRM_UDELAY(1); | 763 | DRM_UDELAY(1); |
719 | } | 764 | } |
@@ -1549,7 +1594,7 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev) | |||
1549 | start = dev_priv->last_buf; | 1594 | start = dev_priv->last_buf; |
1550 | 1595 | ||
1551 | for (t = 0; t < dev_priv->usec_timeout; t++) { | 1596 | for (t = 0; t < dev_priv->usec_timeout; t++) { |
1552 | u32 done_age = GET_SCRATCH(1); | 1597 | u32 done_age = GET_SCRATCH(dev_priv, 1); |
1553 | DRM_DEBUG("done_age = %d\n", done_age); | 1598 | DRM_DEBUG("done_age = %d\n", done_age); |
1554 | for (i = start; i < dma->buf_count; i++) { | 1599 | for (i = start; i < dma->buf_count; i++) { |
1555 | buf = dma->buflist[i]; | 1600 | buf = dma->buflist[i]; |
@@ -1583,8 +1628,9 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev) | |||
1583 | struct drm_buf *buf; | 1628 | struct drm_buf *buf; |
1584 | int i, t; | 1629 | int i, t; |
1585 | int start; | 1630 | int start; |
1586 | u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)); | 1631 | u32 done_age; |
1587 | 1632 | ||
1633 | done_age = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1)); | ||
1588 | if (++dev_priv->last_buf >= dma->buf_count) | 1634 | if (++dev_priv->last_buf >= dma->buf_count) |
1589 | dev_priv->last_buf = 0; | 1635 | dev_priv->last_buf = 0; |
1590 | 1636 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index c608e22f73f9..a253cf071ec4 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h | |||
@@ -160,10 +160,6 @@ enum radeon_chip_flags { | |||
160 | RADEON_IS_IGPGART = 0x01000000UL, | 160 | RADEON_IS_IGPGART = 0x01000000UL, |
161 | }; | 161 | }; |
162 | 162 | ||
163 | #define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \ | ||
164 | DRM_READ32( (dev_priv)->ring_rptr, 0 ) : RADEON_READ(RADEON_CP_RB_RPTR)) | ||
165 | #define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) ) | ||
166 | |||
167 | typedef struct drm_radeon_freelist { | 163 | typedef struct drm_radeon_freelist { |
168 | unsigned int age; | 164 | unsigned int age; |
169 | struct drm_buf *buf; | 165 | struct drm_buf *buf; |
@@ -248,7 +244,6 @@ typedef struct drm_radeon_private { | |||
248 | drm_radeon_freelist_t *head; | 244 | drm_radeon_freelist_t *head; |
249 | drm_radeon_freelist_t *tail; | 245 | drm_radeon_freelist_t *tail; |
250 | int last_buf; | 246 | int last_buf; |
251 | volatile u32 *scratch; | ||
252 | int writeback_works; | 247 | int writeback_works; |
253 | 248 | ||
254 | int usec_timeout; | 249 | int usec_timeout; |
@@ -338,6 +333,12 @@ extern int radeon_no_wb; | |||
338 | extern struct drm_ioctl_desc radeon_ioctls[]; | 333 | extern struct drm_ioctl_desc radeon_ioctls[]; |
339 | extern int radeon_max_ioctl; | 334 | extern int radeon_max_ioctl; |
340 | 335 | ||
336 | extern u32 radeon_get_ring_head(drm_radeon_private_t *dev_priv); | ||
337 | extern void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val); | ||
338 | |||
339 | #define GET_RING_HEAD(dev_priv) radeon_get_ring_head(dev_priv) | ||
340 | #define SET_RING_HEAD(dev_priv, val) radeon_set_ring_head(dev_priv, val) | ||
341 | |||
341 | /* Check whether the given hardware address is inside the framebuffer or the | 342 | /* Check whether the given hardware address is inside the framebuffer or the |
342 | * GART area. | 343 | * GART area. |
343 | */ | 344 | */ |
@@ -639,9 +640,9 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, | |||
639 | 640 | ||
640 | #define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x)) | 641 | #define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x)) |
641 | 642 | ||
642 | #define GET_SCRATCH( x ) (dev_priv->writeback_works \ | 643 | extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index); |
643 | ? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \ | 644 | |
644 | : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) ) | 645 | #define GET_SCRATCH(dev_priv, x) radeon_get_scratch(dev_priv, x) |
645 | 646 | ||
646 | #define RADEON_GEN_INT_CNTL 0x0040 | 647 | #define RADEON_GEN_INT_CNTL 0x0040 |
647 | # define RADEON_CRTC_VBLANK_MASK (1 << 0) | 648 | # define RADEON_CRTC_VBLANK_MASK (1 << 0) |
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index ef940a079dcb..03fea43dae75 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c | |||
@@ -3010,14 +3010,14 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil | |||
3010 | break; | 3010 | break; |
3011 | case RADEON_PARAM_LAST_FRAME: | 3011 | case RADEON_PARAM_LAST_FRAME: |
3012 | dev_priv->stats.last_frame_reads++; | 3012 | dev_priv->stats.last_frame_reads++; |
3013 | value = GET_SCRATCH(0); | 3013 | value = GET_SCRATCH(dev_priv, 0); |
3014 | break; | 3014 | break; |
3015 | case RADEON_PARAM_LAST_DISPATCH: | 3015 | case RADEON_PARAM_LAST_DISPATCH: |
3016 | value = GET_SCRATCH(1); | 3016 | value = GET_SCRATCH(dev_priv, 1); |
3017 | break; | 3017 | break; |
3018 | case RADEON_PARAM_LAST_CLEAR: | 3018 | case RADEON_PARAM_LAST_CLEAR: |
3019 | dev_priv->stats.last_clear_reads++; | 3019 | dev_priv->stats.last_clear_reads++; |
3020 | value = GET_SCRATCH(2); | 3020 | value = GET_SCRATCH(dev_priv, 2); |
3021 | break; | 3021 | break; |
3022 | case RADEON_PARAM_IRQ_NR: | 3022 | case RADEON_PARAM_IRQ_NR: |
3023 | value = drm_dev_to_irq(dev); | 3023 | value = drm_dev_to_irq(dev); |