/* Radeontool v1.4 * by Frederick Dean * Copyright 2002-2004 Frederick Dean * Use hereby granted under the zlib license. * * Warning: I do not have the Radeon documents, so this was engineered from * the radeon_reg.h header file. * * USE RADEONTOOL AT YOUR OWN RISK * * Thanks to Deepak Chawla, Erno Kuusela, Rolf Offermanns, and Soos Peter * for patches. */ #include #include #include #include #include #include #include #include #include #include #include "radeon_reg.h" int debug; int skip; /* *radeon_cntl_mem is mapped to the actual device's memory mapped control area. */ /* Not the address but what it points to is volatile. */ unsigned char * volatile radeon_cntl_mem; static void fatal(char *why) { fprintf(stderr,why); exit (-1); } static unsigned int radeon_get(unsigned long offset, const char *name) { unsigned int value; if(debug) printf("reading %s (%lx) is ",name,offset); if(radeon_cntl_mem == NULL) { printf("internal error\n"); exit(-2); }; #ifdef __powerpc__ __asm__ __volatile__ ("lwbrx %0,%1,%2\n\t" "eieio" : "=r" (value) : "b" (radeon_cntl_mem), "r"(offset), "m" (*((volatile unsigned int *)radeon_cntl_mem+offset))); #else value = *(unsigned int * volatile)(radeon_cntl_mem+offset); #endif if(debug) printf("%08x\n",value); return value; } static void radeon_set(unsigned long offset, const char *name, unsigned int value) { if(debug) printf("writing %s (%lx) -> %08x\n",name,offset,value); if(radeon_cntl_mem == NULL) { printf("internal error\n"); exit(-2); }; #ifdef __powerpc__ __asm__ __volatile__ ("stwbrx %1,%2,%3\n\t" "eieio" : "=m" (*((volatile unsigned int *)radeon_cntl_mem+offset)) : "r"(value), "b"(radeon_cntl_mem), "r"(offset)); #else *(unsigned int * volatile)(radeon_cntl_mem+offset) = value; #endif } static void usage(void) { printf("usage: radeontool [options] [command]\n"); printf(" --debug - show a little debug info\n"); printf(" --skip=1 - use the second radeon card\n"); printf(" dac [on|off] - power down the external video outputs (%s)\n", (radeon_get(RADEON_DAC_CNTL,"RADEON_DAC_CNTL")&RADEON_DAC_PDWN)?"off":"on"); printf(" light [on|off] - power down the backlight (%s)\n", (radeon_get(RADEON_LVDS_GEN_CNTL,"RADEON_LVDS_GEN_CNTL")&RADEON_LVDS_ON)?"on":"off"); printf(" stretch [on|off|vert|horiz|auto|manual] - stretching for resolution mismatch \n"); printf(" regs - show a listing of some random registers\n"); printf(" regmatch - show registers matching wildcard pattern\n"); printf(" regset - set registers matching wildcard pattern\n"); exit(-1); } /* Ohh, life would be good if we could simply address all memory addresses */ /* with /dev/mem, then I could write this whole program in perl, */ /* but sadly this is only the size of physical RAM. If you */ /* want to be truely bad and poke into device memory you have to mmap() */ static unsigned char * map_devince_memory(unsigned int base,unsigned int length) { int mem_fd; unsigned char *device_mem; /* open /dev/mem */ if ((mem_fd = open("/dev/mem", O_RDWR) ) < 0) { fatal("can't open /dev/mem\nAre you root?\n"); } /* mmap graphics memory */ if ((device_mem = malloc(length + (getpagesize()-1))) == NULL) { fatal("allocation error \n"); } if ((unsigned long)device_mem % getpagesize()) device_mem += getpagesize() - ((unsigned long)device_mem % getpagesize()); device_mem = (unsigned char *)mmap( (caddr_t)device_mem, length, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, mem_fd, base ); if ((long)device_mem < 0) { if(debug) fprintf(stderr,"mmap returned %d\n",(int)device_mem); fatal("mmap error \n"); } return device_mem; } void radeon_cmd_regs(void) { #define SHOW_REG(r) printf("%s\t%08x\n", #r, radeon_get(r, #r)) SHOW_REG(RADEON_DAC_CNTL); SHOW_REG(RADEON_DAC_CNTL2); SHOW_REG(RADEON_TV_DAC_CNTL); SHOW_REG(RADEON_DISP_OUTPUT_CNTL); SHOW_REG(RADEON_CONFIG_MEMSIZE); SHOW_REG(RADEON_AUX_SC_CNTL); SHOW_REG(RADEON_CRTC_EXT_CNTL); SHOW_REG(RADEON_CRTC_GEN_CNTL); SHOW_REG(RADEON_CRTC2_GEN_CNTL); SHOW_REG(RADEON_DEVICE_ID); SHOW_REG(RADEON_DISP_MISC_CNTL); SHOW_REG(RADEON_GPIO_MONID); SHOW_REG(RADEON_GPIO_MONIDB); SHOW_REG(RADEON_GPIO_CRT2_DDC); SHOW_REG(RADEON_GPIO_DVI_DDC); SHOW_REG(RADEON_GPIO_VGA_DDC); SHOW_REG(RADEON_LVDS_GEN_CNTL); SHOW_REG(RADEON_FP_GEN_CNTL); SHOW_REG(RADEON_FP2_GEN_CNTL); SHOW_REG(RADEON_PIXCLKS_CNTL); } #define REGLIST(r) { #r, RADEON_ ## r } static struct { const char *name; unsigned address; } reg_list[] = { REGLIST(ADAPTER_ID), REGLIST(AGP_BASE), REGLIST(AGP_CNTL), REGLIST(AGP_COMMAND), REGLIST(AGP_STATUS), REGLIST(AMCGPIO_A_REG), REGLIST(AMCGPIO_EN_REG), REGLIST(AMCGPIO_MASK), REGLIST(AMCGPIO_Y_REG), REGLIST(ATTRDR), REGLIST(ATTRDW), REGLIST(ATTRX), REGLIST(AUX_SC_CNTL), REGLIST(AUX1_SC_BOTTOM), REGLIST(AUX1_SC_LEFT), REGLIST(AUX1_SC_RIGHT), REGLIST(AUX1_SC_TOP), REGLIST(AUX2_SC_BOTTOM), REGLIST(AUX2_SC_LEFT), REGLIST(AUX2_SC_RIGHT), REGLIST(AUX2_SC_TOP), REGLIST(AUX3_SC_BOTTOM), REGLIST(AUX3_SC_LEFT), REGLIST(AUX3_SC_RIGHT), REGLIST(AUX3_SC_TOP), REGLIST(AUX_WINDOW_HORZ_CNTL), REGLIST(AUX_WINDOW_VERT_CNTL), REGLIST(BASE_CODE), REGLIST(BIOS_0_SCRATCH), REGLIST(BIOS_1_SCRATCH), REGLIST(BIOS_2_SCRATCH), REGLIST(BIOS_3_SCRATCH), REGLIST(BIOS_4_SCRATCH), REGLIST(BIOS_5_SCRATCH), REGLIST(BIOS_6_SCRATCH), REGLIST(BIOS_7_SCRATCH), REGLIST(BIOS_ROM), REGLIST(BIST), REGLIST(BUS_CNTL), REGLIST(BUS_CNTL1), REGLIST(CACHE_CNTL), REGLIST(CACHE_LINE), REGLIST(CAP0_TRIG_CNTL), REGLIST(CAP1_TRIG_CNTL), REGLIST(CAPABILITIES_ID), REGLIST(CAPABILITIES_PTR), REGLIST(CLOCK_CNTL_DATA), REGLIST(CLOCK_CNTL_INDEX), REGLIST(CLR_CMP_CLR_3D), REGLIST(CLR_CMP_CLR_DST), REGLIST(CLR_CMP_CLR_SRC), REGLIST(CLR_CMP_CNTL), REGLIST(CLR_CMP_MASK), REGLIST(CLR_CMP_MASK_3D), REGLIST(COMMAND), REGLIST(COMPOSITE_SHADOW_ID), REGLIST(CONFIG_APER_0_BASE), REGLIST(CONFIG_APER_1_BASE), REGLIST(CONFIG_APER_SIZE), REGLIST(CONFIG_BONDS), REGLIST(CONFIG_CNTL), REGLIST(CONFIG_MEMSIZE), REGLIST(CONFIG_MEMSIZE_EMBEDDED), REGLIST(CONFIG_REG_1_BASE), REGLIST(CONFIG_REG_APER_SIZE), REGLIST(CONFIG_XSTRAP), REGLIST(CONSTANT_COLOR_C), REGLIST(CRC_CMDFIFO_ADDR), REGLIST(CRC_CMDFIFO_DOUT), REGLIST(CRTC_CRNT_FRAME), REGLIST(CRTC_DEBUG), REGLIST(CRTC_EXT_CNTL), REGLIST(CRTC_EXT_CNTL_DPMS_BYTE), REGLIST(CRTC_GEN_CNTL), REGLIST(CRTC2_GEN_CNTL), REGLIST(CRTC_GUI_TRIG_VLINE), REGLIST(CRTC_H_SYNC_STRT_WID), REGLIST(CRTC2_H_SYNC_STRT_WID), REGLIST(CRTC_H_TOTAL_DISP), REGLIST(CRTC2_H_TOTAL_DISP), REGLIST(CRTC_OFFSET), REGLIST(CRTC2_OFFSET), REGLIST(CRTC_OFFSET_CNTL), REGLIST(CRTC2_OFFSET_CNTL), REGLIST(CRTC_PITCH), REGLIST(CRTC2_PITCH), REGLIST(CRTC_STATUS), REGLIST(CRTC_V_SYNC_STRT_WID), REGLIST(CRTC2_V_SYNC_STRT_WID), REGLIST(CRTC_V_TOTAL_DISP), REGLIST(CRTC2_V_TOTAL_DISP), REGLIST(CRTC_VLINE_CRNT_VLINE), REGLIST(CRTC2_CRNT_FRAME), REGLIST(CRTC2_DEBUG), REGLIST(CRTC2_GUI_TRIG_VLINE), REGLIST(CRTC2_STATUS), REGLIST(CRTC2_VLINE_CRNT_VLINE), REGLIST(CRTC8_DATA), REGLIST(CRTC8_IDX), REGLIST(CUR_CLR0), REGLIST(CUR_CLR1), REGLIST(CUR_HORZ_VERT_OFF), REGLIST(CUR_HORZ_VERT_POSN), REGLIST(CUR_OFFSET), REGLIST(CUR2_CLR0), REGLIST(CUR2_CLR1), REGLIST(CUR2_HORZ_VERT_OFF), REGLIST(CUR2_HORZ_VERT_POSN), REGLIST(CUR2_OFFSET), REGLIST(DAC_CNTL), REGLIST(DAC_CNTL2), REGLIST(TV_DAC_CNTL), REGLIST(DISP_OUTPUT_CNTL), REGLIST(DAC_CRC_SIG), REGLIST(DAC_DATA), REGLIST(DAC_MASK), REGLIST(DAC_R_INDEX), REGLIST(DAC_W_INDEX), REGLIST(DDA_CONFIG), REGLIST(DDA_ON_OFF), REGLIST(DEFAULT_OFFSET), REGLIST(DEFAULT_PITCH), REGLIST(DEFAULT_SC_BOTTOM_RIGHT), REGLIST(DESTINATION_3D_CLR_CMP_VAL), REGLIST(DESTINATION_3D_CLR_CMP_MSK), REGLIST(DEVICE_ID), REGLIST(DISP_MISC_CNTL), REGLIST(DP_BRUSH_BKGD_CLR), REGLIST(DP_BRUSH_FRGD_CLR), REGLIST(DP_CNTL), REGLIST(DP_CNTL_XDIR_YDIR_YMAJOR), REGLIST(DP_DATATYPE), REGLIST(DP_GUI_MASTER_CNTL), REGLIST(DP_GUI_MASTER_CNTL_C), REGLIST(DP_MIX), REGLIST(DP_SRC_BKGD_CLR), REGLIST(DP_SRC_FRGD_CLR), REGLIST(DP_WRITE_MASK), REGLIST(DST_BRES_DEC), REGLIST(DST_BRES_ERR), REGLIST(DST_BRES_INC), REGLIST(DST_BRES_LNTH), REGLIST(DST_BRES_LNTH_SUB), REGLIST(DST_HEIGHT), REGLIST(DST_HEIGHT_WIDTH), REGLIST(DST_HEIGHT_WIDTH_8), REGLIST(DST_HEIGHT_WIDTH_BW), REGLIST(DST_HEIGHT_Y), REGLIST(DST_LINE_START), REGLIST(DST_LINE_END), REGLIST(DST_LINE_PATCOUNT), REGLIST(DST_OFFSET), REGLIST(DST_PITCH), REGLIST(DST_PITCH_OFFSET), REGLIST(DST_PITCH_OFFSET_C), REGLIST(DST_WIDTH), REGLIST(DST_WIDTH_HEIGHT), REGLIST(DST_WIDTH_X), REGLIST(DST_WIDTH_X_INCY), REGLIST(DST_X), REGLIST(DST_X_SUB), REGLIST(DST_X_Y), REGLIST(DST_Y), REGLIST(DST_Y_SUB), REGLIST(DST_Y_X), REGLIST(FLUSH_1), REGLIST(FLUSH_2), REGLIST(FLUSH_3), REGLIST(FLUSH_4), REGLIST(FLUSH_5), REGLIST(FLUSH_6), REGLIST(FLUSH_7), REGLIST(FOG_3D_TABLE_START), REGLIST(FOG_3D_TABLE_END), REGLIST(FOG_3D_TABLE_DENSITY), REGLIST(FOG_TABLE_INDEX), REGLIST(FOG_TABLE_DATA), REGLIST(FP_CRTC_H_TOTAL_DISP), REGLIST(FP_CRTC_V_TOTAL_DISP), REGLIST(FP_CRTC2_H_TOTAL_DISP), REGLIST(FP_CRTC2_V_TOTAL_DISP), REGLIST(FP_GEN_CNTL), REGLIST(FP2_GEN_CNTL), REGLIST(FP_H_SYNC_STRT_WID), REGLIST(FP_H2_SYNC_STRT_WID), REGLIST(FP_HORZ_STRETCH), REGLIST(FP_HORZ2_STRETCH), REGLIST(FP_V_SYNC_STRT_WID), REGLIST(FP_VERT_STRETCH), REGLIST(FP_V2_SYNC_STRT_WID), REGLIST(FP_VERT2_STRETCH), REGLIST(FW_CNTL), REGLIST(FW_STATUS), REGLIST(GEN_INT_CNTL), REGLIST(GEN_INT_STATUS), REGLIST(GENENB), REGLIST(GENFC_RD), REGLIST(GENFC_WT), REGLIST(GENMO_RD), REGLIST(GENMO_WT), REGLIST(GENS0), REGLIST(GENS1), REGLIST(GPIO_MONID), REGLIST(GPIO_MONIDB), REGLIST(GPIO_CRT2_DDC), REGLIST(GPIO_DVI_DDC), REGLIST(GPIO_VGA_DDC), REGLIST(GRPH8_DATA), REGLIST(GRPH8_IDX), REGLIST(GUI_DEBUG0), REGLIST(GUI_DEBUG1), REGLIST(GUI_DEBUG2), REGLIST(GUI_DEBUG3), REGLIST(GUI_DEBUG4), REGLIST(GUI_DEBUG5), REGLIST(GUI_DEBUG6), REGLIST(GUI_SCRATCH_REG0), REGLIST(GUI_SCRATCH_REG1), REGLIST(GUI_SCRATCH_REG2), REGLIST(GUI_SCRATCH_REG3), REGLIST(GUI_SCRATCH_REG4), REGLIST(GUI_SCRATCH_REG5), REGLIST(HEADER), REGLIST(HOST_DATA0), REGLIST(HOST_DATA1), REGLIST(HOST_DATA2), REGLIST(HOST_DATA3), REGLIST(HOST_DATA4), REGLIST(HOST_DATA5), REGLIST(HOST_DATA6), REGLIST(HOST_DATA7), REGLIST(HOST_DATA_LAST), REGLIST(HOST_PATH_CNTL), REGLIST(HW_DEBUG), REGLIST(HW_DEBUG2), REGLIST(I2C_CNTL_1), REGLIST(DVI_I2C_CNTL_1), REGLIST(INTERRUPT_LINE), REGLIST(INTERRUPT_PIN), REGLIST(IO_BASE), REGLIST(LATENCY), REGLIST(LEAD_BRES_DEC), REGLIST(LEAD_BRES_LNTH), REGLIST(LEAD_BRES_LNTH_SUB), REGLIST(LVDS_GEN_CNTL), REGLIST(MAX_LATENCY), REGLIST(MC_AGP_LOCATION), REGLIST(MC_FB_LOCATION), REGLIST(MC_STATUS), REGLIST(MDGPIO_A_REG), REGLIST(MDGPIO_EN_REG), REGLIST(MDGPIO_MASK), REGLIST(MDGPIO_Y_REG), REGLIST(MEM_ADDR_CONFIG), REGLIST(MEM_BASE), REGLIST(MEM_CNTL), REGLIST(MEM_INIT_LAT_TIMER), REGLIST(MEM_INTF_CNTL), REGLIST(MEM_SDRAM_MODE_REG), REGLIST(MEM_STR_CNTL), REGLIST(MEM_VGA_RP_SEL), REGLIST(MEM_VGA_WP_SEL), REGLIST(MIN_GRANT), REGLIST(MM_DATA), REGLIST(MM_INDEX), REGLIST(MPP_TB_CONFIG), REGLIST(MPP_GP_CONFIG), REGLIST(N_VIF_COUNT), REGLIST(OV0_SCALE_CNTL), REGLIST(OVR_CLR), REGLIST(OVR_WID_LEFT_RIGHT), REGLIST(OVR_WID_TOP_BOTTOM), REGLIST(OV0_Y_X_START), REGLIST(OV0_Y_X_END), REGLIST(OV0_EXCLUSIVE_HORZ), REGLIST(OV0_EXCLUSIVE_VERT), REGLIST(OV0_REG_LOAD_CNTL), REGLIST(OV0_SCALE_CNTL), REGLIST(OV0_V_INC), REGLIST(OV0_P1_V_ACCUM_INIT), REGLIST(OV0_P23_V_ACCUM_INIT), REGLIST(OV0_P1_BLANK_LINES_AT_TOP), REGLIST(OV0_P23_BLANK_LINES_AT_TOP), REGLIST(OV0_VID_BUF0_BASE_ADRS), REGLIST(OV0_VID_BUF1_BASE_ADRS), REGLIST(OV0_VID_BUF2_BASE_ADRS), REGLIST(OV0_VID_BUF3_BASE_ADRS), REGLIST(OV0_VID_BUF4_BASE_ADRS), REGLIST(OV0_VID_BUF5_BASE_ADRS), REGLIST(OV0_VID_BUF_PITCH0_VALUE), REGLIST(OV0_VID_BUF_PITCH1_VALUE), REGLIST(OV0_AUTO_FLIP_CNTL), REGLIST(OV0_DEINTERLACE_PATTERN), REGLIST(OV0_H_INC), REGLIST(OV0_STEP_BY), REGLIST(OV0_P1_H_ACCUM_INIT), REGLIST(OV0_P23_H_ACCUM_INIT), REGLIST(OV0_P1_X_START_END), REGLIST(OV0_P2_X_START_END), REGLIST(OV0_P3_X_START_END), REGLIST(OV0_FILTER_CNTL), REGLIST(OV0_FOUR_TAP_COEF_0), REGLIST(OV0_FOUR_TAP_COEF_1), REGLIST(OV0_FOUR_TAP_COEF_2), REGLIST(OV0_FOUR_TAP_COEF_3), REGLIST(OV0_FOUR_TAP_COEF_4), REGLIST(OV0_COLOUR_CNTL), REGLIST(OV0_VIDEO_KEY_CLR), REGLIST(OV0_VIDEO_KEY_MSK), REGLIST(OV0_GRAPHICS_KEY_CLR), REGLIST(OV0_GRAPHICS_KEY_MSK), REGLIST(OV0_KEY_CNTL), REGLIST(OV0_TEST), REGLIST(PALETTE_DATA), REGLIST(PALETTE_30_DATA), REGLIST(PALETTE_INDEX), REGLIST(PCI_GART_PAGE), REGLIST(PIXCLKS_CNTL), REGLIST(PLANE_3D_MASK_C), REGLIST(PMI_CAP_ID), REGLIST(PMI_DATA), REGLIST(PMI_NXT_CAP_PTR), REGLIST(PMI_PMC_REG), REGLIST(PMI_PMCSR_REG), REGLIST(PMI_REGISTER), REGLIST(PWR_MNGMT_CNTL_STATUS), REGLIST(DSTCACHE_MODE), REGLIST(RBBM_SOFT_RESET), REGLIST(RBBM_STATUS), REGLIST(RB2D_DSTCACHE_CTLSTAT), REGLIST(RB2D_DSTCACHE_MODE), REGLIST(REG_BASE), REGLIST(REGPROG_INF), REGLIST(REVISION_ID), REGLIST(SC_BOTTOM), REGLIST(SC_BOTTOM_RIGHT), REGLIST(SC_BOTTOM_RIGHT_C), REGLIST(SC_LEFT), REGLIST(SC_RIGHT), REGLIST(SC_TOP), REGLIST(SC_TOP_LEFT), REGLIST(SC_TOP_LEFT_C), REGLIST(SDRAM_MODE_REG), REGLIST(SEQ8_DATA), REGLIST(SEQ8_IDX), REGLIST(SNAPSHOT_F_COUNT), REGLIST(SNAPSHOT_VH_COUNTS), REGLIST(SNAPSHOT_VIF_COUNT), REGLIST(SRC_OFFSET), REGLIST(SRC_PITCH), REGLIST(SRC_PITCH_OFFSET), REGLIST(SRC_SC_BOTTOM), REGLIST(SRC_SC_BOTTOM_RIGHT), REGLIST(SRC_SC_RIGHT), REGLIST(SRC_X), REGLIST(SRC_X_Y), REGLIST(SRC_Y), REGLIST(SRC_Y_X), REGLIST(STATUS), REGLIST(SUBPIC_CNTL), REGLIST(SUB_CLASS), REGLIST(SURFACE_CNTL), REGLIST(SURFACE0_INFO), REGLIST(SURFACE0_LOWER_BOUND), REGLIST(SURFACE0_UPPER_BOUND), REGLIST(SURFACE1_INFO), REGLIST(SURFACE1_LOWER_BOUND), REGLIST(SURFACE1_UPPER_BOUND), REGLIST(SURFACE2_INFO), REGLIST(SURFACE2_LOWER_BOUND), REGLIST(SURFACE2_UPPER_BOUND), REGLIST(SURFACE3_INFO), REGLIST(SURFACE3_LOWER_BOUND), REGLIST(SURFACE3_UPPER_BOUND), REGLIST(SURFACE4_INFO), REGLIST(SURFACE4_LOWER_BOUND), REGLIST(SURFACE4_UPPER_BOUND), REGLIST(SURFACE5_INFO), REGLIST(SURFACE5_LOWER_BOUND), REGLIST(SURFACE5_UPPER_BOUND), REGLIST(SURFACE6_INFO), REGLIST(SURFACE6_LOWER_BOUND), REGLIST(SURFACE6_UPPER_BOUND), REGLIST(SURFACE7_INFO), REGLIST(SURFACE7_LOWER_BOUND), REGLIST(SURFACE7_UPPER_BOUND), REGLIST(SW_SEMAPHORE), REGLIST(TEST_DEBUG_CNTL), REGLIST(TEST_DEBUG_MUX), REGLIST(TEST_DEBUG_OUT), REGLIST(TMDS_CRC), REGLIST(TRAIL_BRES_DEC), REGLIST(TRAIL_BRES_ERR), REGLIST(TRAIL_BRES_INC), REGLIST(TRAIL_X), REGLIST(TRAIL_X_SUB), REGLIST(PIXCLKS_CNTL), REGLIST(VENDOR_ID), REGLIST(VGA_DDA_CONFIG), REGLIST(VGA_DDA_ON_OFF), REGLIST(VID_BUFFER_CONTROL), REGLIST(VIDEOMUX_CNTL), REGLIST(VIPH_CONTROL), REGLIST(WAIT_UNTIL), REGLIST(RB3D_BLENDCNTL), REGLIST(RB3D_CNTL), REGLIST(RB3D_COLOROFFSET), REGLIST(RB3D_COLORPITCH), REGLIST(RB3D_DEPTHOFFSET), REGLIST(RB3D_DEPTHPITCH), REGLIST(RB3D_PLANEMASK), REGLIST(RB3D_ROPCNTL), REGLIST(RB3D_STENCILREFMASK), REGLIST(RB3D_ZSTENCILCNTL), REGLIST(RB3D_DSTCACHE_MODE), REGLIST(RE_LINE_PATTERN), REGLIST(RE_LINE_STATE), REGLIST(RE_MISC), REGLIST(RE_SOLID_COLOR), REGLIST(RE_TOP_LEFT), REGLIST(RE_WIDTH_HEIGHT), REGLIST(LVDS_PLL_CNTL), REGLIST(TMDS_PLL_CNTL), REGLIST(TMDS_TRANSMITTER_CNTL), REGLIST(ISYNC_CNTL), }; void radeon_reg_match(const char *pattern) { int i; for (i=0;i [disabled] [size=128K] Capabilities: 02:00.0 Ethernet controller: 3Com Corporation 3c905C-TX/TX-M [Tornado] (rev 78) Subsystem: Dell Computer Corporation: Unknown device 00e3 Flags: bus master, medium devsel, latency 32, IRQ 11 I/O ports at ec80 [size=128] t emory at f8fffc00 (32-bit, non-prefetchable) [size=128] Expansion ROM at f9000000 [disabled] [size=128K] Capabilities: We need to look through it to find the smaller region base address f8fffc00. #endif while(1) { /* for every line up to the "Radeon" string */ if(fgets(line,sizeof(line),fp) == NULL) { /* if end of file */ fatal("Radeon hardware not found in lspci output.\n"); } if(strstr(line,"Radeon") || strstr(line,"ATI Tech")) { /* if line contains a "radeon" string */ if(skip-- < 1) { break; } } }; if(debug) printf("%s",line); while(1) { /* for every line up till memory statement */ if(fgets(line,sizeof(line),fp) == NULL || line[0] != '\t') { /* if end of file */ fatal("Radeon control memory not found.\n"); } if(debug) printf("%s",line); if(strstr(line,"emory") && strstr(line,"K")) { /* if line contains a "Memory" and "K" string */ break; } }; if(sscanf(line,"%*s%*s%x",&base) == 0) { /* third token as hex number */ fatal("parse error of lspci output (control memory not found)\n"); } if(debug) printf("Radeon found. Base control address is %x.\n",base); radeon_cntl_mem = map_devince_memory(base,0x4000); } #ifdef __powerpc__ #define __swab16(x) \ ({ \ unsigned short __x = (x); \ ((unsigned short)( \ (((unsigned short)(__x) & (unsigned short)0x00ffU) << 8) | \ (((unsigned short)(__x) & (unsigned short)0xff00U) >> 8) )); \ }) #define __swab32(x) \ ({ \ unsigned int __x = (x); \ ((unsigned int)( \ (((unsigned int)(__x) & (unsigned int)0x000000ffUL) << 24) | \ (((unsigned int)(__x) & (unsigned int)0x0000ff00UL) << 8) | \ (((unsigned int)(__x) & (unsigned int)0x00ff0000UL) >> 8) | \ (((unsigned int)(__x) & (unsigned int)0xff000000UL) >> 24) )); \ }) #define BIOS16(offset) __swab16(*((unsigned short *)(bios + (offset)))) #define BIOS32(offset) __swab32(*((unsigned int *)(bios + (offset)))) #else #define BIOS16(offset) (*((unsigned short *)(bios + (offset)))) #define BIOS32(offset) (*((unsigned int *)(bios + (offset)))) #endif #define BIOS8(offset) (*((unsigned char *)(bios + (offset)))) struct nametable_entry { unsigned int value; const char *name; }; const char *radeon_valname(const struct nametable_entry *table, unsigned int value) { static char ret_buf[256]; while(table->name) { if (table->value == value) return table->name; table++; } sprintf(ret_buf, "", value); return ret_buf; } static struct nametable_entry hdr_type_name[] = { { 2, "Rage128 & Pro"}, { 3, "Rage M3"}, { 4, "Radeon"}, { 36, "ATOM" }, { 0, NULL} }; static void radeon_rom_legacy_clocks(unsigned char *bios, int hdr) { int pll_info_block = BIOS16(hdr + 0x30); if (pll_info_block == 0) { printf("No clock info block in BIOS\n"); return; } printf("Clock info block:\n"); printf(" SCLK : %f\n", BIOS16(pll_info_block + 0x08) / 100.0); printf(" MCLK : %f\n", BIOS16(pll_info_block + 0x0a) / 100.0); printf(" RefClk : %f\n", BIOS16(pll_info_block + 0x0e) / 100.0); printf(" RefDiv : %d\n", BIOS16(pll_info_block + 0x10)); printf(" VCO Min: %f\n", BIOS32(pll_info_block + 0x12) / 100.0); printf(" VCO Max: %f\n", BIOS32(pll_info_block + 0x16) / 100.0); printf("\n"); } static void radeon_rom_atom_clocks(unsigned char *bios, int master) { int pll_info_block = BIOS16(master + 12); if (pll_info_block == 0) { printf("No clock info block in BIOS\n"); } printf("Clock info block:\n"); printf(" SCLK : %f\n", BIOS32(pll_info_block + 8) / 100.0); printf(" MCLK : %f\n", BIOS32(pll_info_block + 12) / 100.0); printf(" RefClk : %f\n", BIOS16(pll_info_block + 82) / 100.0); printf(" PPLL Min: %f\n", BIOS16(pll_info_block + 78) / 100.0); printf(" PPLL Max: %f\n", BIOS32(pll_info_block + 32) / 100.0); } static struct nametable_entry lconn_type_name[] = { { 0, "None"}, { 1, "Proprietary"}, { 2, "VGA"}, { 3, "DVI-I"}, { 4, "DVI-D"}, { 5, "CTV"}, { 6, "STV"}, { 7, "Unsupported"}, { 0, NULL} }; static struct nametable_entry lddc_type_name[] = { { 0, "None"}, { 1, "MONID"}, { 2, "DVI"}, { 3, "VGA"}, { 4, "CRT2"}, { 0, NULL} }; static struct nametable_entry ldac_type_name[] = { { 0, "CRT"}, { 1, "TV"}, { 2, "External"}, { 0, NULL} }; static void radeon_rom_legacy_connectors(unsigned char *bios, int hdr) { int offset = BIOS16(hdr + 0x50); int i, entry, tmp, chips, entries; if (offset == 0) { printf("No connector table in BIOS\n"); return; } printf("Connector table:\n"); #if 0 printf(" raw: %02x %02x %02x %02x %02x %02x %02x %02x\n", BIOS8(offset+0), BIOS8(offset+1), BIOS8(offset+2), BIOS8(offset+3), BIOS8(offset+4), BIOS8(offset+5), BIOS8(offset+6), BIOS8(offset+7)); #endif chips = BIOS8(offset) >> 4; printf(" Table revision %d for %d chip(s)\n", BIOS8(offset) & 0xf, chips); if (chips > 1) printf(" Only 1 chip supported for now !\n"); entries = BIOS8(offset + 1) & 0xf; printf(" Table for chip %d has %d connector(s):\n", BIOS8(offset + 1) >> 4, entries); for (i = 0; i < 4; i++) { entry = offset + 2 + i*2; /* End of table */ if (!BIOS16(entry)) { if (i < entries) printf(" \n"); break; } /* Read table entry, check connector type */ tmp = BIOS16(entry); printf(" %08x ", tmp); printf("Type:%s", radeon_valname(lconn_type_name, (tmp >> 12) & 0xf)); printf(", DDC:%s", radeon_valname(lddc_type_name, (tmp >> 8) & 0xf)); printf(", DAC:%s", radeon_valname(ldac_type_name, tmp & 0x3)); printf(", TMDS:%s", (tmp & 0x10) ? "External" : "Internal"); printf("\n"); } printf("\n"); } static struct nametable_entry atomconn_type_name[] = { { 0, "None"}, { 1, "VGA"}, { 2, "DVI-I"}, { 3, "DVI-D"}, { 4, "DVI-A"}, { 5, "STV"}, { 6, "CTV"}, { 7, "LVDS"}, { 8, "Digital"}, { 9, "Unsupported"}, { 0, NULL} }; static void radeon_rom_atom_connectors(unsigned char *bios, int master) { int offset = BIOS16(master + 22); int tmp, i, tmp0; int crtc, dac, connector, ddc=0; if (offset == 0) { printf("No connector table in BIOS\n"); return; } tmp = BIOS16(offset + 4); printf("Connector table:\n"); for (i=0; i<8; i++) { if (tmp & (1<> 8) & 0xf; dac = (portinfo & 0xf) - 1; connector = (portinfo >> 4) & 0xf; tmp0 = BIOS16(master + 24); if (1/*crtc*/) { int gpio = BIOS16(tmp0 + 4 + 27 * crtc) * 4; printf("gpio is %02X\n", gpio); switch(gpio) { case RADEON_GPIO_MONID: ddc = 1; break; case RADEON_GPIO_DVI_DDC: ddc = 2; break; case RADEON_GPIO_VGA_DDC: ddc = 3; break; case RADEON_GPIO_CRT2_DDC: ddc = 4; break; default: ddc=0; break; } } printf("%d: %08x ", i, portinfo); printf(", Id:%d", crtc); printf(", Type:%s", radeon_valname(atomconn_type_name, connector)); if (1/*crtc*/) printf(", DDC:%s", radeon_valname(lddc_type_name, ddc)); printf(", DAC:%s", radeon_valname(ldac_type_name, dac)); if (i==3) printf(" TMDS: Internal\n"); else if (i==7) printf(" TMDS: External\n"); else printf("\n"); } } } static void radeon_rom_legacy_dfptable(unsigned char *bios, int hdr) { int offset, i, n, rev, stride; offset = BIOS16(hdr + 0x34); if (offset == 0) { printf("No DFP info table\n"); return; } rev = BIOS8(offset); printf("DFP table revision: %d\n", rev); switch(rev) { case 3: n = BIOS8(offset + 5) + 1; if (n > 4) n = 4; for (i = 0; i < n; i++) { /* Looks weird ... but that's what is in X.org */ printf(" PixClock: %f\t TMDS_PLL_CNTL: %08x\n", BIOS16(offset+i*10+0x10) / 100.0, BIOS32(offset+i*10+0x08)); } break; /* revision 4 has some problem as it appears in RV280... */ case 4: stride = 0; n = BIOS8(offset+ 5) + 1; if (n > 4) n = 4; for (i = 0; i < n; i++) { printf(" PixClock: %f\t TMDS_PLL_CNTL: %08x\n", BIOS16(offset+stride+0x10) / 100.0, BIOS32(offset+stride+0x08)); if (i == 0) stride += 10; else stride += 6; } break; } } static void radeon_rom_legacy_exttmdstable(unsigned char *bios, int hdr) { if (BIOS16(hdr + 0x58)) { printf("Found External TMDS Table\n"); } } void radeon_rom_tables(const char * file) { #define _64K (64*1024) unsigned char bios[_64K]; int fd, hdr, atom; fd = open(file, O_RDONLY); if (fd < 0) { perror("can't open rom file"); return; } memset(bios, 0, _64K); read(fd, bios, _64K); close(fd); if (bios[0] != 0x55 || bios[1] != 0xaa) fatal("PCI ROM signature 0x55 0xaa missing"); hdr = BIOS16(0x48); printf("\nBIOS Tables:\n------------\n\n"); printf("Header at %x, type: %d [%s]\n", hdr, BIOS8(hdr), radeon_valname(hdr_type_name, BIOS8(hdr))); printf("OEM ID: %02x %02x\n", BIOS8(hdr+2), BIOS8(hdr+3)); atom = (BIOS8(hdr+4) == 'A' && BIOS8(hdr+5) == 'T' && BIOS8(hdr+6) == 'O' && BIOS8(hdr+7) == 'M') || (BIOS8(hdr+4) == 'M' && BIOS8(hdr+5) == 'O' && BIOS8(hdr+6) == 'T' && BIOS8(hdr+7) == 'A'); if (atom) { int master = BIOS16(hdr+32); printf("ATOM BIOS detected !\n\n"); radeon_rom_atom_clocks(bios, master); radeon_rom_atom_connectors(bios, master); // add more ... } else { printf("Legacy BIOS detected !\n"); printf("BIOS Rev: %x.%x\n\n", BIOS8(hdr+4), BIOS8(hdr+5)); radeon_rom_legacy_clocks(bios, hdr); radeon_rom_legacy_connectors(bios, hdr); radeon_rom_legacy_dfptable(bios, hdr); radeon_rom_legacy_exttmdstable(bios, hdr); } } int main(int argc,char *argv[]) { if(argc == 1) { map_radeon_cntl_mem(); usage(); } if(strcmp(argv[1],"--debug") == 0) { debug=1; argv++; argc--; }; if(strcmp(argv[1],"--skip=") == 0) { skip=atoi(argv[1]+7); argv++; argc--; }; map_radeon_cntl_mem(); if(argc == 2) { if(strcmp(argv[1],"regs") == 0) { radeon_cmd_regs(); return 0; } else if(strcmp(argv[1],"bits") == 0) { radeon_cmd_bits(); return 0; } else if(strcmp(argv[1],"dac") == 0) { radeon_cmd_dac(NULL); return 0; } else if(strcmp(argv[1],"light") == 0) { radeon_cmd_light(NULL); return 0; } else if(strcmp(argv[1],"stretch") == 0) { radeon_cmd_stretch(NULL); return 0; }; } else if(argc == 3) { if(strcmp(argv[1],"dac") == 0) { radeon_cmd_dac(argv[2]); return 0; } else if(strcmp(argv[1],"light") == 0) { radeon_cmd_light(argv[2]); return 0; } else if(strcmp(argv[1],"stretch") == 0) { radeon_cmd_stretch(argv[2]); return 0; } else if(strcmp(argv[1],"regmatch") == 0) { radeon_reg_match(argv[2]); return 0; } else if(strcmp(argv[1],"romtables") == 0) { radeon_rom_tables(argv[2]); return 0; }; } else if(argc == 4) { if(strcmp(argv[1],"regset") == 0) { radeon_reg_set(argv[2], strtoul(argv[3], NULL, 0)); return 0; } } usage(); return 1; }