summaryrefslogtreecommitdiff
path: root/src/radeon_reg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/radeon_reg.c')
-rw-r--r--src/radeon_reg.c88
1 files changed, 76 insertions, 12 deletions
diff --git a/src/radeon_reg.c b/src/radeon_reg.c
index 781794b..a2aef70 100644
--- a/src/radeon_reg.c
+++ b/src/radeon_reg.c
@@ -24,6 +24,7 @@
* Jerome Glisse
*/
#include <string.h>
+#include <unistd.h>
#include "radeon_priv.h"
#include "radeon_reg.h"
@@ -41,6 +42,20 @@ void radeon_register_dump(const char *bname)
return;
}
switch (radeon->family) {
+ case CHIP_R100:
+ case CHIP_RV100:
+ case CHIP_RS100:
+ case CHIP_RV200:
+ case CHIP_RS200:
+ case CHIP_R200:
+ case CHIP_RV250:
+ case CHIP_RS300:
+ case CHIP_RV280:
+ block = r100_block;
+ reg = r100_reg;
+ nblock = r100_nblock;
+ nreg = r100_nreg;
+ break;
case CHIP_RS600:
block = rs600_block;
reg = rs600_reg;
@@ -59,15 +74,6 @@ void radeon_register_dump(const char *bname)
case CHIP_RV730:
case CHIP_RV710:
case CHIP_RV740:
- case CHIP_R100:
- case CHIP_RV100:
- case CHIP_RS100:
- case CHIP_RV200:
- case CHIP_RS200:
- case CHIP_R200:
- case CHIP_RV250:
- case CHIP_RS300:
- case CHIP_RV280:
case CHIP_R300:
case CHIP_R350:
case CHIP_RV350:
@@ -104,17 +110,74 @@ void radeon_register_dump(const char *bname)
fprintf(stderr, "%s unknown block %s for chipset 0x%04X\n",
__func__, bname, radeon->device);
}
+ bid = 1 << bid;
}
for (i = 0; i < nreg; i++) {
- if ((bname && reg[i].block_id == bid) || bname == NULL) {
- bid = reg[i].block_id;
- printf("%s 0x%08X 0x%08X %s\n", block[bid].name, reg[i].offset,
+ if ((bname && reg[i].block_id & bid) || bname == NULL) {
+ printf("0x%08X 0x%08X %s\n", reg[i].offset,
reg[i].rreg(radeon, reg[i].offset), reg[i].name);
}
}
radeon_decref(radeon);
}
+/* R100 */
+u32 r100_MMIO_rreg(struct radeon *radeon, u32 offset)
+{
+ return radeon_mmio_rd32(radeon, offset);
+}
+
+void r100_MMIO_wreg(struct radeon *radeon, u32 offset, u32 value)
+{
+ radeon_mmio_wr32(radeon, offset, value);
+}
+
+void r100_pll_errata_after_index(struct radeon *radeon)
+{
+ if (radeon->family == CHIP_RV200 || radeon->family == CHIP_RS200) {
+ (void)radeon_mmio_rd32(radeon, 0x000C);
+ (void)radeon_mmio_rd32(radeon, 0x0050);
+ }
+}
+
+static void r100_pll_errata_after_data(struct radeon *radeon)
+{
+ /* This workarounds is necessary on RV100, RS100 and RS200 chips
+ * or the chip could hang on a subsequent access
+ */
+ if (radeon->family == CHIP_RV100 || radeon->family == CHIP_RS100 ||
+ radeon->family == CHIP_RS200) {
+ sleep(1);
+ }
+
+ /* This function is required to workaround a hardware bug in some (all?)
+ * revisions of the R300. This workaround should be called after every
+ * CLOCK_CNTL_INDEX register access. If not, register reads afterward
+ * may not be correct.
+ */
+ if (radeon->family == CHIP_R300) {
+ u32 save, tmp;
+
+ save = radeon_mmio_rd32(radeon, 0x0008);
+ tmp = save & ~(0x3f | (1 << 7));
+ radeon_mmio_wr32(radeon, 0x0008, tmp);
+ tmp = radeon_mmio_rd32(radeon, 0x000C);
+ radeon_mmio_wr32(radeon, 0x0008, save);
+ }
+}
+
+u32 r100_CLK_rreg(struct radeon *radeon, u32 offset)
+{
+ return radeon_mmio_rd32(radeon, offset);
+}
+
+void r100_CLK_wreg(struct radeon *radeon, u32 offset, u32 value)
+{
+ radeon_mmio_wr8(radeon, 0x0008, ((offset & 0x3f) | (1 << 7)));
+ r100_pll_errata_after_index(radeon);
+ radeon_mmio_wr32(radeon, 0x000C, value);
+ r100_pll_errata_after_data(radeon);
+}
/* RS600 */
u32 rs600_MMIO_rreg(struct radeon *radeon, u32 offset)
@@ -127,6 +190,7 @@ void rs600_MMIO_wreg(struct radeon *radeon, u32 offset, u32 value)
radeon_mmio_wr32(radeon, offset, value);
}
+
u32 rs600_MC_rreg(struct radeon *radeon, u32 offset)
{
radeon_mmio_wr32(radeon, 0x0070, (offset & 0xFFFF) | (1 << 21));