diff options
Diffstat (limited to 'src/radeon_reg.c')
-rw-r--r-- | src/radeon_reg.c | 88 |
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)); |