/* 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 #include "radeon_reg.h" int debug = 0; int skip = 0; /* *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; unsigned char * volatile fb_mem; unsigned char * volatile ctrl_mem; static void radeon_rom_legacy_mmio_table(unsigned char *bios, int offset); static void die(const char *why) { fprintf(stderr, "fatal error: %s\n", why); pci_system_cleanup(); exit(-1); } static void die_error(int err, const char *why) { fprintf(stderr, "fatal error: %s: %s\n", why, strerror(err)); pci_system_cleanup(); 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); assert(radeon_cntl_mem); #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); assert(radeon_cntl_mem); #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 unsigned int radeon_get_indexed(unsigned long index_offset, unsigned long data_offset, unsigned long offset, const char *name, unsigned long index_mask) { unsigned int temp = offset; assert(radeon_cntl_mem); if (index_mask) { temp = radeon_get(index_offset, "index"); temp &= ~index_mask; temp += offset; } radeon_set(index_offset, "index", temp); return radeon_get(data_offset, name); } static void radeon_set_indexed(unsigned long index_offset, unsigned long data_offset, unsigned long offset, const char *name, unsigned int value, int index_mask) { unsigned int temp = offset; assert(radeon_cntl_mem); if (index_mask) { temp = radeon_get(index_offset, "index"); temp &= ~index_mask; temp += offset; } radeon_set(index_offset, "index", temp); radeon_set(data_offset, name, value); } static unsigned int radeon_get_clk(unsigned long offset, const char *name) { return radeon_get_indexed(RADEON_CLOCK_CNTL_INDEX, RADEON_CLOCK_CNTL_DATA, offset, name, 0x3f); } static void radeon_set_clk(unsigned long offset, const char *name, unsigned int value) { return radeon_set_indexed(RADEON_CLOCK_CNTL_INDEX, RADEON_CLOCK_CNTL_DATA, offset | RADEON_PLL_WR_EN, name, value, 0xff); } static unsigned int radeon_get_mcind(unsigned long offset, const char *name) { return radeon_get_indexed(0x1f8, 0x1fc, offset, name, 0x3f); } static void radeon_set_mcind(unsigned long offset, const char *name, unsigned int value) { return radeon_set_indexed(0x1f8, 0x1fc, offset | (1 << 8), name, value, 0); } static void usage(void) { const char *dac_status, *light_status; if (!radeon_cntl_mem) { dac_status = ""; light_status = ""; } else { dac_status = (radeon_get(RADEON_DAC_CNTL, "RADEON_DAC_CNTL") & RADEON_DAC_PDWN) ? " (off)" : " (on)"; light_status = (radeon_get(RADEON_LVDS_GEN_CNTL,"RADEON_LVDS_GEN_CNTL") & RADEON_LVDS_ON) ? " (on)" : " (off)"; } fprintf(stderr,"usage: radeontool [options] [command]\n"); fprintf(stderr," --debug - show a little debug info\n"); fprintf(stderr," --skip=1 - use the second radeon card\n"); fprintf(stderr," dac [on|off] - power down the external video outputs%s\n", dac_status); fprintf(stderr," light [on|off] - power down the backlight%s\n", light_status); fprintf(stderr," stretch [on|off|vert|horiz|auto|manual] - stretching for resolution mismatch \n"); fprintf(stderr," regs - show a listing of some random registers\n"); fprintf(stderr," regmatch - show registers matching wildcard pattern\n"); fprintf(stderr," regset - set registers matching wildcard pattern\n"); exit(-1); } void radeon_cmd_regs(void) { #define SHOW_REG(r) printf("%s\t%08x\n", #r, radeon_get(r, #r)) #define SHOW_CLK_REG(r) printf("%s\t%08x\n", #r, radeon_get_indexed(RADEON_CLOCK_CNTL_INDEX, RADEON_CLOCK_CNTL_DATA, (r), #r, 0x3f)) if (!radeon_cntl_mem) exit(-1); SHOW_REG(RADEON_DAC_CNTL); SHOW_REG(RADEON_DAC_EXT_CNTL); SHOW_REG(RADEON_DAC_MACRO_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_LVDS_PLL_CNTL); SHOW_REG(RADEON_FP_GEN_CNTL); SHOW_REG(RADEON_FP2_GEN_CNTL); SHOW_CLK_REG(RADEON_PPLL_CNTL); SHOW_CLK_REG(RADEON_PPLL_REF_DIV); SHOW_CLK_REG(RADEON_PPLL_DIV_3); SHOW_CLK_REG(RADEON_PIXCLKS_CNTL); SHOW_CLK_REG(RADEON_P2PLL_CNTL); SHOW_CLK_REG(RADEON_P2PLL_REF_DIV); SHOW_CLK_REG(RADEON_P2PLL_DIV_0); SHOW_CLK_REG(RADEON_VCLK_ECP_CNTL); SHOW_REG(RADEON_MEM_TIMING_CNTL); SHOW_REG(RADEON_TMDS_PLL_CNTL); SHOW_REG(RADEON_TMDS_TRANSMITTER_CNTL); SHOW_REG(RADEON_CRTC_MORE_CNTL); SHOW_REG(RADEON_FP_H_SYNC_STRT_WID); SHOW_REG(RADEON_FP_V_SYNC_STRT_WID); SHOW_REG(RADEON_FP_CRTC_H_TOTAL_DISP); SHOW_REG(RADEON_FP_CRTC_V_TOTAL_DISP); SHOW_REG(RADEON_FP_HORZ_STRETCH); SHOW_REG(RADEON_FP_VERT_STRETCH); SHOW_REG(RADEON_FP_HORZ_VERT_ACTIVE); SHOW_REG(RADEON_CRTC_H_TOTAL_DISP); SHOW_REG(RADEON_CRTC_H_SYNC_STRT_WID); SHOW_REG(RADEON_CRTC_V_TOTAL_DISP); SHOW_REG(RADEON_CRTC_V_SYNC_STRT_WID); SHOW_REG(RADEON_CRTC2_H_TOTAL_DISP); SHOW_REG(RADEON_CRTC2_H_SYNC_STRT_WID); SHOW_REG(RADEON_CRTC2_V_TOTAL_DISP); SHOW_REG(RADEON_CRTC2_V_SYNC_STRT_WID); } #define REGLIST(r) { "", #r, radeon_get, radeon_set, RADEON_ ## r } #define REGLIST_CLK(r) { "CL: ", #r, radeon_get_clk, radeon_set_clk, RADEON_ ## r } static struct { const char *type; const char *name; unsigned int (*get)(unsigned long, const char *); void (*set)(unsigned long, const char *, unsigned int); 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(DAC_EXT_CNTL), REGLIST(DAC_MACRO_CNTL), REGLIST(TV_DAC_CNTL), REGLIST(DISP_OUTPUT_CNTL), REGLIST(DISPLAY_BASE_ADDR), REGLIST(DISPLAY2_BASE_ADDR), 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_HW_DEBUG), 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(GRPH_BUFFER_CNTL), REGLIST(GRPH2_BUFFER_CNTL), REGLIST(MC_DEBUG), 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_TIMING_CNTL), REGLIST(MC_CNTL), REGLIST(MC_ARB_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(NB_TOM), 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_LOW), REGLIST(OV0_VIDEO_KEY_CLR_HIGH), REGLIST(OV0_GRAPHICS_KEY_CLR_LOW), REGLIST(OV0_GRAPHICS_KEY_CLR_HIGH), REGLIST(OV0_KEY_CNTL), REGLIST(OV0_TEST), REGLIST(PALETTE_DATA), REGLIST(PALETTE_30_DATA), REGLIST(PALETTE_INDEX), REGLIST(PCI_GART_PAGE), REGLIST_CLK(PIXCLKS_CNTL), REGLIST_CLK(VCLK_ECP_CNTL), REGLIST_CLK(MPLL_CNTL), REGLIST_CLK(MCLK_CNTL), REGLIST_CLK(PPLL_DIV_0), REGLIST_CLK(PPLL_DIV_1), REGLIST_CLK(PPLL_DIV_2), REGLIST_CLK(PPLL_DIV_3), REGLIST_CLK(PPLL_REF_DIV), REGLIST_CLK(P2PLL_REF_DIV), REGLIST_CLK(P2PLL_DIV_0), REGLIST_CLK(PPLL_CNTL), REGLIST_CLK(P2PLL_CNTL), REGLIST_CLK(SPLL_CNTL), REGLIST_CLK(AGP_PLL_CNTL), REGLIST_CLK(HTOTAL_CNTL), REGLIST_CLK(HTOTAL2_CNTL), REGLIST_CLK(CLK_PIN_CNTL), REGLIST_CLK(CLK_PWRMGT_CNTL), REGLIST_CLK(PLL_PWRMGT_CNTL), REGLIST_CLK(SCLK_CNTL), REGLIST_CLK(CLK_TEST_ONE), REGLIST_CLK(PWRMAN_MISC), REGLIST_CLK(SS_INT_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(SE_CNTL_STATUS), REGLIST(LVDS_PLL_CNTL), REGLIST(TMDS_PLL_CNTL), REGLIST(TMDS_TRANSMITTER_CNTL), REGLIST(ISYNC_CNTL), REGLIST(TV_MASTER_CNTL), REGLIST(TV_PRE_DAC_MUX_CNTL), REGLIST(TV_RGB_CNTL), REGLIST(TV_SYNC_CNTL), REGLIST(TV_HTOTAL), REGLIST(TV_HDISP), REGLIST(TV_HSTART), REGLIST(TV_HCOUNT), REGLIST(TV_VTOTAL), REGLIST(TV_VDISP), REGLIST(TV_VCOUNT), REGLIST(TV_FTOTAL), REGLIST(TV_FCOUNT), REGLIST(TV_FRESTART), REGLIST(TV_HRESTART), REGLIST(TV_VRESTART), REGLIST(TV_VSCALER_CNTL1), REGLIST(TV_TIMING_CNTL), REGLIST(TV_VSCALER_CNTL2), REGLIST(TV_Y_FALL_CNTL), REGLIST(TV_Y_RISE_CNTL), REGLIST(TV_Y_SAW_TOOTH_CNTL), REGLIST(TV_UPSAMP_AND_GAIN_CNTL), REGLIST(TV_GAIN_LIMIT_SETTINGS), REGLIST(TV_LINEAR_GAIN_SETTINGS), REGLIST(TV_MODULATOR_CNTL1), REGLIST(TV_MODULATOR_CNTL2), REGLIST(TV_CRC_CNTL), REGLIST(TV_UV_ADR), REGLIST(GPIOPAD_A), REGLIST(RS480_UNK_e30), REGLIST(RS480_UNK_e34), REGLIST(RS480_UNK_e38), REGLIST(RS480_UNK_e3c), }; void radeon_reg_match(const char *pattern) { int i; unsigned long address; unsigned int value; if (!radeon_cntl_mem) exit(-1); if (pattern[0] == '0' && pattern[1] == 'x') { address = strtol(&(pattern[2]), NULL, 16); value = radeon_get(address, pattern); printf("%s\t0x%08x (%d)\n", pattern, value, value); } else if (pattern[0] == 'C' && pattern[1] == 'L' && pattern[2] == ':') { address = strtol(&(pattern[3]), NULL, 16); value = radeon_get_clk(address, pattern); printf("%s\t0x%08x (%d)\n", pattern, value, value); } else if (pattern[0] == 'M' && pattern[1] == 'C' && pattern[2] == ':') { address = strtol(&(pattern[3]), NULL, 16); value = radeon_get_mcind(address, pattern); printf("%s\t0x%08x (%d)\n", pattern, value, value); } else { int crtc2_enabled; /* Prepare for a crash (just in case). */ sync(); /* dual-head setup? */ value = radeon_get(RADEON_CRTC2_GEN_CNTL, "RADEON_CRTC2_GEN_CTRL"); crtc2_enabled = (value & RADEON_CRTC2_EN) ? 1 : 0; for (i = 0; i < sizeof(reg_list) / sizeof(reg_list[0]); i++) { if (fnmatch(pattern, reg_list[i].name, 0) == 0) { if (!crtc2_enabled && (reg_list[i].address == RADEON_CRTC2_CRNT_FRAME || reg_list[i].address == RADEON_CRTC2_VLINE_CRNT_VLINE)) /* might freeze, so skip it */ continue; printf("%s (%s%04x)\t", reg_list[i].name, reg_list[i].type, reg_list[i].address); /* Force output in case the register read locks up. */ fflush(stdout); fsync(STDOUT_FILENO); value = reg_list[i].get(reg_list[i].address, reg_list[i].name); printf("0x%08x (%d)\n", value, value); } } if (pattern[0] == '*') { for (i = 0; i < 0x2f; i++) { value = radeon_get_mcind(i, "MC"); printf("MC: 0x%02x\t0x%08x\n", i, value); } } } } void set_reg(const char *name, const char *type, unsigned long address, unsigned int value, unsigned int (*get)(unsigned long, const char *), void (*set)(unsigned long, const char *, unsigned int)) { unsigned int readback; readback = get(address, name); printf("OLD: %s (%s%04lx)\t0x%08x (%d)\n", name, type, address, readback, readback); set(address, name, value); readback = get(address, name); printf("NEW: %s (%s%04lx)\t0x%08x (%d)\n", name, type, address, readback, readback); } void radeon_reg_set(const char *inname, unsigned int value) { int i; unsigned long address; if (!radeon_cntl_mem) exit(-1); if (inname[0] == '0' && inname[1] == 'x') { address = strtol(&(inname[2]), NULL, 16); set_reg(inname, "", address, value, radeon_get, radeon_set); } else if (inname[0] == 'C' && inname[1] == 'L' && inname[2] == ':') { address = strtol(&(inname[3]), NULL, 16); set_reg(inname, "CL: ", address, value, radeon_get_clk, radeon_set_clk); } else { for (i = 0; i < sizeof(reg_list) / sizeof(reg_list[0]); i++) { if (fnmatch(inname, reg_list[i].name, 0) == 0) { set_reg(reg_list[i].name, reg_list[i].type, reg_list[i].address, value, reg_list[i].get, reg_list[i].set); } } } } void radeon_cmd_bits(void) { unsigned int dac_cntl; if (!radeon_cntl_mem) exit(-1); dac_cntl = radeon_get(RADEON_DAC_CNTL,"RADEON_DAC_CNTL"); printf("RADEON_DAC_CNTL=%08x (",dac_cntl); if(dac_cntl & RADEON_DAC_RANGE_CNTL) printf("range_cntl "); if(dac_cntl & RADEON_DAC_BLANKING) printf("blanking "); if(dac_cntl & RADEON_DAC_8BIT_EN) printf("8bit_en "); if(dac_cntl & RADEON_DAC_VGA_ADR_EN) printf("vga_adr_en "); if(dac_cntl & RADEON_DAC_PDWN) printf("pdwn "); printf(")\n"); } void radeon_cmd_dac(char *param) { unsigned long dac_cntl; if (!radeon_cntl_mem) exit(-1); dac_cntl = radeon_get(RADEON_DAC_CNTL,"RADEON_DAC_CNTL"); if(param == NULL) { printf("The radeon external DAC looks %s\n",(dac_cntl&(RADEON_DAC_PDWN))?"off":"on"); exit (-1); } else if(strcmp(param,"off") == 0) { dac_cntl |= RADEON_DAC_PDWN; } else if(strcmp(param,"on") == 0) { dac_cntl &= ~ RADEON_DAC_PDWN; } else { usage(); }; radeon_set(RADEON_DAC_CNTL,"RADEON_DAC_CNTL",dac_cntl); } void radeon_cmd_light(char *param) { unsigned long lvds_gen_cntl; if (!radeon_cntl_mem) exit(-1); lvds_gen_cntl = radeon_get(RADEON_LVDS_GEN_CNTL,"RADEON_LVDS_GEN_CNTL"); if(param == NULL) { printf("The radeon backlight looks %s\n",(lvds_gen_cntl&(RADEON_LVDS_ON))?"on":"off"); exit (-1); } else if(strcmp(param,"on") == 0) { lvds_gen_cntl |= RADEON_LVDS_ON; } else if(strcmp(param,"off") == 0) { lvds_gen_cntl &= ~ RADEON_LVDS_ON; } else { usage(); }; radeon_set(RADEON_LVDS_GEN_CNTL,"RADEON_LVDS_GEN_CNTL",lvds_gen_cntl); } void radeon_cmd_stretch(char *param) { unsigned long fp_vert_stretch,fp_horz_stretch; if (!radeon_cntl_mem) exit(-1); fp_vert_stretch = radeon_get(RADEON_FP_VERT_STRETCH,"RADEON_FP_VERT_STRETCH"); fp_horz_stretch = radeon_get(RADEON_FP_HORZ_STRETCH,"RADEON_FP_HORZ_STRETCH"); if(param == NULL) { printf("The horizontal stretching looks %s\n",(fp_horz_stretch&(RADEON_HORZ_STRETCH_ENABLE))?"on":"off"); printf("The vertical stretching looks %s\n",(fp_vert_stretch&(RADEON_VERT_STRETCH_ENABLE))?"on":"off"); exit (-1); } else if(strncmp(param,"ver",3) == 0) { fp_horz_stretch &= ~ RADEON_HORZ_STRETCH_ENABLE; fp_vert_stretch |= RADEON_VERT_STRETCH_ENABLE; } else if(strncmp(param,"hor",3) == 0) { fp_horz_stretch |= RADEON_HORZ_STRETCH_ENABLE; fp_vert_stretch &= ~ RADEON_VERT_STRETCH_ENABLE; } else if(strcmp(param,"on") == 0) { fp_horz_stretch |= RADEON_HORZ_STRETCH_ENABLE; fp_vert_stretch |= RADEON_VERT_STRETCH_ENABLE; } else if(strcmp(param,"auto") == 0) { fp_horz_stretch |= RADEON_HORZ_AUTO_RATIO; fp_horz_stretch |= RADEON_HORZ_AUTO_RATIO_INC; fp_horz_stretch |= RADEON_HORZ_STRETCH_ENABLE; fp_vert_stretch |= RADEON_VERT_AUTO_RATIO_EN; fp_vert_stretch |= RADEON_VERT_STRETCH_ENABLE; } else if(strcmp(param,"manual") == 0) { fp_horz_stretch &= ~ RADEON_HORZ_AUTO_RATIO; fp_horz_stretch &= ~ RADEON_HORZ_AUTO_RATIO_INC; fp_horz_stretch |= RADEON_HORZ_STRETCH_ENABLE; fp_vert_stretch &= ~ RADEON_VERT_AUTO_RATIO_EN; fp_vert_stretch |= RADEON_VERT_STRETCH_ENABLE; } else if(strcmp(param,"off") == 0) { fp_horz_stretch &= ~ RADEON_HORZ_STRETCH_ENABLE; fp_vert_stretch &= ~ RADEON_VERT_STRETCH_ENABLE; } else { usage(); }; radeon_set(RADEON_FP_HORZ_STRETCH,"RADEON_FP_HORZ_STRETCH",fp_horz_stretch); radeon_set(RADEON_FP_VERT_STRETCH,"RADEON_FP_VERT_STRETCH",fp_vert_stretch); } /* Look for the Radeon hardware address. */ static void map_radeon_cntl_mem(void) { struct pci_slot_match match; struct pci_device_iterator *iter; struct pci_device *device; pciaddr_t fb_base, fb_size, ctrl_base, ctrl_size; int i = 0, ret; ret = pci_system_init(); if (ret) { fprintf(stderr, "error: failed to initialise libpciaccess: %s\n", strerror(ret)); return; } match.domain = PCI_MATCH_ANY; match.bus = PCI_MATCH_ANY; match.dev = PCI_MATCH_ANY; match.func = 0; match.match_data = 0; iter = pci_slot_match_iterator_create(&match); while ((device = pci_device_next(iter))) { pci_device_probe(device); if (device->vendor_id != 0x1002) continue; if ((device->device_class & 0x00ffff00) != 0x00030000) continue; if (debug) printf("Found card %x:%x (%x)\n", device->vendor_id, device->device_id, device->device_class); if (skip--) continue; break; } if (!device) { fprintf(stderr, "error: cannot find Radeon device\n"); return; } ctrl_base = device->regions[2].base_addr; ctrl_size = device->regions[2].size; if (!ctrl_size) { fprintf(stderr, "error: missing ctrl region\n"); return; } ret = pci_device_map_range(device, ctrl_base, ctrl_size, PCI_DEV_MAP_FLAG_WRITABLE, (void **) &ctrl_mem); if (ret) { fprintf(stderr, "cannot map ctrl region: %s\n", strerror(ret)); return; } fb_base = device->regions[0].base_addr; fb_size = device->regions[0].size; if (!fb_size || pci_device_map_range(device, fb_base, fb_size, PCI_DEV_MAP_FLAG_WRITABLE, (void **) &fb_mem)) fb_mem = NULL; pci_iterator_destroy(iter); if (debug) printf("Radeon found. Base control address is %lx; " "base framebuffer address is %lx.\n", (unsigned long) ctrl_mem, (unsigned long) fb_mem); if (!ctrl_mem) die("internal error"); radeon_cntl_mem = ctrl_mem; } #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); int rev; if (pll_info_block == 0) { printf("No clock info block in BIOS\n"); return; } rev = BIOS8(pll_info_block); printf("revision %d\n", rev); printf("Clock info block:\n"); printf(" SCLK : %f\n", BIOS16(pll_info_block + 0x0a) / 100.0); printf(" MCLK : %f\n", BIOS16(pll_info_block + 0x08) / 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); if (rev > 9) { printf(" VCO in Min: %f\n", BIOS32(pll_info_block + 0x36) / 100.0); printf(" VCO in Max: %f\n", BIOS32(pll_info_block + 0x3a) / 100.0); printf(" VCO out Min: %f\n", BIOS32(pll_info_block + 0x3e) / 100.0); printf(" VCO out Max: %f\n", BIOS32(pll_info_block + 0x42) / 100.0); } printf(" SPLL RefClk : %f\n", BIOS16(pll_info_block + 0x1a) / 100.0); printf(" SPLL ref div : %d\n", BIOS16(pll_info_block + 0x1c)); printf(" VCO Min: %f\n", BIOS32(pll_info_block + 0x1e) / 100.0); printf(" VCO Max: %f\n", BIOS32(pll_info_block + 0x22) / 100.0); printf(" MPLL RefClk : %f\n", BIOS16(pll_info_block + 0x26) / 100.0); printf(" MPLL ref div : %d\n", BIOS16(pll_info_block + 0x28)); printf(" VCO Min: %f\n", BIOS32(pll_info_block + 0x2a) / 100.0); printf(" VCO Max: %f\n", BIOS32(pll_info_block + 0x2e) / 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 in Min: %f\n", BIOS16(pll_info_block + 74) / 100.0); printf(" PPLL in Max: %f\n", BIOS16(pll_info_block + 76) / 100.0); printf(" PPLL out Min: %f\n", BIOS16(pll_info_block + 78) / 100.0); printf(" PPLL out 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 < entries; 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)); if (((tmp >> 8) & 0xf) == 5) { printf(", DDC:0x%x", BIOS8(entry+2)); } else { 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(", MUX switch:%s", (tmp & 0x20) ? "yes" : "no"); 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, "SCART"}, { 10, "HDMI A"}, { 11, "HDMI B"}, { 14, "Special DIN"}, { 15, "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<16; i++) { if (tmp & (1<> 8) & 0xf; dac = (portinfo & 0xf) - 1; connector = (portinfo >> 4) & 0xf; printf("output id: %d\n", crtc); 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 if (i==9) printf(" TMDS: LVTMA\n"); else printf("\n"); } } } static void radeon_rom_legacy_lcdtable(unsigned char *bios, int hdr) { int offset, i, type_info, extended_offset; unsigned int setup; char stmp[30]; offset = BIOS16(hdr + 0x40); if (offset == 0) { printf("No LCD info table\n"); return; } printf("\nLCD info table:\n"); printf("lcd panel id: %d\n", BIOS8(offset)); for (i = 0; i < 24; i++) stmp[i] = BIOS8(offset+i+1); stmp[24] = 0; printf("lcd panel id string: %s\n", stmp); printf("lcd panel x: %d\n", BIOS16(offset+0x19)); printf("lcd panel y: %d\n", BIOS16(offset+0x1b)); type_info = BIOS16(offset+0x1d); if (type_info & 0x1) printf("color "); else printf("mono "); if (type_info & 0x2) printf("single "); else printf("dual "); switch ((type_info & 0xfc) >> 2) { case 0: printf("STN\n"); break; case 1: default: printf("TFT\n"); break; case 2: printf("active addressed STN\n"); break; case 3: printf("EL\n"); break; case 4: printf("Plasma\n"); break; } printf("lcd panel power delay: %d\n", BIOS16(offset+0x24)); extended_offset = BIOS16(offset+0x26); if (extended_offset) { int extended_rev; extended_rev = BIOS8(extended_offset); printf("lcd panel extended info offset: %x\n", extended_offset); printf("lcd extended info rev: %x\n", extended_rev); printf("SS delay %x step size %x\n", BIOS8(extended_offset+1), BIOS8(extended_offset + 2)); if (extended_rev > 1) { printf("lcd fake edid id num bytes %d\n", BIOS8(extended_offset+3)); printf("lcd fake edid id num offset 0x%x\n", BIOS16(extended_offset+4)); } if (extended_rev > 2) { printf("lcd LVPVS %x\n", BIOS8(extended_offset+6)); printf("lcd PVG/PCP %x\n", BIOS8(extended_offset+7)); printf("lcd SSPLL table offset %x\n", BIOS16(extended_offset+8)); } if (extended_rev > 3) { printf("lcd resp time coeff 0x%x\n", BIOS8(extended_offset+10)); } if (extended_rev > 4) { printf("edid low refresh offset 0x%x\n", BIOS16(extended_offset+11)); } } printf("lcd panel vcc delay: %d\n", BIOS16(offset+0x2c)); printf("lcd panel ref div: %d\n", BIOS16(offset+0x2e)); printf("lcd panel post div: %d\n", BIOS8(offset+0x30)); printf("lcd panel fb div: %d\n", BIOS16(offset+0x31)); printf("SS type: %s / %s\n", (BIOS8(offset + 0x33) & 1) ? "center" : "down", (BIOS8(offset + 0x33) & (1<<7)) ? "internal" : "external"); printf("SS percentage %x\n", BIOS16(offset + 0x34)); printf("lcd panel DIGON to LVDS active: %d\n", BIOS8(offset+0x38) & 0xf); printf("lcd panel LVDS active to BLON: %d\n", (BIOS8(offset+0x38) >> 4) & 0xf); setup = BIOS32(offset+0x39); printf("lcd panel LVDS setup: 0x%x\n", setup); if (setup & 0x1) printf("888 RGB\n"); else printf("666 RGB\n"); switch ((setup >> 8) & 0x8) { case 0: printf("no frame modulation\n"); break; case 1: printf("2 levels of grey\n"); break; case 2: printf("4 levels of grey\n"); break; default: printf("STN panel\n"); break; } if ((setup >> 16) & 0x1) printf("frame pulse high\n"); else printf("frame pulse low\n"); if ((setup >> 17) & 0x1) printf("line pulse high\n"); else printf("line pulse low\n"); if ((setup >> 18) & 0x1) printf("MOD high\n"); else printf("MOD low\n"); if ((setup >> 23) & 0x1) printf("backlight mod 29 Mhz\n"); else printf("backlight mod 29 Mhz / 3\n"); } static void radeon_rom_legacy_mobiletable(unsigned char *bios, int hdr) { int offset, rev, i, gpiooffset, blocks, powerplayoffset, lcdddcoffset, tmdspoweroffset; unsigned int reg, andmask, ormask; offset = BIOS16(hdr + 0x42); if (offset == 0) { printf("No mobile info table\n"); return; } rev = BIOS8(offset); printf("mobile table revision: %d\n", rev); switch (BIOS8(offset + 0x8) & 0xf) { case 1: printf("CRT i2c clk=GPIO0, data=GPIO1\n"); break; case 2: printf("CRT i2c clk=GPIO4, data=GPIO3\n"); break; default: printf("%d\n", BIOS8(offset + 0x8) & 0xf); break; } gpiooffset = BIOS16(offset+0x13); if (gpiooffset) { printf("gpio table revision: %d\n", BIOS8(gpiooffset)); blocks = BIOS8(gpiooffset + 0x2); printf("gpio blocks: %d\n", blocks); for (i = 0; i < blocks; i++) { reg = BIOS16(gpiooffset + 3 + (i * 10) + 0); andmask = BIOS32(gpiooffset + 3 + (i * 10) + 0x2); ormask = BIOS32(gpiooffset + 3 + (i * 10) + 0x6); printf("reg: 0x%x, AND: 0x%x, OR: 0x%x\n", reg * 4, andmask, ormask); } } powerplayoffset = BIOS16(offset+0x11); if (powerplayoffset) { unsigned int powerplay_flags; int powerplay_rev = BIOS8(powerplayoffset); printf("powerplay table revision: %d\n", powerplay_rev); printf("powerplay table size: %d bytes\n", BIOS8(powerplayoffset) + 1); blocks = BIOS8(powerplayoffset+0x2); printf("powerplay states: %d\n", blocks); for (i = 0; i < blocks; i++) { printf("state %d\n", i); powerplay_flags = BIOS16(powerplayoffset + 5 + (i * 0x10)); if (powerplay_flags & 0x1) printf("\tMCLK_SRC_SPLL\n"); else if (powerplay_flags & 0x2) printf("\tSCLK_SRC_MPLL\n"); else printf("\tsplit clock\n"); if (powerplay_flags & 0x4) { printf("\tvoltage drop supported\n"); if (powerplay_flags & 0x8) printf("\tvoltage drop active high\n"); else printf("\tvoltage drop active low\n"); } if (powerplay_flags & 0x10) printf("\tlcd refresh rate change\n"); if (powerplay_flags & 0x20) printf("\tengine clk control enabled\n"); if (powerplay_flags & 0x40) printf("\tmemory clk control enabled\n"); if (powerplay_flags & 0x80) printf("\toverclock mode\n"); else if (powerplay_rev <= 3) printf("\tpowersave mode\n"); if (powerplay_flags & 0x100) printf("\thalf engine clk\n"); if (powerplay_flags & 0x200) printf("\tdynamic voltage control enabled\n"); if (powerplay_flags & 0x400) printf("\tpower state sleep mode enabled\n"); if (powerplay_flags & 0x800) printf("\tpower state load balancing enabled\n"); if (powerplay_flags & 0x1000) printf("\tdefault DC state\n"); if (powerplay_flags & 0x2000) printf("\tdefault DC low state\n"); if (powerplay_rev > 3) { if (powerplay_flags & 0x4000) printf("\tpowersave mode\n"); if (powerplay_flags & 0x8000) printf("\tthermal diode mode\n"); } printf("\tmclk/sclk: %f/%f\n", BIOS32(powerplayoffset + 5 + (i * 0x10) + 0x2) / 100.0, BIOS32(powerplayoffset + 5 + (i * 0x10) + 0x6) / 100.0); switch (BIOS8(powerplayoffset + 5 + (i * 0x10) + 0xa)) { case 0: printf("\tLCD refresh: 50 Hz\n"); break; case 2: printf("\tLCD refresh: 56 Hz\n"); break; case 4: printf("\tLCD refresh: 60 Hz\n"); break; case 6: printf("\tLCD refresh: 67 Hz\n"); break; case 8: printf("\tLCD refresh: 70 Hz\n"); break; case 10: printf("\tLCD refresh: 72 Hz\n"); break; case 12: printf("\tLCD refresh: 75 Hz\n"); break; case 14: printf("\tLCD refresh: 76 Hz\n"); break; case 16: printf("\tLCD refresh: 85 Hz\n"); break; case 18: printf("\tLCD refresh: 90 Hz\n"); break; case 20: printf("\tLCD refresh: 100 Hz\n"); break; case 22: printf("\tLCD refresh: 120 Hz\n"); break; case 24: printf("\tLCD refresh: 140 Hz\n"); break; case 26: printf("\tLCD refresh: 150 Hz\n"); break; case 28: printf("\tLCD refresh: 160 Hz\n"); break; case 30: printf("\tLCD refresh: 200 Hz\n"); break; case 1: printf("\tLCD refresh: 40 Hz\n"); break; case 3: printf("\tLCD refresh: 30 Hz\n"); break; default: break; } if (powerplay_rev < 6) { printf("\tvoltage control reg: 0x%x\n", BIOS16(powerplayoffset + 5 + (i * 0x10) + 0xb) * 4); printf("\tvoltage control bits: %d\n", BIOS8(powerplayoffset + 5 + (i * 0x10) + 0xd)); } else { int j; int entries = BIOS8(powerplayoffset + 5 + (i * 0x10) + 0xb); int voltage_table_offset = BIOS16(powerplayoffset + 5 + (i * 0x10) + 0xc); if (entries && voltage_table_offset) { printf("\t%d entries in voltage drop table\n", entries); printf("\tvoltage drop table at 0x%x\n", voltage_table_offset); for (j = 0; j < entries; j++) { printf("\t\tvoltage drop register: 0x%x\n", BIOS16(voltage_table_offset) * 4); printf("\t\tvoltage drop register bits: %d\n", BIOS8(voltage_table_offset + 0x2)); } } } if (powerplay_rev < 5) { if (BIOS16(powerplayoffset + 5 + (i * 0x10) + 0xe)) printf("\tpowerplay memory reset table at 0x%x\n", BIOS16(powerplayoffset + 5 + (i * 0x10) + 0xe)); } else { int powerplay_flags2 = BIOS16(powerplayoffset + 5 + (i * 0x10) + 0xe); if (powerplay_flags2 & 0x1) printf("\tenable frame modulation w/ 2 level grey\n"); else if (powerplay_flags2 & 0x2) printf("\tenable frame modulation w/ 4 level grey\n"); else printf("\tdisable frame modulation\n"); if (powerplay_flags2 & 0x4) printf("\tenable dynamic half clock\n"); if (powerplay_flags2 & 0x8) printf("\tenable dynamic clock on static screen\n"); if (powerplay_flags2 & 0x10) printf("\tenable dynamic clocking in 2D\n"); if ((powerplay_flags2 & 0xe0) == 0x20) printf("\tdynamic clocking divider: 1/2\n"); else if ((powerplay_flags2 & 0xe0) == 0x40) printf("\tdynamic clocking divider: 1/3\n"); else if ((powerplay_flags2 & 0xe0) == 0x60) printf("\tdynamic clocking divider: 1/4\n"); printf("\tdelay between voltage drop and sclk change: "); if ((powerplay_flags2 & 0x700) == 0) printf("no delay\n"); else if ((powerplay_flags2 & 0x700) == 0x100) printf("33 us\n"); else if ((powerplay_flags2 & 0x700) == 0x200) printf("66 us\n"); else if ((powerplay_flags2 & 0x700) == 0x300) printf("99 us\n"); else if ((powerplay_flags2 & 0x700) == 0x400) printf("132 us\n"); if (powerplay_rev > 6) { int pcie_lanes; if (powerplay_flags2 & 0x800) printf("\tperformance mode\n"); if (powerplay_flags2 & 0x1000) printf("\tvri-brightness required\n"); pcie_lanes = BIOS8(powerplayoffset + 5 + (i * 0x10) + 0x10); if (pcie_lanes == 0) pcie_lanes = 16; printf("\t%d pcie lanes\n", pcie_lanes); } } } } lcdddcoffset = BIOS16(offset+0x15); if (lcdddcoffset) { int i2cline; printf("LCD DDC table revision: %d\n", BIOS8(lcdddcoffset)); i2cline = BIOS8(lcdddcoffset+0x2); printf("LCD DDC table i2c line: %d\n", i2cline); if (i2cline > 4) { printf("LCD DDC table i2c clock pin mask: 0x%x\n", BIOS32(lcdddcoffset+0x3)); printf("LCD DDC table i2c data pin mask: 0x%x\n", BIOS32(lcdddcoffset+0x7)); } } tmdspoweroffset = BIOS16(offset+0x17); if (tmdspoweroffset) { int tmdsflags = BIOS8(tmdspoweroffset + 1); int ontable_offset = BIOS16(tmdspoweroffset + 2); int ontable_rev = BIOS8(ontable_offset); int offtable_offset = BIOS16(tmdspoweroffset + 4); int offtable_rev = BIOS8(offtable_offset); printf("tmds power on/off table at offset: 0x%x\n", tmdspoweroffset); printf("tmds power on/off table revision: %d\n", BIOS8(tmdspoweroffset)); if (tmdsflags & 1) printf("external tmds\n"); else printf("internal tmds\n"); printf("tmds power on table revision: %d\n", ontable_rev); if (ontable_rev == 1) { // fix me } else if (ontable_rev == 2) { int j = 4; int type; int blocks = BIOS8(ontable_offset + 3); int start = BIOS16(ontable_offset + j); int size = BIOS16(ontable_offset + 1); printf("tmds on table size: %d bytes\n", size); printf("tmds on table blocks: %d \n", blocks); while (blocks > 0) { type = (start & 0xe000) >> 13; if (type == 0) { unsigned int reg = BIOS16(ontable_offset + j) & 0x1fff; unsigned int val = BIOS32(ontable_offset + j + 2); printf("mmio reg: 0x%x, val: 0x%x\n", reg, val); j += 6; } else if (type == 2) { unsigned int reg = BIOS16(ontable_offset + j) & 0x1fff; unsigned int and_mask = BIOS32(ontable_offset + j + 2); unsigned int or_mask = BIOS32(ontable_offset + j + 6); printf("mmio reg: 0x%x, AND mask: 0x%x, OR mask: 0x%x\n", reg * 4, and_mask, or_mask); j += 10; } else if (type == 3) { printf("delay %d ms\n", BIOS16(ontable_offset + j + 2)); j += 4; } else if (type == 4) { printf("delay %d us\n", BIOS16(ontable_offset + j + 2)); j += 4; } else if (type == 6) { int i2c_slave_addr = BIOS16(ontable_offset + j) & 0xff; int i2c_id = BIOS8(ontable_offset + j + 2); int i2c_reg = BIOS8(ontable_offset + j + 3); int i2c_reg_val = BIOS8(ontable_offset + j + 4); printf("write to i2c addr 0x%x (i2c id %d) reg: 0x%x, val: 0x%x\n", i2c_slave_addr, i2c_id, i2c_reg, i2c_reg_val); j += 5; } else break; blocks--;; start = BIOS16(ontable_offset + j); } } printf("tmds power off table revision: %d\n", offtable_rev); if (offtable_rev == 1) { // fix me } else if (offtable_rev == 2) { int j = 4; int type; int blocks = BIOS8(offtable_offset + 3); int start = BIOS16(offtable_offset + j); int size = BIOS16(offtable_offset + 1); printf("tmds off table size: %d bytes\n", size); printf("tmds off table blocks: %d \n", blocks); while (blocks > 0) { type = (start & 0xe000) >> 13; if (type == 0) { unsigned int reg = BIOS16(offtable_offset + j) & 0x1fff; unsigned int val = BIOS32(offtable_offset + j + 2); printf("mmio reg: 0x%x, val: 0x%x\n", reg, val); j += 6; } else if (type == 2) { unsigned int reg = BIOS16(offtable_offset + j) & 0x1fff; unsigned int and_mask = BIOS32(offtable_offset + j + 2); unsigned int or_mask = BIOS32(offtable_offset + j + 6); printf("pll reg: 0x%x, AND mask: 0x%x, OR mask: 0x%x\n", reg * 4, and_mask, or_mask); j += 10; } else if (type == 3) { printf("delay %d ms\n", BIOS16(offtable_offset + j + 2)); j += 4; } else if (type == 4) { printf("delay %d us\n", BIOS16(offtable_offset + j + 2)); j += 4; } else if (type == 6) { int i2c_slave_addr = BIOS16(offtable_offset + j) & 0xff; int i2c_id = BIOS8(offtable_offset + j + 2); int i2c_reg = BIOS8(offtable_offset + j + 3); int i2c_reg_val = BIOS8(offtable_offset + j + 4); printf("write to i2c addr 0x%x (i2c id %d) reg: 0x%x, val: 0x%x\n", i2c_slave_addr, i2c_id, i2c_reg, i2c_reg_val); j += 5; } else break; blocks--; start = BIOS16(offtable_offset + j); } } } if (rev > 7) { int external_ss_table = BIOS16(offset+0x15); if (external_ss_table) { printf("External SS table present %d\n", external_ss_table); printf("revision %d size bytes %d block %d\n", BIOS8(external_ss_table), BIOS8(external_ss_table + 1), BIOS8(external_ss_table + 2)); printf("header bytes %d\n", BIOS8(external_ss_table + 3)); } } } 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_crttable(unsigned char *bios, int hdr) { int offset, rev, dac2table, dac2muxreg, bgadjcrt1, dacwhitecrt1, bgadjcrt2, dacadjcrt2, temp; offset = BIOS16(hdr + 0x60); if (offset == 0) { printf("No CRT info table\n"); return; } rev = BIOS8(offset) & 0x3; printf("\nCRT table revision: %d\n", rev); printf("\nCRT table size: %d bytes\n", BIOS8(offset+1)); if (rev == 2) { bgadjcrt1 = BIOS8(offset + 0x2); dacwhitecrt1 = BIOS8(offset + 0x3); printf("crt1: 0x%x, 0x%x\n", bgadjcrt1, dacwhitecrt1); bgadjcrt2 = BIOS8(offset + 0x4); dacadjcrt2 = BIOS8(offset + 0x5); printf("crt2: 0x%x, 0x%x\n", bgadjcrt2, dacadjcrt2); dac2table = BIOS16(offset+8); } else { bgadjcrt1 = BIOS8(offset + 0x2) & 0xf; dacwhitecrt1 = (BIOS8(offset + 0x2) >> 4) & 0xf; printf("crt1: 0x%x, 0x%x\n", bgadjcrt1, dacwhitecrt1); bgadjcrt2 = BIOS8(offset + 0x3) & 0xf; dacadjcrt2 = (BIOS8(offset + 0x3) >> 4) & 0xf; printf("crt2: 0x%x, 0x%x\n", bgadjcrt2, dacadjcrt2); dac2table = BIOS16(offset + 0x5); } printf("reg val 0x%x\n", (bgadjcrt2 << 16) | (dacadjcrt2 << 20)); if (dac2table) { printf("\nDac2 table: 0x%x\n", dac2table); printf("revision: %d\n", (BIOS16(dac2table) & 0x3)); dac2muxreg = BIOS16(dac2table + 0x2); printf("\nmux reg: 0x%x\n", dac2muxreg); temp = BIOS8(dac2table + 0x4); if (temp & 0x80) printf("CRT2 active high\n"); else printf("CRT2 active low\n"); printf("pin detection bits: 0x%x\n", (temp & 0x1f)); printf("access mode: 0x%x\n", ((temp >> 5) & 0x3)); } } static void radeon_rom_legacy_list_tables_present(unsigned char *bios, int hdr) { int offset; offset = BIOS16(hdr + 0xc); if (offset) { printf("asic init table 1\n"); } offset = BIOS16(hdr + 0x14); if (offset) { printf("bios support info table\n"); } offset = BIOS16(hdr + 0x2a); if (offset) { printf("dac programming info table\n"); } offset = BIOS16(hdr + 0x2c); if (offset) { printf("max color depth info table\n"); } offset = BIOS16(hdr + 0x2e); if (offset) { printf("crtc info table\n"); } offset = BIOS16(hdr + 0x30); if (offset) { printf("pll info table\n"); } offset = BIOS16(hdr + 0x32); if (offset) { printf("TV info table\n"); } offset = BIOS16(hdr + 0x34); if (offset) { printf("DFP info table\n"); } offset = BIOS16(hdr + 0x36); if (offset) { printf("HW config info table\n"); } offset = BIOS16(hdr + 0x38); if (offset) { printf("multimedia info table\n"); } offset = BIOS16(hdr + 0x3e); if (offset) { printf("tv standard patch table\n"); } offset = BIOS16(hdr + 0x40); if (offset) { printf("LCD info table\n"); } offset = BIOS16(hdr + 0x42); if (offset) { printf("Mobile info table\n"); } offset = BIOS16(hdr + 0x46); if (offset) { printf("pll init info table\n"); } offset = BIOS16(hdr + 0x48); if (offset) { int check_offset = offset; printf("mem config info table\n"); while (BIOS8(check_offset++)); check_offset += 2; if (check_offset) printf("mem ram reset table %d %x %x\n", check_offset, BIOS8(check_offset -2), BIOS8(check_offset - 1)); } offset = BIOS16(hdr + 0x4a); if (offset) { printf("save mask info table\n"); } offset = BIOS16(hdr + 0x4c); if (offset) { printf("Hardcoded DFP edid\n"); } offset = BIOS16(hdr + 0x4e); if (offset) { printf("asic init table 2\n"); } offset = BIOS16(hdr + 0x50); if (offset) { printf("connector info table\n"); } offset = BIOS16(hdr + 0x52); if (offset) { printf("dyn clock 1 info table\n"); } offset = BIOS16(hdr + 0x54); if (offset) { printf("reserved mem info table\n"); } offset = BIOS16(hdr + 0x58); if (offset) { printf("Ext TMDS info table\n"); } offset = BIOS16(hdr + 0x5a); if (offset) { printf("mem clock info table\n"); } offset = BIOS16(hdr + 0x5c); if (offset) { printf("ext DAC info table\n"); } offset = BIOS16(hdr + 0x5e); if (offset) { printf("misc info table\n"); } offset = BIOS16(hdr + 0x60); if (offset) { printf("CRT info table\n"); } offset = BIOS16(hdr + 0x62); if (offset) { printf("integrated system info table\n"); } offset = BIOS16(hdr + 0x64); if (offset) { printf("Component video info table\n"); } offset = BIOS16(hdr + 0x66); if (offset) { printf("fan speed info table\n"); } offset = BIOS16(hdr + 0x68); if (offset) { printf("overdrive info table\n"); } offset = BIOS16(hdr + 0x6a); if (offset) { printf("OEM info table\n"); } offset = BIOS16(hdr + 0x6c); if (offset) { printf("dyn clock 2 info table\n"); } offset = BIOS16(hdr + 0x6e); if (offset) { printf("power connector info table\n"); } offset = BIOS16(hdr + 0x70); if (offset) { printf("i2c info table\n"); } offset = BIOS16(hdr + 0x72); if (offset) { printf("object header info table\n\n"); } printf("\n"); } static void radeon_rom_legacy_biosinfotable(unsigned char *bios, int hdr) { int offset, i; char strp[4]; offset = BIOS16(hdr + 0x14); if (offset == 0) { printf("bios info table\n"); return; } printf("bios info table\n"); for (i = 0; i < 4; i++) strp[i] = BIOS8(offset + i); printf("chip type: %s\n", strp); for (i = 0; i < 4; i++) strp[i] = BIOS32(offset + 4 + i); printf("bus type: %s\n", strp); for (i = 0; i < 4; i++) strp[i] = BIOS32(offset + 8 + i); printf("mem type: %s\n", strp); } static void radeon_rom_legacy_miscinfotable(unsigned char *bios, int hdr) { int offset, rev, start, size; offset = BIOS16(hdr + 0x5e); if (offset == 0) { printf("No misc info table\n"); return; } rev = BIOS8(offset); printf("misc info table revision: %d\n", rev); if (rev > 0) { size = BIOS8(offset + 2); printf("misc info table size: %d bytes\n", size); } start = BIOS8(offset + 1); if (start & 0x1) printf("dualview supported\n"); if (rev == 8) if (start & 0x8) printf("sleep mode enabled in perfomance mode\n"); if (start & 0x20) printf("hypermemory flag\n"); if (rev == 5) { if (start & 0x40) printf("sleep mode enabled in perfomance mode\n"); } else if (rev == 8) { if (start & 0x40) printf("power state load balancing is enabled in perfomance mode\n"); } if (rev == 6) if (start & 0x80) printf("WMI thermal method supported\n"); if (rev > 0) { if (BIOS16(offset + 0x3)) { printf("asic init table 3 offset: 0x%x\n", BIOS16(offset + 0x3)); radeon_rom_legacy_mmio_table(bios, BIOS16(offset + 0x3)); } if (BIOS16(offset + 0x5)) { printf("asic init table 4 offset: 0x%x\n", BIOS16(offset + 0x5)); radeon_rom_legacy_mmio_table(bios, BIOS16(offset + 0x5)); } if (BIOS16(offset + 0x7)) printf("detected mem config table offset: 0x%x\n", BIOS16(offset + 0x7)); if (rev == 2) { if (BIOS16(offset + 0x9)) printf("asic init table 5 offset: 0x%x\n", BIOS16(offset + 0x9)); if (BIOS16(offset + 0xb)) printf("memreset sequence table offset: 0x%x\n", BIOS16(offset + 0xb)); } else if ((rev == 4) || (rev == 5) || (rev == 6)) { if (BIOS16(offset + 0x9)) printf("pointer to asic init table 5 offset list: 0x%x\n", BIOS16(offset + 0x9)); if (BIOS16(offset + 0xb)) printf("pointer to memreset sequence table offset list: 0x%x\n", BIOS16(offset + 0xb)); } if ((rev == 5) || (rev == 6)) { if (BIOS16(offset + 0xd)) printf("mem info table offset: 0x%x\n", BIOS16(offset + 0xd)); printf("min backlight value: 0x%x\n", BIOS8(offset + 0xf)); } if (rev == 7) { if (BIOS16(offset + 0x7)) printf("pointer to detected mem config table offset list: 0x%x\n", BIOS16(offset + 0x7)); if (BIOS16(offset + 0x9)) printf("pointer to asic init table 5 offset list: 0x%x\n", BIOS16(offset + 0x9)); if (BIOS16(offset + 0xb)) printf("pointer to memreset sequence table offset list: 0x%x\n", BIOS16(offset + 0xb)); } if (rev >= 6) { int flags = BIOS8(offset + 0x10); if (flags & 0x1) printf("driver controls brightness\n"); if (flags & 0x2) printf("bios controls powerplay\n"); if (flags & 0x4) printf("use new mem reset sequence\n"); if (flags & 0x8) printf("power state load balancing is disabled in performance mode\n"); if (rev == 9) if (flags & 0x40) printf("PCIE to PCI bridge present\n"); } } } static void radeon_rom_legacy_ram_reset_table(unsigned char *bios, int hdr) { int offset = BIOS16(hdr + 0x48); uint32_t val; if (!offset) return; while (BIOS8(offset++)); offset += 2; printf("ram reset table %d rev %d and mask %x\n", offset, BIOS8(offset - 1), BIOS8(offset - 2)); val = BIOS8(offset); while(val != 0xff) { offset++; if (val == 0x0f) { printf("pwup complete test\n"); } else { uint32_t or_mask = BIOS16(offset); offset+=2; printf("rmw SDRAM mask %x %x\n", or_mask, val); } val = BIOS8(offset); } } static void radeon_rom_legacy_mmio_table(unsigned char *bios, int offset) { if (!offset) return; while (BIOS16(offset)) { uint16_t cmd = (BIOS16(offset) & 0xe000) >> 13; uint32_t addr = BIOS16(offset) & 0x1fff; uint32_t val, and_mask, or_mask, tmp; offset+=2; switch(cmd) { case 0: case 1: val = BIOS32(offset); offset += 4; printf("write reg %x %x\n", addr, val); break; case 2: case 3: and_mask = BIOS32(offset); offset += 4; or_mask = BIOS32(offset); offset += 4; printf("write reg %x and %x or %x val\n", addr, and_mask, or_mask); break; case 4: val = BIOS16(offset); offset += 2; printf("delay %x\n", val); break; case 5: val = BIOS16(offset); offset += 2; switch (addr) { case 8: printf("wait for CLK_PWRMGR CNTL MC busy %x\n", val); break; case 9: printf("wait for MC_STATUS MC idle %x\n", val); break; } break; default: printf("unknown\n"); } } } static void radeon_rom_legacy_asicinittable(unsigned char *bios, int hdr) { int offset = BIOS16(hdr + 0xc); if (offset) { printf("asic init table 1\n"); radeon_rom_legacy_mmio_table(bios, offset); } offset = BIOS16(hdr + 0x4e); if (offset) { printf("-----------------\n"); printf("asic init table 2\n"); radeon_rom_legacy_mmio_table(bios, offset); } } static void radeon_rom_legacy_plltable(unsigned char *bios, int offset) { int type, start, i = 0; start = BIOS8(offset); while (start != 0) { type = (start & 0xc0) >> 6; if (type == 0) { int reg = BIOS8(offset + i) & 0x3f; unsigned int val = BIOS32(offset + i + 1); printf("pll reg: 0x%x, val: 0x%x\n", reg, val); i += 5; } else if (type == 1) { int reg = BIOS8(offset + i) & 0x3f; int byte_offset = BIOS8(offset + i + 1); int and_mask = BIOS8(offset + i + 2); int or_mask = BIOS8(offset + i + 3); printf("pll reg: 0x%x, byte offset of dword 0x%x, AND mask: 0x%x, OR mask: 0x%x\n", reg, byte_offset, and_mask, or_mask); i += 4; } else if (type >= 2) { int cmd = BIOS8(offset + i) & 0x3f; switch (cmd) { case 1: printf("delay 150 us\n"); break; case 2: printf("delay 1 ms\n"); break; case 3: printf("wait for MC_BUSY = 0 in CLK_PWRMGT_CNTL\n"); break; case 4: printf("wait for DLL_READY = 1 in CLK_PWRMGT_CNTL\n"); break; case 5: printf("check and set bit 24 in CLK_PWRMGT_CNTL to 0\n"); break; default: printf("ass\n"); break; } i += 1; } else break; start = BIOS8(offset + i); } } static void radeon_rom_legacy_dynclk1table(unsigned char *bios, int hdr) { int offset, type, start, i = 0; offset = BIOS16(hdr + 0x52); if (offset == 0) { printf("No dyn clock 1 info table\n"); return; } printf("dyn clock 1 info table\n"); radeon_rom_legacy_plltable(bios, offset); } static void radeon_rom_legacy_pllinittable(unsigned char *bios, int hdr) { int offset, type, start, i = 0; offset = BIOS16(hdr + 0x46); if (offset == 0) { return; } printf("pll init table %x\n", BIOS8(offset - 1)); radeon_rom_legacy_plltable(bios, offset); } static void radeon_rom_legacy_dynclk2table(unsigned char *bios, int hdr) { int offset, type, start, rev, i = 0; offset = BIOS16(hdr + 0x52); if (offset == 0) { printf("No dyn clock 2 info table\n"); return; } rev = BIOS8(offset - 1); start = BIOS16(offset); printf("dyn clock 2 info table revision %d\n", rev); while (start != 0) { type = (start & 0xe000) >> 13; if (type == 0) { unsigned int reg = BIOS16(offset + i) & 0x1fff; unsigned int val = BIOS32(offset + i + 2); printf("mmio reg: 0x%x, val: 0x%x\n", reg * 4, val); i += 6; } else if (type == 1) { unsigned int reg = BIOS16(offset + i) & 0x1fff; unsigned int val = BIOS32(offset + i + 2); printf("I/O reg: 0x%x, val: 0x%x\n", reg * 4, val); i += 6; } else if (type == 2) { unsigned int reg = BIOS16(offset + i) & 0x1fff; unsigned int and_mask = BIOS32(offset + i + 2); unsigned int or_mask = BIOS32(offset + i + 6); printf("mmio reg: 0x%x, AND mask: 0x%x, OR mask: 0x%x\n", reg * 4, and_mask, or_mask); i += 10; } else if (type == 3) { unsigned int reg = BIOS16(offset + i) & 0x1fff; unsigned int and_mask = BIOS32(offset + i + 2); unsigned int or_mask = BIOS32(offset + i + 6); printf("I/O reg: 0x%x, AND mask: 0x%x, OR mask: 0x%x\n", reg * 4, and_mask, or_mask); i += 10; } else if (type == 4) { printf("delay %d us\n", BIOS16(offset + i + 2)); i += 4; } else break; start = BIOS16(offset + i); } } static void radeon_rom_legacy_igptable(unsigned char *bios, int hdr) { int offset, rev, fsb; offset = BIOS16(hdr + 0x62); if (offset == 0) { printf("No igp info table\n"); return; } rev = BIOS8(offset); printf("\nigp table revision: %d\n", rev); fsb = BIOS16(offset + 0x2); if (rev < 2) fsb *= 100; printf("FSB: %f Mhz\n", fsb); printf("mclk reference frequency: %f Mhz\n", BIOS16(offset + 0x4) / 100.00); printf("mclk reference divider: %d \n", BIOS16(offset + 0x6)); printf("memory refresh period from SPD: %d \n", BIOS8(offset + 0x8)); if (rev > 0) printf("min mclk: %f \n", BIOS16(offset + 0xd) / 100.00); if (rev > 1) printf("max mclk: %f \n", BIOS16(offset + 0xf) / 100.00); if (rev > 2) { printf("K8 mclk: %f \n", BIOS16(offset + 0x11)); printf("K8 sync start delay: %f us\n", BIOS16(offset + 0x13) / 100); printf("K8 data return time: %f us\n", BIOS16(offset + 0x15) / 100); } if (rev > 3) { if (BIOS16(offset + 0x17) & 1) printf("PCIE lane reserved\n"); else printf("PCIE lane not reserved\n"); } } static void radeon_rom_legacy_componenttv_table(unsigned char *bios, int hdr) { int offset, rev, temp; offset = BIOS16(hdr + 0x62); if (offset == 0) { printf("No component tv info table\n"); return; } rev = BIOS8(offset); printf("\ncomponent tv table revision: %d\n", rev); if (rev < 3) { if (BIOS8(offset + 0x2) & 0x4) printf("CRT2 Mux used as well to switch to CV\n"); if (BIOS8(offset + 0x2) & 0x8) printf("Low voltage TV/CV MUX control\n"); } else { if (BIOS8(offset + 0x2) & 0x10) printf("enable access for i2c D-Connect Support\n"); } printf("GPIO register for detection: 0x%x \n", BIOS16(offset + 0x3)); temp = BIOS8(offset + 0x5); if (temp & 0x80) printf("Active high\n"); else printf("Active low\n"); printf("GPIO TV/HDTV MUX control register: 0x%x \n", BIOS16(offset + 0x6)); temp = BIOS8(offset + 0x8); if (temp & 0x80) printf("Active high\n"); else printf("Active low\n"); } static void radeon_rom_legacy_integratedtable(unsigned char *bios, int hdr) { int offset, rev, size; offset = BIOS16(hdr + 0x62); if (offset == 0) { printf("no igp table\n"); return; } rev = BIOS8(offset); size = BIOS8(offset + 1); printf("igp table rev %d size %d\n", rev, size); if (rev < 2) printf("FSB freq in Khz * 10 %d\n", BIOS16(offset + 2)); else printf("FSB freq in Mhz %d\n", BIOS16(offset + 2)); printf("Memory reference clock in Mhz * 100 %d\n", BIOS16(offset + 4)); printf("Memory reference divider %d\n", BIOS16(offset + 6)); if (rev >= 3) { printf("K8 memory clock %d\n", BIOS16(offset + 0x11)); } } static void radeon_rom_legacy_multimediatable(unsigned char *bios, int hdr) { int offset, rev, size; int tmp; offset = BIOS16(hdr + 0x38); if (offset == 0) { printf("no mm info table\n"); return; } rev = BIOS8(offset - 2); size = BIOS8(offset - 1); printf("mm table rev %d size %d\n", rev, size); tmp = BIOS8(offset); printf("tuner id %x - video input %d\n", tmp & 0x1f, (tmp >> 5) & 0x7); tmp = BIOS8(offset + 1); printf("audio chip %x\n", tmp & 0xf); printf("product %s - rev %d\n", tmp & 0x10 ? "ATI" : "OEM", tmp >> 5); printf("product ID %d\n", BIOS8(offset + 2)); tmp = BIOS8(offset + 3); printf("tuner regulator control %d\n", tmp & 0x3); printf("teletext support %d\n", (tmp >> 2) & 0x3); printf("fm audio decoder %d\n", (tmp >> 4) & 0x3); printf("audio scramming %d\n", tmp >> 7); tmp = BIOS8(offset + 4); printf("i2s input config %d, output config %d\n", tmp & 0x1, (tmp >> 1) & 0x1); printf("i2s audio chip %d\n", (tmp >> 2) & 0x3); tmp = BIOS8(offset + 5); printf("video decoder type %x\n", tmp & 0xf); printf("video crystal %d\n", (tmp >> 4) & 0xf); tmp = BIOS8(offset + 6); printf("video decoder config %d\n", tmp); } static void radeon_rom_legacy_i2ctable(unsigned char *bios, int hdr) { int offset, rev, size, blocks, i, id, reg, clock, data; offset = BIOS16(hdr + 0x70); if (offset == 0) { printf("No i2c info table\n"); return; } rev = BIOS8(offset); printf("\ni2c table revision: %d\n", rev); size = BIOS8(offset + 1); printf("i2c table size: %d\n", size); blocks = BIOS8(offset + 2); printf("i2c blocks: %d\n", blocks); for (i = 0; i < blocks; i++) { id = BIOS8(offset + 3 + (i * 5) + 0); reg = BIOS16(offset + 3 + (i * 5) + 1); clock = BIOS8(offset + 3 + (i * 5) + 3); data = BIOS8(offset + 3 + (i * 5) + 4); printf("id: %d, reg: 0x%x, clk: %d, data: %d\n", id, reg * 4, clock, data); } } static void radeon_rom_legacy_tvtable(unsigned char *bios, int hdr) { int offset, rev, refclk, drvstds, biosstds; offset = BIOS16(hdr + 0x32); if (offset == 0) { printf("No TV info table\n"); return; } rev = BIOS8(offset + 3); printf("\nTV table revision: %d\n", rev); printf("\nTV table size: %d\n", BIOS16(offset + 4)); if (BIOS8(offset + 6) == 'T') printf("TV out on board\n"); else printf("No TV out on board\n"); printf("Default Standard: "); switch (BIOS8(offset + 7)) { case 1: printf("NTSC\n"); break; case 2: printf("PAL\n"); break; case 3: printf("PAL-M\n"); break; case 4: printf("PAL-60\n"); break; case 5: printf("NTSC-J\n"); break; case 6: printf("SCART-PAL\n"); break; default: printf("Unknown standard\n"); break; } printf("TV Ref Clk: "); refclk = BIOS8(offset + 9) >> 2; if (refclk == 0) printf("29.498928713 MHz\n"); else if (refclk == 1) printf("28.636360000 MHz\n"); else if (refclk == 2) printf("14.318180000 MHz\n"); else if (refclk == 3) printf("27.000000000 MHz\n"); printf("TV standards supported by driver: "); drvstds = BIOS8(offset + 10); if (drvstds & 1) printf("NTSC "); if (drvstds & 2) printf("PAL "); if (drvstds & 4) printf("PAL-M "); if (drvstds & 8) printf("PAL-60 "); if (drvstds & 16) printf("NTSC-J "); if (drvstds & 32) printf("SCART-PAL"); printf("\n"); printf("TV standards supported by bios: "); biosstds = BIOS8(offset + 11); if (biosstds & 1) printf("NTSC "); if (biosstds & 2) printf("PAL "); if (biosstds & 4) printf("PAL-M "); if (biosstds & 8) printf("PAL-60 "); if (biosstds & 16) printf("NTSC-J "); if (biosstds & 32) printf("SCART-PAL"); printf("\n"); if (rev >= 5) { int temp, temp2; temp = BIOS8(offset + 0xc); temp2 = BIOS8(offset + 0xd); printf("crt2 ps2: 0x%x, 0x%x\n", temp, temp2); temp = BIOS8(offset + 0xe); temp2 = BIOS8(offset + 0xf); printf("crt2 pal: 0x%x, 0x%x\n", temp, temp2); temp = BIOS8(offset + 0x10); temp2 = BIOS8(offset + 0x11); printf("crt2 ntsc: 0x%x, 0x%x\n", temp, temp2); temp = BIOS16(offset + 0x12); printf("gpio reg: 0x%x\n", temp); temp = BIOS16(offset + 0x14); printf("gpio AND mask: 0x%x\n", temp); temp = BIOS16(offset + 0x18); printf("gpio OR mask: 0x%x\n", temp); } else if (rev >= 2) { int temp, temp2; temp = BIOS8(offset + 0xc) & 0xf; temp2 = (BIOS8(offset + 0xc) >> 4) & 0xf; printf("crt2 ps2: 0x%x, 0x%x\n", temp, temp2); temp = BIOS8(offset + 0xd) & 0xf; temp2 = (BIOS8(offset + 0xd) >> 4) & 0xf; printf("crt2 pal: 0x%x, 0x%x\n", temp, temp2); temp = BIOS8(offset + 0xe) & 0xf; temp2 = (BIOS8(offset + 0xe) >> 4) & 0xf; printf("crt2 ntsc: 0x%x, 0x%x\n", temp, temp2); if (rev > 2) { temp = BIOS8(offset + 0x10); printf("gpio bit: 0x%x\n", temp); } if (rev > 3) { temp = BIOS16(offset + 0x11); printf("gpio reg: 0x%x\n", temp); } } } static void radeon_rom_legacy_exttmdstable(unsigned char *bios, int hdr) { int offset, rev; int nr_blocks; int table_start; unsigned short index; unsigned short id; offset = BIOS16(hdr + 0x58); if (offset == 0) { printf("No External TMDS table found\n"); return; } rev = BIOS8(offset); printf("Found External TMDS Table rev %d\n", rev); if (rev == 2) printf("single link\n"); else if (rev == 3) printf("dual link\n"); printf("table size %08x\n", BIOS16(offset+1)); nr_blocks = BIOS8(offset+3); printf("no blocks %08x\n", nr_blocks); table_start = offset+4; printf("max freq %d, slave i2c %02x i2c %d conn id %d, flags %d\n", BIOS16(table_start), BIOS8(table_start+2), BIOS8(table_start+3), BIOS8(table_start+4), BIOS8(table_start+5)); index = table_start+6; printf("next short is %04X\n", BIOS16(index)>>13); id = BIOS16(index); printf("id is %04X %d\n", id, id & 0x1fff); while (id != 0xffff) { switch(id >> 13) { case 0: printf("mm write\n"); index += 6; break; case 2: printf("mm mask write\n"); index += 10; break; case 4: printf("delay microsec \n"); index += 4; break; case 5: printf("pll mask write \n"); index += 10; break; case 6: printf("i2c write %02X\n", BIOS8(index+2)); index += 3; break; default: printf("unknown id %d\n", id>>13); return; }; id = BIOS16(index); printf("id is %04X %d\n", id, id & 0x1fff); } } void radeon_rom_legacy_memclktable(unsigned char *bios, int hdr) { int offset = BIOS16(hdr + 0x5a); int block_rev; if (!offset) return; block_rev = BIOS8(offset); while (block_rev != 0xff) { printf("mem clock table header %d\n", block_rev); if (block_rev == 1) { printf("mem clock min %d ,max %d\n", BIOS16(offset + 1), BIOS16(offset + 3)); offset += 5; } if (block_rev == 2) { printf("pre mem clock reset table %d\n", BIOS16(offset + 1)); offset += 3; } if (block_rev == 3) { printf("pll change table %d\n", BIOS16(offset + 1)); offset += 3; } if (block_rev == 4) { printf("register change table %d\n", BIOS16(offset + 1)); offset += 3; } if (block_rev == 5) { printf("post memory clock reset seq table %d\n", BIOS16(offset + 1)); offset += 3; } if (block_rev == 6) { printf("mc register change table %d\n", BIOS16(offset + 1)); offset += 3; } if (block_rev == 7) { printf("pll pre clock lock table %d\n", BIOS16(offset + 1)); offset += 3; } if (block_rev == 8) { printf("pre clock change table %d\n", BIOS16(offset + 1)); offset += 3; } if (block_rev == 9) { printf("post memory clock reset seq table 2 %d\n", BIOS16(offset + 1)); offset += 3; } block_rev = BIOS8(offset); } } #define OF32(offset) (*((unsigned int *)(bios + (offset)))) #define _2K (2*1024) #define OF_TABLE_INIT1 1 #define OF_TABLE_INIT2 2 #define OF_TABLE_PLL 3 #define OF_TABLE_MEMINIT 4 void radeon_of_table(const char * file, int table) { unsigned char bios[_2K]; unsigned int reg, mask, val, op; int fd; int len; int count = 0; fd = open(file, O_RDONLY); if (fd < 0) { perror("can't open init file"); return; } memset(bios, 0, _2K); len = read(fd, bios, _2K); close(fd); while (len > 0) { switch(table) { case OF_TABLE_INIT1: len -= 12; reg = OF32(count); mask = OF32(count + 4); val = OF32(count + 8); printf("reg: 0x%x, mask 0x%x, val 0x%x\n", reg, mask, val); count += 12; break; case OF_TABLE_INIT2: len -= 16; reg = OF32(count); mask = OF32(count + 4); val = OF32(count + 8); op = OF32(count + 12); printf("reg: 0x%x, mask 0x%x, val 0x%x op 0x%x\n", reg, mask, val, op); count += 16; break; case OF_TABLE_PLL: len -= 16; reg = OF32(count); mask = OF32(count + 4); val = OF32(count + 8); op = OF32(count + 12); printf("pll reg: 0x%x, mask 0x%x, val 0x%x, op %x\n", reg, mask, val, op); if (op == 5) printf("delay 1 ms\n"); else if (op == 6) printf("delay 150 us\n"); else if (op) printf("unknown op %d\n", op); count += 16; break; case OF_TABLE_MEMINIT: len -= 4; val = OF32(count); if (val >> 16 == 0x6fff) printf("pwup complete test\n"); else { mask = val >> 24; val = val & 0xffff; printf("rmw SDRAM mask %x %x\n", val, mask); } count += 4; break; } } } 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) die("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_list_tables_present(bios, hdr); printf("-------------\n"); radeon_rom_legacy_asicinittable(bios, hdr); printf("-------------\n"); radeon_rom_legacy_pllinittable(bios, hdr); printf("-------------\n"); radeon_rom_legacy_ram_reset_table(bios, hdr); printf("-------------\n"); radeon_rom_legacy_clocks(bios, hdr); printf("-------------\n"); radeon_rom_legacy_connectors(bios, hdr); printf("-------------\n"); radeon_rom_legacy_dfptable(bios, hdr); printf("-------------\n"); radeon_rom_legacy_exttmdstable(bios, hdr); printf("-------------\n"); radeon_rom_legacy_tvtable(bios, hdr); printf("-------------\n"); radeon_rom_legacy_crttable(bios, hdr); printf("-------------\n"); radeon_rom_legacy_i2ctable(bios, hdr); printf("-------------\n"); radeon_rom_legacy_lcdtable(bios, hdr); printf("-------------\n"); radeon_rom_legacy_mobiletable(bios, hdr); printf("-------------\n"); radeon_rom_legacy_igptable(bios, hdr); printf("-------------\n"); radeon_rom_legacy_componenttv_table(bios, hdr); printf("-------------\n"); radeon_rom_legacy_dynclk1table(bios, hdr); printf("-------------\n"); radeon_rom_legacy_dynclk2table(bios, hdr); printf("-------------\n"); radeon_rom_legacy_miscinfotable(bios, hdr); printf("-------------\n"); radeon_rom_legacy_biosinfotable(bios, hdr); printf("-------------\n"); radeon_rom_legacy_memclktable(bios, hdr); printf("-------------\n"); radeon_rom_legacy_multimediatable(bios, hdr); printf("-------------\n"); radeon_rom_legacy_integratedtable(bios, hdr); printf("-------------\n"); } } int main(int argc,char *argv[]) { while (argc >= 2) { if(strcmp(argv[1],"--debug") == 0) { debug=1; argv++; argc--; } else if (strncmp(argv[1],"--skip=", 7) == 0) { skip=atoi(argv[1]+7); argv++; argc--; } else { break; } } if(argc == 2) { map_radeon_cntl_mem(); 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],"romtables") == 0) { radeon_rom_tables(argv[2]); return 0; } if(strcmp(argv[1],"oftablepll") == 0) { radeon_of_table(argv[2], OF_TABLE_PLL); return 0; } if(strcmp(argv[1],"oftableinit1") == 0) { radeon_of_table(argv[2], OF_TABLE_INIT1); return 0; } if(strcmp(argv[1],"oftableinit2") == 0) { radeon_of_table(argv[2], OF_TABLE_INIT2); return 0; } if(strcmp(argv[1],"oftablememinit") == 0) { radeon_of_table(argv[2], OF_TABLE_MEMINIT); return 0; } map_radeon_cntl_mem(); 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(argc == 4) { map_radeon_cntl_mem(); if(strcmp(argv[1],"regset") == 0) { radeon_reg_set(argv[2], strtoul(argv[3], NULL, 0)); return 0; } } else { map_radeon_cntl_mem(); } usage(); return 1; }