📄 r128.c
字号:
/*Rage 128 chipset driver */#include <stdlib.h>#include <stdio.h> #include <string.h>#include <unistd.h>#include <sys/mman.h>#include <errno.h>#include "vga.h"#include "libvga.h"#include "driver.h"#include "timing.h"#include "vgaregs.h"#include "interface.h"#include "accel.h"#include "vgapci.h"#include "r128_reg.h"typedef unsigned int CARD32;typedef unsigned short CARD16;typedef int Bool;static int r128_ramtype;static int BusCntl, CRTOnly, HasPanelRegs;typedef struct { CARD16 reference_freq; CARD16 reference_div; CARD32 min_pll_freq; CARD32 max_pll_freq; CARD16 xclk;} R128PLLRec, *R128PLLPtr;typedef struct { /* Common registers */ CARD32 ovr_clr; CARD32 ovr_wid_left_right; CARD32 ovr_wid_top_bottom; CARD32 ov0_scale_cntl; CARD32 mpp_tb_config; CARD32 mpp_gp_config; CARD32 subpic_cntl; CARD32 viph_control; CARD32 i2c_cntl_1; CARD32 gen_int_cntl; CARD32 cap0_trig_cntl; CARD32 cap1_trig_cntl; CARD32 bus_cntl; CARD32 config_cntl; CARD32 mem_vga_wp_sel; CARD32 mem_vga_rp_sel; /* Other registers to save for VT switches */ CARD32 dp_datatype; CARD32 gen_reset_cntl; CARD32 clock_cntl_index; CARD32 amcgpio_en_reg; CARD32 amcgpio_mask; /* CRTC registers */ CARD32 crtc_gen_cntl; CARD32 crtc_ext_cntl; CARD32 dac_cntl; CARD32 crtc_h_total_disp; CARD32 crtc_h_sync_strt_wid; CARD32 crtc_v_total_disp; CARD32 crtc_v_sync_strt_wid; CARD32 crtc_offset; CARD32 crtc_offset_cntl; CARD32 crtc_pitch; /* CRTC2 registers */ CARD32 crtc2_gen_cntl; /* Flat panel registers */ CARD32 fp_crtc_h_total_disp; CARD32 fp_crtc_v_total_disp; CARD32 fp_gen_cntl; CARD32 fp_h_sync_strt_wid; CARD32 fp_horz_stretch; CARD32 fp_panel_cntl; CARD32 fp_v_sync_strt_wid; CARD32 fp_vert_stretch; CARD32 lvds_gen_cntl; CARD32 tmds_crc; /* Computed values for PLL */ CARD32 dot_clock_freq; CARD32 pll_output_freq; int feedback_div; int post_div; /* PLL registers */ CARD32 ppll_ref_div; CARD32 ppll_div_3; CARD32 htotal_cntl; /* DDA register */ CARD32 dda_config; CARD32 dda_on_off; CARD32 vga_dda_config; CARD32 vga_dda_on_off; /* Pallet */ Bool palette_valid; CARD32 palette[256];} R128SaveRec, *R128SavePtr;typedef struct { /* All values in XCLKS */ int ML; /* Memory Read Latency */ int MB; /* Memory Burst Length */ int Trcd; /* RAS to CAS delay */ int Trp; /* RAS percentage */ int Twr; /* Write Recovery */ int CL; /* CAS Latency */ int Tr2w; /* Read to Write Delay */ int Rloop; /* Loop Latency */ int Rloop_fudge; /* Add to ML to get Rloop */ char *name;} R128RAMRec, *R128RAMPtr;#define R128_TOTAL_REGS (VGA_TOTAL_REGS + sizeof(R128SaveRec))static int R128MinBits(int val){ int bits; if (!val) return 1; for (bits = 0; val; val >>= 1, ++bits); return bits;}static int R128Div(int n, int d){ return (n + (d / 2)) / d;}static R128PLLRec pll;static R128RAMRec ram[] = { /* Memory Specifications From RAGE 128 Software Development Manual (Technical Reference Manual P/N SDK-G04000 Rev 0.01), page 3-21. */ { 4, 4, 3, 3, 1, 3, 1, 16, 12, "128-bit SDR SGRAM 1:1" }, { 4, 8, 3, 3, 1, 3, 1, 17, 13, "64-bit SDR SGRAM 1:1" }, { 4, 4, 1, 2, 1, 2, 1, 16, 12, "64-bit SDR SGRAM 2:1" }, { 4, 4, 3, 3, 2, 3, 1, 16, 12, "64-bit DDR SGRAM" },};unsigned R128INPLL(int addr){ OUTREG8(R128_CLOCK_CNTL_INDEX, addr & 0x1f); return INREG(R128_CLOCK_CNTL_DATA);}void R128WaitForVerticalSync(void){ int i; OUTREG(R128_GEN_INT_STATUS, R128_VSYNC_INT_AK); for (i = 0; i < R128_TIMEOUT; i++) { if (INREG(R128_GEN_INT_STATUS) & R128_VSYNC_INT) break; }}/* Blank screen. */static void R128Blank(void){ OUTREGP(R128_CRTC_EXT_CNTL, R128_CRTC_DISPLAY_DIS, ~R128_CRTC_DISPLAY_DIS);}/* Unblank screen. */static void R128Unblank(void){ OUTREGP(R128_CRTC_EXT_CNTL, 0, ~R128_CRTC_DISPLAY_DIS);}static void R128RestoreCommonRegisters(R128SavePtr restore){ OUTREG(R128_OVR_CLR, restore->ovr_clr); OUTREG(R128_OVR_WID_LEFT_RIGHT, restore->ovr_wid_left_right); OUTREG(R128_OVR_WID_TOP_BOTTOM, restore->ovr_wid_top_bottom); OUTREG(R128_OV0_SCALE_CNTL, restore->ov0_scale_cntl); OUTREG(R128_MPP_TB_CONFIG, restore->mpp_tb_config ); OUTREG(R128_MPP_GP_CONFIG, restore->mpp_gp_config ); OUTREG(R128_SUBPIC_CNTL, restore->subpic_cntl); OUTREG(R128_VIPH_CONTROL, restore->viph_control); OUTREG(R128_I2C_CNTL_1, restore->i2c_cntl_1); OUTREG(R128_GEN_INT_CNTL, restore->gen_int_cntl); OUTREG(R128_CAP0_TRIG_CNTL, restore->cap0_trig_cntl); OUTREG(R128_CAP1_TRIG_CNTL, restore->cap1_trig_cntl); OUTREG(R128_BUS_CNTL, restore->bus_cntl); OUTREG(R128_CONFIG_CNTL, restore->config_cntl); OUTREG(R128_MEM_VGA_WP_SEL, restore->mem_vga_wp_sel); OUTREG(R128_MEM_VGA_RP_SEL, restore->mem_vga_rp_sel);}/* Write CRTC registers. */static void R128RestoreCrtcRegisters(R128SavePtr restore){ OUTREG(R128_CRTC_GEN_CNTL, restore->crtc_gen_cntl); OUTREGP(R128_CRTC_EXT_CNTL, restore->crtc_ext_cntl, R128_CRTC_VSYNC_DIS | R128_CRTC_HSYNC_DIS | R128_CRTC_DISPLAY_DIS); OUTREGP(R128_DAC_CNTL, restore->dac_cntl, R128_DAC_RANGE_CNTL | R128_DAC_BLANKING); OUTREG(R128_CRTC_H_TOTAL_DISP, restore->crtc_h_total_disp); OUTREG(R128_CRTC_H_SYNC_STRT_WID, restore->crtc_h_sync_strt_wid); OUTREG(R128_CRTC_V_TOTAL_DISP, restore->crtc_v_total_disp); OUTREG(R128_CRTC_V_SYNC_STRT_WID, restore->crtc_v_sync_strt_wid); OUTREG(R128_CRTC_OFFSET, restore->crtc_offset); OUTREG(R128_CRTC_OFFSET_CNTL, restore->crtc_offset_cntl); OUTREG(R128_CRTC_PITCH, restore->crtc_pitch);}/* Write flat panel registers */static void R128RestoreFPRegisters(R128SavePtr restore){ CARD32 tmp; OUTREG(R128_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl); OUTREG(R128_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp); OUTREG(R128_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp); OUTREG(R128_FP_GEN_CNTL, restore->fp_gen_cntl); OUTREG(R128_FP_H_SYNC_STRT_WID, restore->fp_h_sync_strt_wid); OUTREG(R128_FP_HORZ_STRETCH, restore->fp_horz_stretch); OUTREG(R128_FP_PANEL_CNTL, restore->fp_panel_cntl); OUTREG(R128_FP_V_SYNC_STRT_WID, restore->fp_v_sync_strt_wid); OUTREG(R128_FP_VERT_STRETCH, restore->fp_vert_stretch); OUTREG(R128_TMDS_CRC, restore->tmds_crc); tmp = INREG(R128_LVDS_GEN_CNTL); if ((tmp & (R128_LVDS_ON | R128_LVDS_BLON)) == (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON))) { OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl); } else { if (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON)) { OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl & ~R128_LVDS_BLON);// usleep(R128PTR(pScrn)->PanelPwrDly * 1000); OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl); } else { OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl | R128_LVDS_BLON);// usleep(R128PTR(pScrn)->PanelPwrDly * 1000); OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl); } }}static void R128PLLWaitForReadUpdateComplete(void){ while (INPLL(R128_PPLL_REF_DIV) & R128_PPLL_ATOMIC_UPDATE_R);}static void R128PLLWriteUpdate(void){ OUTPLLP(R128_PPLL_REF_DIV, R128_PPLL_ATOMIC_UPDATE_W, 0xffff);}/* Write PLL registers. */static void R128RestorePLLRegisters(R128SavePtr restore){ OUTREGP(R128_CLOCK_CNTL_INDEX, R128_PLL_DIV_SEL, 0xffff); OUTPLLP( R128_PPLL_CNTL, R128_PPLL_RESET | R128_PPLL_ATOMIC_UPDATE_EN, 0xffff); R128PLLWaitForReadUpdateComplete(); OUTPLLP(R128_PPLL_REF_DIV, restore->ppll_ref_div, ~R128_PPLL_REF_DIV_MASK); R128PLLWriteUpdate(); R128PLLWaitForReadUpdateComplete(); OUTPLLP(R128_PPLL_DIV_3, restore->ppll_div_3, ~R128_PPLL_FB3_DIV_MASK); R128PLLWriteUpdate(); OUTPLLP(R128_PPLL_DIV_3, restore->ppll_div_3, ~R128_PPLL_POST3_DIV_MASK); R128PLLWriteUpdate(); R128PLLWaitForReadUpdateComplete(); OUTPLL(R128_HTOTAL_CNTL, restore->htotal_cntl); R128PLLWriteUpdate(); OUTPLLP( R128_PPLL_CNTL, 0, ~R128_PPLL_RESET);}/* Write DDA registers. */static void R128RestoreDDARegisters(R128SavePtr restore){ OUTREG(R128_DDA_CONFIG, restore->dda_config); OUTREG(R128_DDA_ON_OFF, restore->dda_on_off);// OUTREG(R128_VGA_DDA_CONFIG, restore->vga_dda_config);// OUTREG(R128_VGA_DDA_ON_OFF, restore->vga_dda_on_off);}/* Write palette data. */static void R128RestorePalette( R128SavePtr restore){ int i; if (!restore->palette_valid) return; /* Select palette 0 (main CRTC) if using FP-enabled chip */// if (info->HasPanelRegs) PAL_SELECT(0); OUTPAL_START(0); for (i = 0; i < 256; i++) OUTPAL_NEXT_CARD32(restore->palette[i]);}/* Write out state to define a new video mode. */static void R128RestoreMode(R128SavePtr restore){ R128Blank(); OUTREG(R128_AMCGPIO_MASK, restore->amcgpio_mask); OUTREG(R128_AMCGPIO_EN_REG, restore->amcgpio_en_reg); OUTREG(R128_CLOCK_CNTL_INDEX, restore->clock_cntl_index); OUTREG(R128_GEN_RESET_CNTL, restore->gen_reset_cntl); OUTREG(R128_DP_DATATYPE, restore->dp_datatype); R128RestoreCommonRegisters( restore); R128RestoreCrtcRegisters( restore);// if (info->HasPanelRegs)// R128RestoreFPRegisters(restore);// if (!info->HasPanelRegs || info->CRTOnly) R128RestorePLLRegisters(restore); R128RestoreDDARegisters(restore); R128RestorePalette(restore);}/* Read common registers. */static void R128SaveCommonRegisters(R128SavePtr save){ save->ovr_clr = INREG(R128_OVR_CLR); save->ovr_wid_left_right = INREG(R128_OVR_WID_LEFT_RIGHT); save->ovr_wid_top_bottom = INREG(R128_OVR_WID_TOP_BOTTOM); save->ov0_scale_cntl = INREG(R128_OV0_SCALE_CNTL); save->mpp_tb_config = INREG(R128_MPP_TB_CONFIG); save->mpp_gp_config = INREG(R128_MPP_GP_CONFIG); save->subpic_cntl = INREG(R128_SUBPIC_CNTL); save->viph_control = INREG(R128_VIPH_CONTROL); save->i2c_cntl_1 = INREG(R128_I2C_CNTL_1); save->gen_int_cntl = INREG(R128_GEN_INT_CNTL); save->cap0_trig_cntl = INREG(R128_CAP0_TRIG_CNTL); save->cap1_trig_cntl = INREG(R128_CAP1_TRIG_CNTL); save->bus_cntl = INREG(R128_BUS_CNTL); save->config_cntl = INREG(R128_CONFIG_CNTL); save->mem_vga_wp_sel = INREG(R128_MEM_VGA_WP_SEL); save->mem_vga_rp_sel = INREG(R128_MEM_VGA_RP_SEL);}/* Read CRTC registers. */static void R128SaveCrtcRegisters(R128SavePtr save){ save->crtc_gen_cntl = INREG(R128_CRTC_GEN_CNTL); save->crtc_ext_cntl = INREG(R128_CRTC_EXT_CNTL); save->dac_cntl = INREG(R128_DAC_CNTL); save->crtc_h_total_disp = INREG(R128_CRTC_H_TOTAL_DISP); save->crtc_h_sync_strt_wid = INREG(R128_CRTC_H_SYNC_STRT_WID); save->crtc_v_total_disp = INREG(R128_CRTC_V_TOTAL_DISP); save->crtc_v_sync_strt_wid = INREG(R128_CRTC_V_SYNC_STRT_WID); save->crtc_offset = INREG(R128_CRTC_OFFSET); save->crtc_offset_cntl = INREG(R128_CRTC_OFFSET_CNTL); save->crtc_pitch = INREG(R128_CRTC_PITCH);}/* Read flat panel registers */static void R128SaveFPRegisters(R128SavePtr save){ save->crtc2_gen_cntl = INREG(R128_CRTC2_GEN_CNTL); save->fp_crtc_h_total_disp = INREG(R128_FP_CRTC_H_TOTAL_DISP); save->fp_crtc_v_total_disp = INREG(R128_FP_CRTC_V_TOTAL_DISP); save->fp_gen_cntl = INREG(R128_FP_GEN_CNTL); save->fp_h_sync_strt_wid = INREG(R128_FP_H_SYNC_STRT_WID); save->fp_horz_stretch = INREG(R128_FP_HORZ_STRETCH); save->fp_panel_cntl = INREG(R128_FP_PANEL_CNTL); save->fp_v_sync_strt_wid = INREG(R128_FP_V_SYNC_STRT_WID); save->fp_vert_stretch = INREG(R128_FP_VERT_STRETCH); save->lvds_gen_cntl = INREG(R128_LVDS_GEN_CNTL); save->tmds_crc = INREG(R128_TMDS_CRC);}/* Read PLL registers. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -