aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_cp.c
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2009-02-24 16:22:29 -0500
committerDave Airlie <airlied@redhat.com>2009-03-13 00:24:11 -0400
commitc05ce0834a268f7d18274847190f6ed826b99332 (patch)
treeb9980946e7e5cb72abf20c88c3f84db93af9c281 /drivers/gpu/drm/radeon/radeon_cp.c
parent80b3334a4d5c163ab35c560a21d2cdc39bb5d3f8 (diff)
drm/radeon: add initial support for R6xx/R7xx GPUs
This adds support for 2D/Xv acceleration in the X.org 2D driver, to the drm. It doesn't yet provide any 3D support hooks. Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_cp.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_cp.c188
1 files changed, 141 insertions, 47 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c
index e42b6a2a7e8e..596da014dfd9 100644
--- a/drivers/gpu/drm/radeon/radeon_cp.c
+++ b/drivers/gpu/drm/radeon/radeon_cp.c
@@ -43,7 +43,7 @@
43static int radeon_do_cleanup_cp(struct drm_device * dev); 43static int radeon_do_cleanup_cp(struct drm_device * dev);
44static void radeon_do_cp_start(drm_radeon_private_t * dev_priv); 44static void radeon_do_cp_start(drm_radeon_private_t * dev_priv);
45 45
46static u32 radeon_read_ring_rptr(drm_radeon_private_t *dev_priv, u32 off) 46u32 radeon_read_ring_rptr(drm_radeon_private_t *dev_priv, u32 off)
47{ 47{
48 u32 val; 48 u32 val;
49 49
@@ -62,11 +62,15 @@ u32 radeon_get_ring_head(drm_radeon_private_t *dev_priv)
62{ 62{
63 if (dev_priv->writeback_works) 63 if (dev_priv->writeback_works)
64 return radeon_read_ring_rptr(dev_priv, 0); 64 return radeon_read_ring_rptr(dev_priv, 0);
65 else 65 else {
66 return RADEON_READ(RADEON_CP_RB_RPTR); 66 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
67 return RADEON_READ(R600_CP_RB_RPTR);
68 else
69 return RADEON_READ(RADEON_CP_RB_RPTR);
70 }
67} 71}
68 72
69static void radeon_write_ring_rptr(drm_radeon_private_t *dev_priv, u32 off, u32 val) 73void radeon_write_ring_rptr(drm_radeon_private_t *dev_priv, u32 off, u32 val)
70{ 74{
71 if (dev_priv->flags & RADEON_IS_AGP) 75 if (dev_priv->flags & RADEON_IS_AGP)
72 DRM_WRITE32(dev_priv->ring_rptr, off, val); 76 DRM_WRITE32(dev_priv->ring_rptr, off, val);
@@ -82,11 +86,19 @@ void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val)
82 86
83u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index) 87u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index)
84{ 88{
85 if (dev_priv->writeback_works) 89 if (dev_priv->writeback_works) {
86 return radeon_read_ring_rptr(dev_priv, 90 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
87 RADEON_SCRATCHOFF(index)); 91 return radeon_read_ring_rptr(dev_priv,
88 else 92 R600_SCRATCHOFF(index));
89 return RADEON_READ(RADEON_SCRATCH_REG0 + 4*index); 93 else
94 return radeon_read_ring_rptr(dev_priv,
95 RADEON_SCRATCHOFF(index));
96 } else {
97 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
98 return RADEON_READ(R600_SCRATCH_REG0 + 4*index);
99 else
100 return RADEON_READ(RADEON_SCRATCH_REG0 + 4*index);
101 }
90} 102}
91 103
92u32 RADEON_READ_MM(drm_radeon_private_t *dev_priv, int addr) 104u32 RADEON_READ_MM(drm_radeon_private_t *dev_priv, int addr)
@@ -142,7 +154,11 @@ static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
142u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) 154u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
143{ 155{
144 156
145 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) 157 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)
158 return RADEON_READ(R700_MC_VM_FB_LOCATION);
159 else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
160 return RADEON_READ(R600_MC_VM_FB_LOCATION);
161 else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
146 return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); 162 return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION);
147 else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || 163 else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
148 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) 164 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
@@ -155,7 +171,11 @@ u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
155 171
156static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) 172static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
157{ 173{
158 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) 174 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)
175 RADEON_WRITE(R700_MC_VM_FB_LOCATION, fb_loc);
176 else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
177 RADEON_WRITE(R600_MC_VM_FB_LOCATION, fb_loc);
178 else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
159 R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); 179 R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc);
160 else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || 180 else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
161 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) 181 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
@@ -166,9 +186,16 @@ static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
166 RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc); 186 RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc);
167} 187}
168 188
169static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc) 189void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc)
170{ 190{
171 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) 191 /*R6xx/R7xx: AGP_TOP and BOT are actually 18 bits each */
192 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) {
193 RADEON_WRITE(R700_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */
194 RADEON_WRITE(R700_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff);
195 } else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
196 RADEON_WRITE(R600_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */
197 RADEON_WRITE(R600_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff);
198 } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
172 R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); 199 R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc);
173 else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || 200 else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
174 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) 201 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
@@ -179,12 +206,18 @@ static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_lo
179 RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc); 206 RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc);
180} 207}
181 208
182static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) 209void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base)
183{ 210{
184 u32 agp_base_hi = upper_32_bits(agp_base); 211 u32 agp_base_hi = upper_32_bits(agp_base);
185 u32 agp_base_lo = agp_base & 0xffffffff; 212 u32 agp_base_lo = agp_base & 0xffffffff;
186 213 u32 r6xx_agp_base = (agp_base >> 22) & 0x3ffff;
187 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) { 214
215 /* R6xx/R7xx must be aligned to a 4MB boundry */
216 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)
217 RADEON_WRITE(R700_MC_VM_AGP_BASE, r6xx_agp_base);
218 else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
219 RADEON_WRITE(R600_MC_VM_AGP_BASE, r6xx_agp_base);
220 else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) {
188 R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo); 221 R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo);
189 R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi); 222 R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi);
190 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || 223 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
@@ -205,7 +238,7 @@ static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base)
205 } 238 }
206} 239}
207 240
208static void radeon_enable_bm(struct drm_radeon_private *dev_priv) 241void radeon_enable_bm(struct drm_radeon_private *dev_priv)
209{ 242{
210 u32 tmp; 243 u32 tmp;
211 /* Turn on bus mastering */ 244 /* Turn on bus mastering */
@@ -1440,6 +1473,7 @@ static int radeon_do_resume_cp(struct drm_device *dev, struct drm_file *file_pri
1440 1473
1441int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv) 1474int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
1442{ 1475{
1476 drm_radeon_private_t *dev_priv = dev->dev_private;
1443 drm_radeon_init_t *init = data; 1477 drm_radeon_init_t *init = data;
1444 1478
1445 LOCK_TEST_WITH_RETURN(dev, file_priv); 1479 LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -1452,8 +1486,13 @@ int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_pri
1452 case RADEON_INIT_R200_CP: 1486 case RADEON_INIT_R200_CP:
1453 case RADEON_INIT_R300_CP: 1487 case RADEON_INIT_R300_CP:
1454 return radeon_do_init_cp(dev, init, file_priv); 1488 return radeon_do_init_cp(dev, init, file_priv);
1489 case RADEON_INIT_R600_CP:
1490 return r600_do_init_cp(dev, init, file_priv);
1455 case RADEON_CLEANUP_CP: 1491 case RADEON_CLEANUP_CP:
1456 return radeon_do_cleanup_cp(dev); 1492 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
1493 return r600_do_cleanup_cp(dev);
1494 else
1495 return radeon_do_cleanup_cp(dev);
1457 } 1496 }
1458 1497
1459 return -EINVAL; 1498 return -EINVAL;
@@ -1476,7 +1515,10 @@ int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_pr
1476 return 0; 1515 return 0;
1477 } 1516 }
1478 1517
1479 radeon_do_cp_start(dev_priv); 1518 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
1519 r600_do_cp_start(dev_priv);
1520 else
1521 radeon_do_cp_start(dev_priv);
1480 1522
1481 return 0; 1523 return 0;
1482} 1524}
@@ -1507,7 +1549,10 @@ int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_pri
1507 * code so that the DRM ioctl wrapper can try again. 1549 * code so that the DRM ioctl wrapper can try again.
1508 */ 1550 */
1509 if (stop->idle) { 1551 if (stop->idle) {
1510 ret = radeon_do_cp_idle(dev_priv); 1552 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
1553 ret = r600_do_cp_idle(dev_priv);
1554 else
1555 ret = radeon_do_cp_idle(dev_priv);
1511 if (ret) 1556 if (ret)
1512 return ret; 1557 return ret;
1513 } 1558 }
@@ -1516,10 +1561,16 @@ int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_pri
1516 * we will get some dropped triangles as they won't be fully 1561 * we will get some dropped triangles as they won't be fully
1517 * rendered before the CP is shut down. 1562 * rendered before the CP is shut down.
1518 */ 1563 */
1519 radeon_do_cp_stop(dev_priv); 1564 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
1565 r600_do_cp_stop(dev_priv);
1566 else
1567 radeon_do_cp_stop(dev_priv);
1520 1568
1521 /* Reset the engine */ 1569 /* Reset the engine */
1522 radeon_do_engine_reset(dev); 1570 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
1571 r600_do_engine_reset(dev);
1572 else
1573 radeon_do_engine_reset(dev);
1523 1574
1524 return 0; 1575 return 0;
1525} 1576}
@@ -1532,29 +1583,47 @@ void radeon_do_release(struct drm_device * dev)
1532 if (dev_priv) { 1583 if (dev_priv) {
1533 if (dev_priv->cp_running) { 1584 if (dev_priv->cp_running) {
1534 /* Stop the cp */ 1585 /* Stop the cp */
1535 while ((ret = radeon_do_cp_idle(dev_priv)) != 0) { 1586 if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_R600) {
1536 DRM_DEBUG("radeon_do_cp_idle %d\n", ret); 1587 while ((ret = r600_do_cp_idle(dev_priv)) != 0) {
1588 DRM_DEBUG("radeon_do_cp_idle %d\n", ret);
1537#ifdef __linux__ 1589#ifdef __linux__
1538 schedule(); 1590 schedule();
1539#else 1591#else
1540 tsleep(&ret, PZERO, "rdnrel", 1); 1592 tsleep(&ret, PZERO, "rdnrel", 1);
1541#endif 1593#endif
1594 }
1595 } else {
1596 while ((ret = radeon_do_cp_idle(dev_priv)) != 0) {
1597 DRM_DEBUG("radeon_do_cp_idle %d\n", ret);
1598#ifdef __linux__
1599 schedule();
1600#else
1601 tsleep(&ret, PZERO, "rdnrel", 1);
1602#endif
1603 }
1604 }
1605 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
1606 r600_do_cp_stop(dev_priv);
1607 r600_do_engine_reset(dev);
1608 } else {
1609 radeon_do_cp_stop(dev_priv);
1610 radeon_do_engine_reset(dev);
1542 } 1611 }
1543 radeon_do_cp_stop(dev_priv);
1544 radeon_do_engine_reset(dev);
1545 } 1612 }
1546 1613
1547 /* Disable *all* interrupts */ 1614 if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_R600) {
1548 if (dev_priv->mmio) /* remove this after permanent addmaps */ 1615 /* Disable *all* interrupts */
1549 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); 1616 if (dev_priv->mmio) /* remove this after permanent addmaps */
1550 1617 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
1551 if (dev_priv->mmio) { /* remove all surfaces */ 1618
1552 for (i = 0; i < RADEON_MAX_SURFACES; i++) { 1619 if (dev_priv->mmio) { /* remove all surfaces */
1553 RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0); 1620 for (i = 0; i < RADEON_MAX_SURFACES; i++) {
1554 RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 1621 RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0);
1555 16 * i, 0); 1622 RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND +
1556 RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 1623 16 * i, 0);
1557 16 * i, 0); 1624 RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND +
1625 16 * i, 0);
1626 }
1558 } 1627 }
1559 } 1628 }
1560 1629
@@ -1563,7 +1632,10 @@ void radeon_do_release(struct drm_device * dev)
1563 radeon_mem_takedown(&(dev_priv->fb_heap)); 1632 radeon_mem_takedown(&(dev_priv->fb_heap));
1564 1633
1565 /* deallocate kernel resources */ 1634 /* deallocate kernel resources */
1566 radeon_do_cleanup_cp(dev); 1635 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
1636 r600_do_cleanup_cp(dev);
1637 else
1638 radeon_do_cleanup_cp(dev);
1567 } 1639 }
1568} 1640}
1569 1641
@@ -1581,7 +1653,10 @@ int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_pr
1581 return -EINVAL; 1653 return -EINVAL;
1582 } 1654 }
1583 1655
1584 radeon_do_cp_reset(dev_priv); 1656 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
1657 r600_do_cp_reset(dev_priv);
1658 else
1659 radeon_do_cp_reset(dev_priv);
1585 1660
1586 /* The CP is no longer running after an engine reset */ 1661 /* The CP is no longer running after an engine reset */
1587 dev_priv->cp_running = 0; 1662 dev_priv->cp_running = 0;
@@ -1596,23 +1671,36 @@ int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_pri
1596 1671
1597 LOCK_TEST_WITH_RETURN(dev, file_priv); 1672 LOCK_TEST_WITH_RETURN(dev, file_priv);
1598 1673
1599 return radeon_do_cp_idle(dev_priv); 1674 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
1675 return r600_do_cp_idle(dev_priv);
1676 else
1677 return radeon_do_cp_idle(dev_priv);
1600} 1678}
1601 1679
1602/* Added by Charl P. Botha to call radeon_do_resume_cp(). 1680/* Added by Charl P. Botha to call radeon_do_resume_cp().
1603 */ 1681 */
1604int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv) 1682int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv)
1605{ 1683{
1606 return radeon_do_resume_cp(dev, file_priv); 1684 drm_radeon_private_t *dev_priv = dev->dev_private;
1685 DRM_DEBUG("\n");
1686
1687 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
1688 return r600_do_resume_cp(dev, file_priv);
1689 else
1690 return radeon_do_resume_cp(dev, file_priv);
1607} 1691}
1608 1692
1609int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) 1693int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv)
1610{ 1694{
1695 drm_radeon_private_t *dev_priv = dev->dev_private;
1611 DRM_DEBUG("\n"); 1696 DRM_DEBUG("\n");
1612 1697
1613 LOCK_TEST_WITH_RETURN(dev, file_priv); 1698 LOCK_TEST_WITH_RETURN(dev, file_priv);
1614 1699
1615 return radeon_do_engine_reset(dev); 1700 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
1701 return r600_do_engine_reset(dev);
1702 else
1703 return radeon_do_engine_reset(dev);
1616} 1704}
1617 1705
1618/* ================================================================ 1706/* ================================================================
@@ -1997,7 +2085,13 @@ void radeon_commit_ring(drm_radeon_private_t *dev_priv)
1997 DRM_MEMORYBARRIER(); 2085 DRM_MEMORYBARRIER();
1998 GET_RING_HEAD( dev_priv ); 2086 GET_RING_HEAD( dev_priv );
1999 2087
2000 RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); 2088 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
2001 /* read from PCI bus to ensure correct posting */ 2089 RADEON_WRITE(R600_CP_RB_WPTR, dev_priv->ring.tail);
2002 RADEON_READ( RADEON_CP_RB_RPTR ); 2090 /* read from PCI bus to ensure correct posting */
2091 RADEON_READ(R600_CP_RB_RPTR);
2092 } else {
2093 RADEON_WRITE(RADEON_CP_RB_WPTR, dev_priv->ring.tail);
2094 /* read from PCI bus to ensure correct posting */
2095 RADEON_READ(RADEON_CP_RB_RPTR);
2096 }
2003} 2097}