diff options
author | Dave Airlie <airlied@redhat.com> | 2008-02-07 00:01:05 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2008-02-07 00:13:40 -0500 |
commit | 3d5e2c13b13468f5eb2ac9323690af7e17f195fe (patch) | |
tree | c282c2a8413ca5096877360d86402df08bec6b3a /drivers/char/drm/radeon_cp.c | |
parent | 576cc458a64673ecf3fa7f1bab751e52fd939071 (diff) |
drm: add initial r500 drm support
This adds CP support for the r500 series of chips, and allows
accel 2D support on these chips with a new radeon driver.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/char/drm/radeon_cp.c')
-rw-r--r-- | drivers/char/drm/radeon_cp.c | 135 |
1 files changed, 90 insertions, 45 deletions
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index 020323bd1626..5dc799ab86b8 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c | |||
@@ -816,6 +816,46 @@ static const u32 R300_cp_microcode[][2] = { | |||
816 | {0000000000, 0000000000}, | 816 | {0000000000, 0000000000}, |
817 | }; | 817 | }; |
818 | 818 | ||
819 | static u32 RADEON_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) | ||
820 | { | ||
821 | u32 ret; | ||
822 | RADEON_WRITE(R520_MC_IND_INDEX, 0x7f0000 | (addr & 0xff)); | ||
823 | ret = RADEON_READ(R520_MC_IND_DATA); | ||
824 | RADEON_WRITE(R520_MC_IND_INDEX, 0); | ||
825 | return ret; | ||
826 | } | ||
827 | |||
828 | u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) | ||
829 | { | ||
830 | |||
831 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) | ||
832 | return RADEON_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); | ||
833 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) | ||
834 | return RADEON_READ_MCIND(dev_priv, R520_MC_FB_LOCATION); | ||
835 | else | ||
836 | return RADEON_READ(RADEON_MC_FB_LOCATION); | ||
837 | } | ||
838 | |||
839 | static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) | ||
840 | { | ||
841 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) | ||
842 | RADEON_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); | ||
843 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) | ||
844 | RADEON_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc); | ||
845 | else | ||
846 | RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc); | ||
847 | } | ||
848 | |||
849 | static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc) | ||
850 | { | ||
851 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) | ||
852 | RADEON_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); | ||
853 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) | ||
854 | RADEON_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc); | ||
855 | else | ||
856 | RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc); | ||
857 | } | ||
858 | |||
819 | static int RADEON_READ_PLL(struct drm_device * dev, int addr) | 859 | static int RADEON_READ_PLL(struct drm_device * dev, int addr) |
820 | { | 860 | { |
821 | drm_radeon_private_t *dev_priv = dev->dev_private; | 861 | drm_radeon_private_t *dev_priv = dev->dev_private; |
@@ -824,7 +864,7 @@ static int RADEON_READ_PLL(struct drm_device * dev, int addr) | |||
824 | return RADEON_READ(RADEON_CLOCK_CNTL_DATA); | 864 | return RADEON_READ(RADEON_CLOCK_CNTL_DATA); |
825 | } | 865 | } |
826 | 866 | ||
827 | static int RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) | 867 | static u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) |
828 | { | 868 | { |
829 | RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff); | 869 | RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff); |
830 | return RADEON_READ(RADEON_PCIE_DATA); | 870 | return RADEON_READ(RADEON_PCIE_DATA); |
@@ -1074,41 +1114,43 @@ static int radeon_do_engine_reset(struct drm_device * dev) | |||
1074 | 1114 | ||
1075 | radeon_do_pixcache_flush(dev_priv); | 1115 | radeon_do_pixcache_flush(dev_priv); |
1076 | 1116 | ||
1077 | clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX); | 1117 | if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV515) { |
1078 | mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL); | 1118 | clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX); |
1079 | 1119 | mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL); | |
1080 | RADEON_WRITE_PLL(RADEON_MCLK_CNTL, (mclk_cntl | | 1120 | |
1081 | RADEON_FORCEON_MCLKA | | 1121 | RADEON_WRITE_PLL(RADEON_MCLK_CNTL, (mclk_cntl | |
1082 | RADEON_FORCEON_MCLKB | | 1122 | RADEON_FORCEON_MCLKA | |
1083 | RADEON_FORCEON_YCLKA | | 1123 | RADEON_FORCEON_MCLKB | |
1084 | RADEON_FORCEON_YCLKB | | 1124 | RADEON_FORCEON_YCLKA | |
1085 | RADEON_FORCEON_MC | | 1125 | RADEON_FORCEON_YCLKB | |
1086 | RADEON_FORCEON_AIC)); | 1126 | RADEON_FORCEON_MC | |
1087 | 1127 | RADEON_FORCEON_AIC)); | |
1088 | rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET); | 1128 | |
1089 | 1129 | rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET); | |
1090 | RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset | | 1130 | |
1091 | RADEON_SOFT_RESET_CP | | 1131 | RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset | |
1092 | RADEON_SOFT_RESET_HI | | 1132 | RADEON_SOFT_RESET_CP | |
1093 | RADEON_SOFT_RESET_SE | | 1133 | RADEON_SOFT_RESET_HI | |
1094 | RADEON_SOFT_RESET_RE | | 1134 | RADEON_SOFT_RESET_SE | |
1095 | RADEON_SOFT_RESET_PP | | 1135 | RADEON_SOFT_RESET_RE | |
1096 | RADEON_SOFT_RESET_E2 | | 1136 | RADEON_SOFT_RESET_PP | |
1097 | RADEON_SOFT_RESET_RB)); | 1137 | RADEON_SOFT_RESET_E2 | |
1098 | RADEON_READ(RADEON_RBBM_SOFT_RESET); | 1138 | RADEON_SOFT_RESET_RB)); |
1099 | RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset & | 1139 | RADEON_READ(RADEON_RBBM_SOFT_RESET); |
1100 | ~(RADEON_SOFT_RESET_CP | | 1140 | RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset & |
1101 | RADEON_SOFT_RESET_HI | | 1141 | ~(RADEON_SOFT_RESET_CP | |
1102 | RADEON_SOFT_RESET_SE | | 1142 | RADEON_SOFT_RESET_HI | |
1103 | RADEON_SOFT_RESET_RE | | 1143 | RADEON_SOFT_RESET_SE | |
1104 | RADEON_SOFT_RESET_PP | | 1144 | RADEON_SOFT_RESET_RE | |
1105 | RADEON_SOFT_RESET_E2 | | 1145 | RADEON_SOFT_RESET_PP | |
1106 | RADEON_SOFT_RESET_RB))); | 1146 | RADEON_SOFT_RESET_E2 | |
1107 | RADEON_READ(RADEON_RBBM_SOFT_RESET); | 1147 | RADEON_SOFT_RESET_RB))); |
1108 | 1148 | RADEON_READ(RADEON_RBBM_SOFT_RESET); | |
1109 | RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl); | 1149 | |
1110 | RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index); | 1150 | RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl); |
1111 | RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset); | 1151 | RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index); |
1152 | RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset); | ||
1153 | } | ||
1112 | 1154 | ||
1113 | /* Reset the CP ring */ | 1155 | /* Reset the CP ring */ |
1114 | radeon_do_cp_reset(dev_priv); | 1156 | radeon_do_cp_reset(dev_priv); |
@@ -1134,14 +1176,14 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, | |||
1134 | * always appended to the fb which is not necessarily the case | 1176 | * always appended to the fb which is not necessarily the case |
1135 | */ | 1177 | */ |
1136 | if (!dev_priv->new_memmap) | 1178 | if (!dev_priv->new_memmap) |
1137 | RADEON_WRITE(RADEON_MC_FB_LOCATION, | 1179 | radeon_write_fb_location(dev_priv, |
1138 | ((dev_priv->gart_vm_start - 1) & 0xffff0000) | 1180 | ((dev_priv->gart_vm_start - 1) & 0xffff0000) |
1139 | | (dev_priv->fb_location >> 16)); | 1181 | | (dev_priv->fb_location >> 16)); |
1140 | 1182 | ||
1141 | #if __OS_HAS_AGP | 1183 | #if __OS_HAS_AGP |
1142 | if (dev_priv->flags & RADEON_IS_AGP) { | 1184 | if (dev_priv->flags & RADEON_IS_AGP) { |
1143 | RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base); | 1185 | RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base); |
1144 | RADEON_WRITE(RADEON_MC_AGP_LOCATION, | 1186 | radeon_write_agp_location(dev_priv, |
1145 | (((dev_priv->gart_vm_start - 1 + | 1187 | (((dev_priv->gart_vm_start - 1 + |
1146 | dev_priv->gart_size) & 0xffff0000) | | 1188 | dev_priv->gart_size) & 0xffff0000) | |
1147 | (dev_priv->gart_vm_start >> 16))); | 1189 | (dev_priv->gart_vm_start >> 16))); |
@@ -1305,7 +1347,7 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on) | |||
1305 | 1347 | ||
1306 | RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev_priv->gart_vm_start); | 1348 | RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev_priv->gart_vm_start); |
1307 | dev_priv->gart_size = 32*1024*1024; | 1349 | dev_priv->gart_size = 32*1024*1024; |
1308 | RADEON_WRITE(RADEON_MC_AGP_LOCATION, | 1350 | radeon_write_agp_location(dev_priv, |
1309 | (((dev_priv->gart_vm_start - 1 + | 1351 | (((dev_priv->gart_vm_start - 1 + |
1310 | dev_priv->gart_size) & 0xffff0000) | | 1352 | dev_priv->gart_size) & 0xffff0000) | |
1311 | (dev_priv->gart_vm_start >> 16))); | 1353 | (dev_priv->gart_vm_start >> 16))); |
@@ -1339,7 +1381,7 @@ static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) | |||
1339 | dev_priv->gart_vm_start + | 1381 | dev_priv->gart_vm_start + |
1340 | dev_priv->gart_size - 1); | 1382 | dev_priv->gart_size - 1); |
1341 | 1383 | ||
1342 | RADEON_WRITE(RADEON_MC_AGP_LOCATION, 0xffffffc0); /* ?? */ | 1384 | radeon_write_agp_location(dev_priv, 0xffffffc0); /* ?? */ |
1343 | 1385 | ||
1344 | RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, | 1386 | RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, |
1345 | RADEON_PCIE_TX_GART_EN); | 1387 | RADEON_PCIE_TX_GART_EN); |
@@ -1382,7 +1424,7 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) | |||
1382 | 1424 | ||
1383 | /* Turn off AGP aperture -- is this required for PCI GART? | 1425 | /* Turn off AGP aperture -- is this required for PCI GART? |
1384 | */ | 1426 | */ |
1385 | RADEON_WRITE(RADEON_MC_AGP_LOCATION, 0xffffffc0); /* ?? */ | 1427 | radeon_write_agp_location(dev_priv, 0xffffffc0); |
1386 | RADEON_WRITE(RADEON_AGP_COMMAND, 0); /* clear AGP_COMMAND */ | 1428 | RADEON_WRITE(RADEON_AGP_COMMAND, 0); /* clear AGP_COMMAND */ |
1387 | } else { | 1429 | } else { |
1388 | RADEON_WRITE(RADEON_AIC_CNTL, | 1430 | RADEON_WRITE(RADEON_AIC_CNTL, |
@@ -1587,10 +1629,9 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) | |||
1587 | dev->agp_buffer_map->handle); | 1629 | dev->agp_buffer_map->handle); |
1588 | } | 1630 | } |
1589 | 1631 | ||
1590 | dev_priv->fb_location = (RADEON_READ(RADEON_MC_FB_LOCATION) | 1632 | dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 16; |
1591 | & 0xffff) << 16; | ||
1592 | dev_priv->fb_size = | 1633 | dev_priv->fb_size = |
1593 | ((RADEON_READ(RADEON_MC_FB_LOCATION) & 0xffff0000u) + 0x10000) | 1634 | ((radeon_read_fb_location(dev_priv) & 0xffff0000u) + 0x10000) |
1594 | - dev_priv->fb_location; | 1635 | - dev_priv->fb_location; |
1595 | 1636 | ||
1596 | dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) | | 1637 | dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) | |
@@ -1841,7 +1882,7 @@ int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_pri | |||
1841 | LOCK_TEST_WITH_RETURN(dev, file_priv); | 1882 | LOCK_TEST_WITH_RETURN(dev, file_priv); |
1842 | 1883 | ||
1843 | if (init->func == RADEON_INIT_R300_CP) | 1884 | if (init->func == RADEON_INIT_R300_CP) |
1844 | r300_init_reg_flags(); | 1885 | r300_init_reg_flags(dev); |
1845 | 1886 | ||
1846 | switch (init->func) { | 1887 | switch (init->func) { |
1847 | case RADEON_INIT_CP: | 1888 | case RADEON_INIT_CP: |
@@ -2250,6 +2291,10 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) | |||
2250 | case CHIP_R350: | 2291 | case CHIP_R350: |
2251 | case CHIP_R420: | 2292 | case CHIP_R420: |
2252 | case CHIP_RV410: | 2293 | case CHIP_RV410: |
2294 | case CHIP_RV515: | ||
2295 | case CHIP_R520: | ||
2296 | case CHIP_RV570: | ||
2297 | case CHIP_R580: | ||
2253 | dev_priv->flags |= RADEON_HAS_HIERZ; | 2298 | dev_priv->flags |= RADEON_HAS_HIERZ; |
2254 | break; | 2299 | break; |
2255 | default: | 2300 | default: |