📄 radeon_vid.c
字号:
/* radeon_vid - VIDIX based video driver for Radeon and Rage128 chips Copyrights 2002 Nick Kurshev. This file is based on sources from GATOS (gatos.sf.net) and X11 (www.xfree86.org) Licence: GPL*/#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include <inttypes.h>#include <sys/mman.h>#include "../../config.h"#include "../../bswap.h"#include "../../libdha/pci_ids.h"#include "../../libdha/pci_names.h"#include "../vidix.h"#include "../fourcc.h"#include "../../libdha/libdha.h"#include "radeon.h"#ifdef RAGE128#define RADEON_MSG "Rage128_vid:"#define X_ADJUST 0#else#define RADEON_MSG "Radeon_vid:"#define X_ADJUST (is_shift_required ? 8 : 0)#ifndef RADEON#define RADEON#endif#endif#define RADEON_ASSERT(msg) printf(RADEON_MSG"################# FATAL:"msg);#ifdef RAGE128#define VIDIX_STATIC rage128_#else#define VIDIX_STATIC radeo_#endif//#undef RADEON_ENABLE_BM /* unfinished stuff. May corrupt your filesystem ever */#define RADEON_ENABLE_BM 1#ifdef RADEON_ENABLE_BMstatic void * radeon_dma_desc_base = 0;static unsigned long bus_addr_dma_desc = 0;static unsigned long *dma_phys_addrs = 0;#pragma pack(1)typedef struct{ uint32_t framebuf_offset; uint32_t sys_addr; uint32_t command; uint32_t reserved;} bm_list_descriptor;#pragma pack()#endif#define VERBOSE_LEVEL 0static int __verbose = 0;#ifndef RAGE128static int is_shift_required=0;#endiftypedef struct bes_registers_s{ /* base address of yuv framebuffer */ uint32_t yuv_base; uint32_t fourcc; uint32_t surf_id; int load_prg_start; int horz_pick_nearest; int vert_pick_nearest; int swap_uv; /* for direct support of bgr fourccs */ uint32_t dest_bpp; /* YUV BES registers */ uint32_t reg_load_cntl; uint32_t h_inc; uint32_t step_by; uint32_t y_x_start; uint32_t y_x_end; uint32_t v_inc; uint32_t p1_blank_lines_at_top; uint32_t p23_blank_lines_at_top; uint32_t vid_buf_pitch0_value; uint32_t vid_buf_pitch1_value; uint32_t p1_x_start_end; uint32_t p2_x_start_end; uint32_t p3_x_start_end; uint32_t base_addr; uint32_t vid_buf_base_adrs_y[VID_PLAY_MAXFRAMES]; uint32_t vid_buf_base_adrs_u[VID_PLAY_MAXFRAMES]; uint32_t vid_buf_base_adrs_v[VID_PLAY_MAXFRAMES]; uint32_t vid_nbufs; uint32_t p1_v_accum_init; uint32_t p1_h_accum_init; uint32_t p23_v_accum_init; uint32_t p23_h_accum_init; uint32_t scale_cntl; uint32_t exclusive_horz; uint32_t auto_flip_cntl; uint32_t filter_cntl; uint32_t four_tap_coeff[5]; uint32_t key_cntl; uint32_t test; /* Configurable stuff */ int double_buff; int brightness; int saturation; int ckey_on; uint32_t graphics_key_clr; uint32_t graphics_key_msk; uint32_t ckey_cntl; int deinterlace_on; uint32_t deinterlace_pattern; } bes_registers_t;typedef struct video_registers_s{ const char * sname; uint32_t name; uint32_t value;}video_registers_t;static bes_registers_t besr;#ifndef RAGE128static int RadeonFamily=100;#endif#define DECLARE_VREG(name) { #name, name, 0 }static video_registers_t vregs[] = { DECLARE_VREG(VIDEOMUX_CNTL), DECLARE_VREG(VIPPAD_MASK), DECLARE_VREG(VIPPAD1_A), DECLARE_VREG(VIPPAD1_EN), DECLARE_VREG(VIPPAD1_Y), DECLARE_VREG(OV0_Y_X_START), DECLARE_VREG(OV0_Y_X_END), DECLARE_VREG(OV0_PIPELINE_CNTL), DECLARE_VREG(OV0_EXCLUSIVE_HORZ), DECLARE_VREG(OV0_EXCLUSIVE_VERT), DECLARE_VREG(OV0_REG_LOAD_CNTL), DECLARE_VREG(OV0_SCALE_CNTL), DECLARE_VREG(OV0_V_INC), DECLARE_VREG(OV0_P1_V_ACCUM_INIT), DECLARE_VREG(OV0_P23_V_ACCUM_INIT), DECLARE_VREG(OV0_P1_BLANK_LINES_AT_TOP), DECLARE_VREG(OV0_P23_BLANK_LINES_AT_TOP),#ifdef RADEON DECLARE_VREG(OV0_BASE_ADDR),#endif DECLARE_VREG(OV0_VID_BUF0_BASE_ADRS), DECLARE_VREG(OV0_VID_BUF1_BASE_ADRS), DECLARE_VREG(OV0_VID_BUF2_BASE_ADRS), DECLARE_VREG(OV0_VID_BUF3_BASE_ADRS), DECLARE_VREG(OV0_VID_BUF4_BASE_ADRS), DECLARE_VREG(OV0_VID_BUF5_BASE_ADRS), DECLARE_VREG(OV0_VID_BUF_PITCH0_VALUE), DECLARE_VREG(OV0_VID_BUF_PITCH1_VALUE), DECLARE_VREG(OV0_AUTO_FLIP_CNTL), DECLARE_VREG(OV0_DEINTERLACE_PATTERN), DECLARE_VREG(OV0_SUBMIT_HISTORY), DECLARE_VREG(OV0_H_INC), DECLARE_VREG(OV0_STEP_BY), DECLARE_VREG(OV0_P1_H_ACCUM_INIT), DECLARE_VREG(OV0_P23_H_ACCUM_INIT), DECLARE_VREG(OV0_P1_X_START_END), DECLARE_VREG(OV0_P2_X_START_END), DECLARE_VREG(OV0_P3_X_START_END), DECLARE_VREG(OV0_FILTER_CNTL), DECLARE_VREG(OV0_FOUR_TAP_COEF_0), DECLARE_VREG(OV0_FOUR_TAP_COEF_1), DECLARE_VREG(OV0_FOUR_TAP_COEF_2), DECLARE_VREG(OV0_FOUR_TAP_COEF_3), DECLARE_VREG(OV0_FOUR_TAP_COEF_4), DECLARE_VREG(OV0_FLAG_CNTL),#ifdef RAGE128 DECLARE_VREG(OV0_COLOUR_CNTL),#else DECLARE_VREG(OV0_SLICE_CNTL),#endif DECLARE_VREG(OV0_VID_KEY_CLR), DECLARE_VREG(OV0_VID_KEY_MSK), DECLARE_VREG(OV0_GRAPHICS_KEY_CLR), DECLARE_VREG(OV0_GRAPHICS_KEY_MSK), DECLARE_VREG(OV0_KEY_CNTL), DECLARE_VREG(OV0_TEST), DECLARE_VREG(OV0_LIN_TRANS_A), DECLARE_VREG(OV0_LIN_TRANS_B), DECLARE_VREG(OV0_LIN_TRANS_C), DECLARE_VREG(OV0_LIN_TRANS_D), DECLARE_VREG(OV0_LIN_TRANS_E), DECLARE_VREG(OV0_LIN_TRANS_F), DECLARE_VREG(OV0_GAMMA_0_F), DECLARE_VREG(OV0_GAMMA_10_1F), DECLARE_VREG(OV0_GAMMA_20_3F), DECLARE_VREG(OV0_GAMMA_40_7F), DECLARE_VREG(OV0_GAMMA_380_3BF), DECLARE_VREG(OV0_GAMMA_3C0_3FF), DECLARE_VREG(SUBPIC_CNTL), DECLARE_VREG(SUBPIC_DEFCOLCON), DECLARE_VREG(SUBPIC_Y_X_START), DECLARE_VREG(SUBPIC_Y_X_END), DECLARE_VREG(SUBPIC_V_INC), DECLARE_VREG(SUBPIC_H_INC), DECLARE_VREG(SUBPIC_BUF0_OFFSET), DECLARE_VREG(SUBPIC_BUF1_OFFSET), DECLARE_VREG(SUBPIC_LC0_OFFSET), DECLARE_VREG(SUBPIC_LC1_OFFSET), DECLARE_VREG(SUBPIC_PITCH), DECLARE_VREG(SUBPIC_BTN_HLI_COLCON), DECLARE_VREG(SUBPIC_BTN_HLI_Y_X_START), DECLARE_VREG(SUBPIC_BTN_HLI_Y_X_END), DECLARE_VREG(SUBPIC_PALETTE_INDEX), DECLARE_VREG(SUBPIC_PALETTE_DATA), DECLARE_VREG(SUBPIC_H_ACCUM_INIT), DECLARE_VREG(SUBPIC_V_ACCUM_INIT), DECLARE_VREG(IDCT_RUNS), DECLARE_VREG(IDCT_LEVELS), DECLARE_VREG(IDCT_AUTH_CONTROL), DECLARE_VREG(IDCT_AUTH), DECLARE_VREG(IDCT_CONTROL),#ifdef RAGE128 DECLARE_VREG(BM_FRAME_BUF_OFFSET), DECLARE_VREG(BM_SYSTEM_MEM_ADDR), DECLARE_VREG(BM_COMMAND), DECLARE_VREG(BM_STATUS), DECLARE_VREG(BM_QUEUE_STATUS), DECLARE_VREG(BM_QUEUE_FREE_STATUS), DECLARE_VREG(BM_CHUNK_0_VAL), DECLARE_VREG(BM_CHUNK_1_VAL), DECLARE_VREG(BM_VIP0_BUF), DECLARE_VREG(BM_VIP0_ACTIVE), DECLARE_VREG(BM_VIP1_BUF), DECLARE_VREG(BM_VIP1_ACTIVE), DECLARE_VREG(BM_VIP2_BUF), DECLARE_VREG(BM_VIP2_ACTIVE), DECLARE_VREG(BM_VIP3_BUF), DECLARE_VREG(BM_VIP3_ACTIVE), DECLARE_VREG(BM_VIDCAP_BUF0), DECLARE_VREG(BM_VIDCAP_BUF1), DECLARE_VREG(BM_VIDCAP_BUF2), DECLARE_VREG(BM_VIDCAP_ACTIVE), DECLARE_VREG(BM_GUI), DECLARE_VREG(BM_ABORT)#else DECLARE_VREG(DMA_GUI_TABLE_ADDR), DECLARE_VREG(DMA_GUI_SRC_ADDR), DECLARE_VREG(DMA_GUI_DST_ADDR), DECLARE_VREG(DMA_GUI_COMMAND), DECLARE_VREG(DMA_GUI_STATUS), DECLARE_VREG(DMA_GUI_ACT_DSCRPTR), DECLARE_VREG(DMA_VID_SRC_ADDR), DECLARE_VREG(DMA_VID_DST_ADDR), DECLARE_VREG(DMA_VID_COMMAND), DECLARE_VREG(DMA_VID_STATUS), DECLARE_VREG(DMA_VID_ACT_DSCRPTR),#endif};static void * radeon_mmio_base = 0;static void * radeon_mem_base = 0; static int32_t radeon_overlay_off = 0;static uint32_t radeon_ram_size = 0;#define GETREG(TYPE,PTR,OFFZ) (*((volatile TYPE*)((PTR)+(OFFZ))))#define SETREG(TYPE,PTR,OFFZ,VAL) (*((volatile TYPE*)((PTR)+(OFFZ))))=VAL#define INREG8(addr) GETREG(uint8_t,(uint32_t)(radeon_mmio_base),addr)#define OUTREG8(addr,val) SETREG(uint8_t,(uint32_t)(radeon_mmio_base),addr,val)static inline uint32_t INREG (uint32_t addr) { uint32_t tmp = GETREG(uint32_t,(uint32_t)(radeon_mmio_base),addr); return le2me_32(tmp);}#define OUTREG(addr,val) SETREG(uint32_t,(uint32_t)(radeon_mmio_base),addr,le2me_32(val))#define OUTREGP(addr,val,mask) \ do { \ unsigned int _tmp = INREG(addr); \ _tmp &= (mask); \ _tmp |= (val); \ OUTREG(addr, _tmp); \ } while (0)static __inline__ uint32_t INPLL(uint32_t addr){ OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000001f); return (INREG(CLOCK_CNTL_DATA));}#define OUTPLL(addr,val) OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000001f) | 0x00000080); \ OUTREG(CLOCK_CNTL_DATA, val)#define OUTPLLP(addr,val,mask) \ do { \ unsigned int _tmp = INPLL(addr); \ _tmp &= (mask); \ _tmp |= (val); \ OUTPLL(addr, _tmp); \ } while (0)static uint32_t radeon_vid_get_dbpp( void ){ uint32_t dbpp,retval; dbpp = (INREG(CRTC_GEN_CNTL)>>8)& 0xF; switch(dbpp) { case DST_8BPP: retval = 8; break; case DST_15BPP: retval = 15; break; case DST_16BPP: retval = 16; break; case DST_24BPP: retval = 24; break; default: retval=32; break; } return retval;}static int radeon_is_dbl_scan( void ){ return (INREG(CRTC_GEN_CNTL))&CRTC_DBL_SCAN_EN;}static int radeon_is_interlace( void ){ return (INREG(CRTC_GEN_CNTL))&CRTC_INTERLACE_EN;}static uint32_t radeon_get_xres( void ){ /* FIXME: currently we extract that from CRTC!!!*/ uint32_t xres,h_total; h_total = INREG(CRTC_H_TOTAL_DISP); xres = (h_total >> 16) & 0xffff; return (xres + 1)*8;}static uint32_t radeon_get_yres( void ){ /* FIXME: currently we extract that from CRTC!!!*/ uint32_t yres,v_total; v_total = INREG(CRTC_V_TOTAL_DISP); yres = (v_total >> 16) & 0xffff; return yres + 1;}static void radeon_wait_vsync(void){ int i; OUTREG(GEN_INT_STATUS, VSYNC_INT_AK); for (i = 0; i < 2000000; i++) { if (INREG(GEN_INT_STATUS) & VSYNC_INT) break; }}#ifdef RAGE128static void _radeon_engine_idle(void);static void _radeon_fifo_wait(unsigned);#define radeon_engine_idle() _radeon_engine_idle()#define radeon_fifo_wait(entries) _radeon_fifo_wait(entries)/* Flush all dirty data in the Pixel Cache to memory. */static __inline__ void radeon_engine_flush ( void ){ unsigned i; OUTREGP(PC_NGUI_CTLSTAT, PC_FLUSH_ALL, ~PC_FLUSH_ALL); for (i = 0; i < 2000000; i++) { if (!(INREG(PC_NGUI_CTLSTAT) & PC_BUSY)) break; }}/* Reset graphics card to known state. */static void radeon_engine_reset( void ){ uint32_t clock_cntl_index; uint32_t mclk_cntl; uint32_t gen_reset_cntl; radeon_engine_flush(); clock_cntl_index = INREG(CLOCK_CNTL_INDEX); mclk_cntl = INPLL(MCLK_CNTL); OUTPLL(MCLK_CNTL, mclk_cntl | FORCE_GCP | FORCE_PIPE3D_CP); gen_reset_cntl = INREG(GEN_RESET_CNTL); OUTREG(GEN_RESET_CNTL, gen_reset_cntl | SOFT_RESET_GUI); INREG(GEN_RESET_CNTL); OUTREG(GEN_RESET_CNTL, gen_reset_cntl & (uint32_t)(~SOFT_RESET_GUI)); INREG(GEN_RESET_CNTL); OUTPLL(MCLK_CNTL, mclk_cntl); OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index); OUTREG(GEN_RESET_CNTL, gen_reset_cntl);}#elsestatic __inline__ void radeon_engine_flush ( void ){ int i; /* initiate flush */ OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL, ~RB2D_DC_FLUSH_ALL); for (i=0; i < 2000000; i++) { if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY)) break; }}static void _radeon_engine_idle(void);static void _radeon_fifo_wait(unsigned);#define radeon_engine_idle() _radeon_engine_idle()#define radeon_fifo_wait(entries) _radeon_fifo_wait(entries)static void radeon_engine_reset( void ){ uint32_t clock_cntl_index, mclk_cntl, rbbm_soft_reset;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -