#include #include #include #include #include #include #include #include #include "voodoo2.h" #include "voodoo2_bits.h" #include "voodoo2_config.h" #include "dac.h" struct name_int { const char * name; uint32_t value; }; void print_registers(struct voodoo2_reg * reg) { const struct name_int registers[] = { {"status", reg->status}, {"fbiInit0", reg->fbiInit0}, {"fbiInit1", reg->fbiInit1}, {"fbiInit2", reg->fbiInit2}, {"fbiInit3", reg->fbiInit3}, {"fbiInit4", reg->fbiInit4}, {"fbiInit5", reg->fbiInit5}, {"fbiInit6", reg->fbiInit6}, {"fbiInit7", reg->fbiInit7}, // {"backPorch", reg->backPorch}, {"videoDimensions", reg->videoDimensions}, {"hSync", reg->hSync}, {"vSync", reg->vSync}, }; for (int i = 0; i < (sizeof (registers)) / (sizeof (registers[0])); i++) { printf("%s %08x\n", registers[i].name, registers[i].value); } } static inline void wait_graphics_busy(voodoo2_reg * voodoo2) { int cnt = 0; for (int i = 0; i < 4096; i++) { if (voodoo2->status & STATUS__GRAPHICS_BUSY) { cnt += 1; } else { cnt = 0; } if (cnt >= 3) return; } assert(!"busy wait timeout"); } static inline void dac_data_read(voodoo2_reg * voodoo2, int data, int rs) { voodoo2->dacData = DACDATA__WRITE_DATA(data) | DACDATA__ADDRESS_2_0(rs >> 0) | DACDATA__READ_COMMAND | DACDATA__ADDRESS_4_3(rs >> 3) ; } static inline void dac_data_write(voodoo2_reg * voodoo2, int data, int rs) { voodoo2->dacData = DACDATA__WRITE_DATA(data) | DACDATA__ADDRESS_2_0(rs >> 0) | DACDATA__ADDRESS_4_3(rs >> 3) ; } static inline void dac_write_pll_8(voodoo2_reg * voodoo2, int address, int parameter_m) { dac_data_write(voodoo2, address, DAC__RS__PLL_ADDRESS_WRITE); wait_graphics_busy(voodoo2); dac_data_write(voodoo2, parameter_m, DAC__RS__PLL_PARAMETER); wait_graphics_busy(voodoo2); } static inline void dac_write_pll_16(voodoo2_reg * voodoo2, int address, int parameter_m, int parameter_n) { dac_data_write(voodoo2, address, DAC__RS__PLL_ADDRESS_WRITE); wait_graphics_busy(voodoo2); dac_data_write(voodoo2, parameter_m, DAC__RS__PLL_PARAMETER); wait_graphics_busy(voodoo2); dac_data_write(voodoo2, parameter_n, DAC__RS__PLL_PARAMETER); wait_graphics_busy(voodoo2); } typedef struct mn { uint8_t m; uint8_t n; } mn_t; static inline mn_t dac_read_pll_16(voodoo2_reg * voodoo2, int address) { dac_data_write(voodoo2, address, DAC__RS__PLL_ADDRESS_READ); wait_graphics_busy(voodoo2); dac_data_read(voodoo2, 0, DAC__RS__PLL_PARAMETER); wait_graphics_busy(voodoo2); int m = voodoo2->fbiInit2 & 0xff; dac_data_read(voodoo2, 0, DAC__RS__PLL_PARAMETER); wait_graphics_busy(voodoo2); int n = voodoo2->fbiInit2 & 0xff; return (mn_t){ m, n }; } int main() { const char * config_path = "/sys/bus/pci/devices/0000:02:0a.0/config"; int fd = open(config_path, O_RDWR | O_SYNC); assert(fd >= 0); uint32_t config_size = (sizeof (struct voodoo2_config)); void * config_base = mmap(0, config_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); assert(config_base != MAP_FAILED); voodoo2_config * config = (voodoo2_config *)config_base; printf("Vendor ID: %04x\n", config->Vendor_ID); printf("Device ID: %04x\n", config->Device_ID); munmap(config_base, config_size); close(fd); return 0; /* const char * filename = "/sys/bus/pci/devices/0000:02:0a.0/resource0"; int fd = open(filename, O_RDWR | O_SYNC); assert(fd >= 0); uint32_t map_size = 0x4000; void * map_base = mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); assert(map_base != MAP_FAILED); struct voodoo2_reg * reg = (struct voodoo2_reg *)map_base; print_registers(reg); close(fd); */ }