From be94988aa9d5db023e9a83b68cb77b3f50f0c98f Mon Sep 17 00:00:00 2001 From: ben Date: Sun, 22 Apr 2007 13:25:50 +0000 Subject: updated the ati vidix driver with the one from upstream vidix, it now supports much more GPUs (including all Radeon > 9600 and X series) git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@23062 b3059339-0415-0410-9bf9-f77b7e298cf2 --- vidix/radeon_vid.c | 2653 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 2025 insertions(+), 628 deletions(-) (limited to 'vidix/radeon_vid.c') diff --git a/vidix/radeon_vid.c b/vidix/radeon_vid.c index 6a0436ee6e..6891bfe8ef 100644 --- a/vidix/radeon_vid.c +++ b/vidix/radeon_vid.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "config.h" #include "libavutil/common.h" @@ -27,8 +28,9 @@ #include "dha.h" #include "radeon.h" -#ifdef HAVE_X11 +#if !defined(RAGE128) && defined(HAVE_X11) #include +static uint32_t firegl_shift = 0; #endif #ifdef RAGE128 @@ -36,22 +38,26 @@ #define X_ADJUST 0 #else #define RADEON_MSG "[radeon]" -#define X_ADJUST (is_shift_required ? 8 : 0) +#define X_ADJUST (((besr.chip_flags&R_OVL_SHIFT)==R_OVL_SHIFT)?8:0) #ifndef RADEON #define RADEON #endif #endif -static int __verbose = 0; -#ifdef RADEON -static int is_shift_required = 0; -#endif +#define RADEON_ASSERT(msg) printf(RADEON_MSG"################# FATAL:"msg); +#define VERBOSE_LEVEL 0 +static int __verbose = 0; typedef 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; @@ -81,6 +87,7 @@ typedef struct bes_registers_s 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 */ @@ -93,10 +100,12 @@ typedef struct bes_registers_s uint32_t graphics_key_clr; uint32_t graphics_key_msk; uint32_t ckey_cntl; + uint32_t merge_cntl; int deinterlace_on; uint32_t deinterlace_pattern; + unsigned chip_flags; } bes_registers_t; typedef struct video_registers_s @@ -107,9 +116,6 @@ typedef struct video_registers_s }video_registers_t; static bes_registers_t besr; -#ifndef RAGE128 -static int RadeonFamily=100; -#endif #define DECLARE_VREG(name) { #name, name, 0 } static video_registers_t vregs[] = { @@ -120,6 +126,8 @@ static video_registers_t vregs[] = DECLARE_VREG(VIPPAD1_Y), DECLARE_VREG(OV0_Y_X_START), DECLARE_VREG(OV0_Y_X_END), + DECLARE_VREG(OV1_Y_X_START), + DECLARE_VREG(OV1_Y_X_END), DECLARE_VREG(OV0_PIPELINE_CNTL), DECLARE_VREG(OV0_EXCLUSIVE_HORZ), DECLARE_VREG(OV0_EXCLUSIVE_VERT), @@ -204,47 +212,380 @@ static video_registers_t vregs[] = DECLARE_VREG(IDCT_AUTH_CONTROL), DECLARE_VREG(IDCT_AUTH), DECLARE_VREG(IDCT_CONTROL), - DECLARE_VREG(CONFIG_CNTL) +#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 }; -#ifdef HAVE_X11 -static uint32_t firegl_shift = 0; +#define R_FAMILY 0x000000FF +#define R_100 0x00000001 +#define R_120 0x00000002 +#define R_150 0x00000003 +#define R_200 0x00000004 +#define R_250 0x00000005 +#define R_280 0x00000006 +#define R_300 0x00000007 +#define R_350 0x00000008 +#define R_370 0x00000010 +#define R_380 0x00000020 +#define R_420 0x00000040 +#define R_430 0x00000080 +#define R_480 0x00000100 +#define R_520 0x00000200 +#define R_530 0x00000400 +#define R_580 0x00000800 +#define R_OVL_SHIFT 0x01000000 +#define R_INTEGRATED 0x02000000 +#define R_PCIE 0x04000000 + +typedef struct ati_card_ids_s +{ + unsigned short id; + unsigned flags; +}ati_card_ids_t; + +static const ati_card_ids_t ati_card_ids[] = +{ +#ifdef RAGE128 + /* + This driver should be compatible with Rage128 (pro) chips. + (include adaptive deinterlacing!!!). + Moreover: the same logic can be used with Mach64 chips. + (I mean: mach64xx, 3d rage, 3d rage IIc, 3D rage pro, 3d rage mobility). + but they are incompatible by i/o ports. So if enthusiasts will want + then they can redefine OUTREG and INREG macros and redefine OV0_* + constants. Also it seems that mach64 chips supports only: YUY2, YV12, UYVY + fourccs (422 and 420 formats only). + */ +/* Rage128 Pro GL */ + { DEVICE_ATI_RAGE_128_PA_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PB_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PC_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PD_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PE_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PF_PRO, 0 }, +/* Rage128 Pro VR */ + { DEVICE_ATI_RAGE_128_PG_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PH_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PI_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PJ_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PK_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PL_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PM_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PN_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PO_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PP_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PQ_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PR_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PS_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PT_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PU_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PV_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PW_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PX_PRO, 0 }, +/* Rage128 GL */ + { DEVICE_ATI_RAGE_128_RE_SG, 0 }, + { DEVICE_ATI_RAGE_128_RF_SG, 0 }, + { DEVICE_ATI_RAGE_128_RG, 0 }, + { DEVICE_ATI_RAGE_128_RK_VR, 0 }, + { DEVICE_ATI_RAGE_128_RL_VR, 0 }, + { DEVICE_ATI_RAGE_128_SE_4X, 0 }, + { DEVICE_ATI_RAGE_128_SF_4X, 0 }, + { DEVICE_ATI_RAGE_128_SG_4X, 0 }, + { DEVICE_ATI_RAGE_128_SH, 0 }, + { DEVICE_ATI_RAGE_128_SK_4X, 0 }, + { DEVICE_ATI_RAGE_128_SL_4X, 0 }, + { DEVICE_ATI_RAGE_128_SM_4X, 0 }, + { DEVICE_ATI_RAGE_128_4X, 0 }, + { DEVICE_ATI_RAGE_128_PRO, 0 }, + { DEVICE_ATI_RAGE_128_PRO2, 0 }, + { DEVICE_ATI_RAGE_128_PRO3, 0 }, +/* these seem to be based on rage 128 instead of mach64 */ + { DEVICE_ATI_RAGE_MOBILITY_M3, 0 }, + { DEVICE_ATI_RAGE_MOBILITY_M32, 0 }, +#else +/* Radeon1 (indeed: Rage 256 Pro ;) */ + { DEVICE_ATI_RADEON_R100_QD, R_100|R_OVL_SHIFT }, + { DEVICE_ATI_RADEON_R100_QE, R_100|R_OVL_SHIFT }, + { DEVICE_ATI_RADEON_R100_QF, R_100|R_OVL_SHIFT }, + { DEVICE_ATI_RADEON_R100_QG, R_100|R_OVL_SHIFT }, + { DEVICE_ATI_RADEON_IGP_320, R_150|R_OVL_SHIFT|R_INTEGRATED }, + { DEVICE_ATI_RADEON_MOBILITY_U1, R_150|R_OVL_SHIFT|R_INTEGRATED }, + { DEVICE_ATI_RADEON_RV100_QY, R_120|R_OVL_SHIFT }, + { DEVICE_ATI_RADEON_RV100_QZ, R_120|R_OVL_SHIFT }, + { DEVICE_ATI_RADEON_MOBILITY_M7, R_150|R_OVL_SHIFT }, + { DEVICE_ATI_RADEON_RV200_LX, R_150|R_OVL_SHIFT }, + { DEVICE_ATI_RADEON_MOBILITY_M6, R_120|R_OVL_SHIFT }, + { DEVICE_ATI_RADEON_MOBILITY_M62, R_120|R_OVL_SHIFT }, +/* Radeon2 (indeed: Rage 512 Pro ;) */ + { DEVICE_ATI_R200_BB_RADEON, R_200 }, + { DEVICE_ATI_R200_BC_RADEON, R_200 }, + { DEVICE_ATI_RADEON_R200_QH, R_200 }, + { DEVICE_ATI_RADEON_R200_QI, R_200 }, + { DEVICE_ATI_RADEON_R200_QJ, R_200 }, + { DEVICE_ATI_RADEON_R200_QK, R_200 }, + { DEVICE_ATI_RADEON_R200_QL, R_200 }, + { DEVICE_ATI_RADEON_R200_QM, R_200 }, + { DEVICE_ATI_RADEON_R200_QN, R_200 }, + { DEVICE_ATI_RADEON_R200_QO, R_200 }, + { DEVICE_ATI_RADEON_R200_QH2, R_200 }, + { DEVICE_ATI_RADEON_R200_QI2, R_200 }, + { DEVICE_ATI_RADEON_R200_QJ2, R_200 }, + { DEVICE_ATI_RADEON_R200_QK2, R_200 }, + { DEVICE_ATI_RADEON_R200_QL2, R_200 }, + { DEVICE_ATI_RADEON_RV200_QW, R_150|R_OVL_SHIFT }, + { DEVICE_ATI_RADEON_RV200_QX, R_150|R_OVL_SHIFT }, + { DEVICE_ATI_RADEON_IGP330_340_350,R_200|R_INTEGRATED }, + { DEVICE_ATI_RADEON_IGP_330M_340M_350M,R_200|R_INTEGRATED }, + { DEVICE_ATI_RADEON_RV250_IG, R_250|R_OVL_SHIFT }, + { DEVICE_ATI_RADEON_7000_IGP, R_250|R_OVL_SHIFT|R_INTEGRATED }, + { DEVICE_ATI_RADEON_MOBILITY_7000, R_250|R_OVL_SHIFT|R_INTEGRATED }, + { DEVICE_ATI_RADEON_RV250_ID, R_250|R_OVL_SHIFT }, + { DEVICE_ATI_RADEON_RV250_IE, R_250|R_OVL_SHIFT }, + { DEVICE_ATI_RADEON_RV250_IF, R_250|R_OVL_SHIFT }, + { DEVICE_ATI_RADEON_RV250_IG, R_250|R_OVL_SHIFT }, + { DEVICE_ATI_RADEON_R250_LD, R_250|R_OVL_SHIFT }, + { DEVICE_ATI_RADEON_R250_LE, R_250|R_OVL_SHIFT }, + { DEVICE_ATI_RADEON_R250_MOBILITY, R_250|R_OVL_SHIFT }, + { DEVICE_ATI_RADEON_R250_LG, R_250|R_OVL_SHIFT }, + { DEVICE_ATI_RV250_RADEON_9000, R_250|R_OVL_SHIFT }, + { DEVICE_ATI_RADEON_RV250_RADEON2, R_250|R_OVL_SHIFT }, + { DEVICE_ATI_RV280_RADEON_9200, R_280 }, + { DEVICE_ATI_RV280_RADEON_92002, R_280 }, + { DEVICE_ATI_RV280_RADEON_92003, R_280 }, + { DEVICE_ATI_RV280_RADEON_92004, R_280 }, + { DEVICE_ATI_RV280_RADEON_92005, R_280 }, + { DEVICE_ATI_RV280_RADEON_92006, R_280 }, + { DEVICE_ATI_RV280_RADEON_92007, R_280 }, + { DEVICE_ATI_M9_5C61_RADEON, R_280 }, + { DEVICE_ATI_M9_5C63_RADEON, R_280 }, +/* Radeon3 (indeed: Rage 1024 Pro ;) */ + { DEVICE_ATI_R300_AG_FIREGL, R_300 }, + { DEVICE_ATI_RADEON_R300_ND, R_300 }, + { DEVICE_ATI_RADEON_R300_NE, R_300 }, + { DEVICE_ATI_RADEON_R300_NG, R_300 }, + { DEVICE_ATI_R300_AD_RADEON, R_300 }, + { DEVICE_ATI_R300_AE_RADEON, R_300 }, + { DEVICE_ATI_R300_AF_RADEON, R_300 }, + { DEVICE_ATI_RADEON_9100_IGP2, R_300|R_OVL_SHIFT|R_INTEGRATED }, + { DEVICE_ATI_RS300M_AGP_RADEON, R_300|R_INTEGRATED }, + { DEVICE_ATI_R350_AH_RADEON, R_350 }, + { DEVICE_ATI_R350_AI_RADEON, R_350 }, + { DEVICE_ATI_R350_AJ_RADEON, R_350 }, + { DEVICE_ATI_R350_AK_FIRE, R_350 }, + { DEVICE_ATI_RADEON_R350_RADEON2, R_350 }, + { DEVICE_ATI_RADEON_R350_RADEON3, R_350 }, + { DEVICE_ATI_RV350_NJ_RADEON, R_350 }, + { DEVICE_ATI_R350_NK_FIRE, R_350 }, + { DEVICE_ATI_RV350_AP_RADEON, R_350 }, + { DEVICE_ATI_RV350_AQ_RADEON, R_350 }, + { DEVICE_ATI_RV350_AR_RADEON, R_350 }, + { DEVICE_ATI_RV350_AS_RADEON, R_350 }, + { DEVICE_ATI_RV350_AT_FIRE, R_350 }, + { DEVICE_ATI_RV350_AU_FIRE, R_350 }, + { DEVICE_ATI_RV350_AV_FIRE, R_350 }, + { DEVICE_ATI_RV350_AW_FIRE, R_350 }, + { DEVICE_ATI_RV350_MOBILITY_RADEON, R_350 }, + { DEVICE_ATI_RV350_NF_RADEON, R_300 }, + { DEVICE_ATI_RV350_NJ_RADEON, R_300 }, + { DEVICE_ATI_RV350_AS_RADEON2, R_350 }, + { DEVICE_ATI_M10_NQ_RADEON, R_350 }, + { DEVICE_ATI_M10_NQ_RADEON2, R_350 }, + { DEVICE_ATI_RV350_MOBILITY_RADEON2, R_350 }, + { DEVICE_ATI_M10_NS_RADEON, R_350 }, + { DEVICE_ATI_M10_NT_FIREGL, R_350 }, + { DEVICE_ATI_M11_NV_FIREGL, R_350 }, + { DEVICE_ATI_RV370_5B60_RADEON, R_370|R_PCIE }, + { DEVICE_ATI_RV370_SAPPHIRE_X550, R_370 }, + { DEVICE_ATI_RV370_5B64_FIREGL, R_370|R_PCIE }, + { DEVICE_ATI_RV370_5B65_FIREGL, R_370|R_PCIE }, + { DEVICE_ATI_M24_1P_RADEON, R_370 }, + { DEVICE_ATI_M22_RADEON_MOBILITY, R_370 }, + { DEVICE_ATI_M24_1T_FIREGL, R_370 }, + { DEVICE_ATI_M24_RADEON_MOBILITY, R_370 }, + { DEVICE_ATI_RV370_RADEON_X300SE, R_370 }, + { DEVICE_ATI_RV370_SECONDARY_SAPPHIRE, R_370 }, + { DEVICE_ATI_RV370_5B64_FIREGL2, R_370 }, + { DEVICE_ATI_RV380_0X3E50_RADEON, R_380|R_PCIE }, + { DEVICE_ATI_RV380_0X3E54_FIREGL, R_380|R_PCIE }, + { DEVICE_ATI_RV380_RADEON_X600, R_380|R_PCIE }, + { DEVICE_ATI_RV380_RADEON_X6002, R_380 }, + { DEVICE_ATI_RV380_RADEON_X6003, R_380 }, + { DEVICE_ATI_RV410_FIREGL_V5000, R_420 }, + { DEVICE_ATI_RV410_FIREGL_V3300, R_420 }, + { DEVICE_ATI_RV410_RADEON_X700XT, R_420 }, + { DEVICE_ATI_RV410_RADEON_X700, R_420|R_PCIE }, + { DEVICE_ATI_RV410_RADEON_X700SE, R_420 }, + { DEVICE_ATI_RV410_RADEON_X7002, R_420|R_PCIE }, + { DEVICE_ATI_RV410_RADEON_X7003, R_420 }, + { DEVICE_ATI_RV410_RADEON_X7004, R_420|R_PCIE }, + { DEVICE_ATI_RV410_RADEON_X7005, R_420|R_PCIE }, + { DEVICE_ATI_M26_MOBILITY_FIREGL, R_420 }, + { DEVICE_ATI_M26_MOBILITY_FIREGL2, R_420 }, + { DEVICE_ATI_M26_RADEON_MOBILITY, R_420 }, + { DEVICE_ATI_M26_RADEON_MOBILITY2, R_420 }, + { DEVICE_ATI_RADEON_MOBILITY_X700, R_420 }, + { DEVICE_ATI_R420_JH_RADEON, R_420|R_PCIE }, + { DEVICE_ATI_R420_JI_RADEON, R_420|R_PCIE }, + { DEVICE_ATI_R420_JJ_RADEON, R_420|R_PCIE }, + { DEVICE_ATI_R420_JK_RADEON, R_420|R_PCIE }, + { DEVICE_ATI_R420_JL_RADEON, R_420|R_PCIE }, + { DEVICE_ATI_R420_JM_FIREGL, R_420|R_PCIE }, + { DEVICE_ATI_M18_JN_RADEON, R_420|R_PCIE }, + { DEVICE_ATI_R420_JP_RADEON, R_420|R_PCIE }, + { DEVICE_ATI_R420_RADEON_X800, R_420|R_PCIE }, + { DEVICE_ATI_R420_RADEON_X8002, R_420|R_PCIE }, + { DEVICE_ATI_R420_RADEON_X8003, R_420|R_PCIE }, + { DEVICE_ATI_R420_RADEON_X8004, R_420|R_PCIE }, + { DEVICE_ATI_R420_RADEON_X8005, R_420|R_PCIE }, + { DEVICE_ATI_R420_JM_FIREGL, R_420|R_PCIE }, + { DEVICE_ATI_R423_5F57_RADEON, R_420|R_PCIE }, + { DEVICE_ATI_R423_5F57_RADEON2, R_420|R_PCIE }, + { DEVICE_ATI_R423_UH_RADEON, R_420|R_PCIE }, + { DEVICE_ATI_R423_UI_RADEON, R_420|R_PCIE }, + { DEVICE_ATI_R423_UJ_RADEON, R_420|R_PCIE }, + { DEVICE_ATI_R423_UK_RADEON, R_420|R_PCIE }, + { DEVICE_ATI_R423_FIRE_GL, R_420|R_PCIE }, + { DEVICE_ATI_R423_UQ_FIREGL, R_420|R_PCIE }, + { DEVICE_ATI_R423_UR_FIREGL, R_420|R_PCIE }, + { DEVICE_ATI_R423_UT_FIREGL, R_420|R_PCIE }, + { DEVICE_ATI_R423_UI_RADEON2, R_420|R_PCIE }, + { DEVICE_ATI_R423GL_SE_ATI_FIREGL, R_420|R_PCIE }, + { DEVICE_ATI_R423_RADEON_X800XT, R_420|R_PCIE }, + { DEVICE_ATI_RADEON_R423_UK, R_420|R_PCIE }, + { DEVICE_ATI_M28_RADEON_MOBILITY, R_420 }, + { DEVICE_ATI_M28_MOBILITY_FIREGL, R_420 }, + { DEVICE_ATI_MOBILITY_RADEON_X800, R_420 }, + { DEVICE_ATI_R430_RADEON_X800, R_430|R_PCIE }, + { DEVICE_ATI_R430_RADEON_X8002, R_430|R_PCIE }, + { DEVICE_ATI_R430_RADEON_X8003, R_430|R_PCIE }, + { DEVICE_ATI_R430_RADEON_X8004, R_430|R_PCIE }, + { DEVICE_ATI_R480_RADEON_X800, R_480 }, + { DEVICE_ATI_R480_RADEON_X8002, R_480 }, + { DEVICE_ATI_R480_RADEON_X850XT, R_480 }, + { DEVICE_ATI_R480_RADEON_X850PRO, R_480 }, + { DEVICE_ATI_R481_RADEON_X850XT_PE, R_480|R_PCIE }, + { DEVICE_ATI_R480_RADEON_X850XT2, R_480 }, + { DEVICE_ATI_R480_RADEON_X850PRO2, R_480 }, + { DEVICE_ATI_R481_RADEON_X850XT_PE2, R_480|R_PCIE }, + { DEVICE_ATI_R480_RADEON_X850XT3, R_480|R_PCIE }, + { DEVICE_ATI_R480_RADEON_X850XT4, R_480|R_PCIE }, + { DEVICE_ATI_R480_RADEON_X850XT5, R_480|R_PCIE }, + { DEVICE_ATI_R480_RADEON_X850XT6, R_480|R_PCIE }, + { DEVICE_ATI_R520_FIREGL, R_520 }, + { DEVICE_ATI_R520_GL_ATI, R_520 }, + { DEVICE_ATI_R520_GL_ATI2, R_520 }, + { DEVICE_ATI_R520_RADEON_X1800, R_520 }, + { DEVICE_ATI_R520_RADEON_X18002, R_520 }, + { DEVICE_ATI_R520_RADEON_X18003, R_520 }, + { DEVICE_ATI_R520_RADEON_X18004, R_520 }, + { DEVICE_ATI_R520_RADEON_X18005, R_520 }, + { DEVICE_ATI_R520_RADEON_X18006, R_520 }, + { DEVICE_ATI_R520_RADEON_X18007, R_520 }, + { DEVICE_ATI_M58_RADEON_MOBILITY, R_520 }, + { DEVICE_ATI_M58_RADEON_MOBILITY2, R_520 }, + { DEVICE_ATI_M58_MOBILITY_FIREGL, R_520 }, + { DEVICE_ATI_M58_MOBILITY_FIREGL2, R_520 }, + { DEVICE_ATI_RV515_RADEON_X1600, R_520 }, + { DEVICE_ATI_RV515_RADEON_X1300, R_520 }, + { DEVICE_ATI_RV515_RADEON_X13002, R_520 }, + { DEVICE_ATI_RV515_RADEON_X13003, R_520 }, + { DEVICE_ATI_RV515_RADEON_X13004, R_520 }, + { DEVICE_ATI_RV515_RADEON_X13005, R_520 }, + { DEVICE_ATI_RV515_RADEON_X13006, R_520 }, + { DEVICE_ATI_RV515_RADEON_X13007, R_520 }, + { DEVICE_ATI_RV515_GL_ATI, R_520 }, + { DEVICE_ATI_RV515_GL_ATI2, R_520 }, + { DEVICE_ATI_RADEON_MOBILITY_X1400, R_520 }, + { DEVICE_ATI_M52_ATI_MOBILITY, R_520 }, + { DEVICE_ATI_M52_ATI_MOBILITY2, R_520 }, + { DEVICE_ATI_M52_ATI_MOBILITY3, R_520 }, + { DEVICE_ATI_M52_ATI_MOBILITY4, R_520 }, + { DEVICE_ATI_RV516_RADEON_X1300, R_520 }, + { DEVICE_ATI_RV516_RADEON_X13002, R_520 }, + { DEVICE_ATI_RV516_XT_RADEON, R_520 }, + { DEVICE_ATI_RV516_XT_RADEON2, R_520 }, + { DEVICE_ATI_RV530_RADEON_X1600, R_520 }, + { DEVICE_ATI_RV530_RADEON_X16002, R_520 }, + { DEVICE_ATI_M56GL_ATI_MOBILITY, R_520 }, + { DEVICE_ATI_M56P_RADEON_MOBILITY, R_520 }, + { DEVICE_ATI_M66_P_ATI_MOBILITY, R_520 }, + { DEVICE_ATI_M66_XT_ATI_MOBILITY, R_520 }, + { DEVICE_ATI_RV530LE_RADEON_X1600, R_520 }, + { DEVICE_ATI_RV530LE_RADEON_X16002, R_520 }, + { DEVICE_ATI_RV530LE_RADEON_X16003, R_520 }, + { DEVICE_ATI_RV530_RADEON_X16003, R_520 }, + { DEVICE_ATI_RV530_RADEON_X16004, R_520 }, + { DEVICE_ATI_R580_RADEON_X1900, R_520 }, + { DEVICE_ATI_R580_RADEON_X19002, R_520 }, + { DEVICE_ATI_R580_RADEON_X19003, R_520 }, + { DEVICE_ATI_R580_RADEON_X19004, R_520 }, + { DEVICE_ATI_R580_RADEON_X19005, R_520 }, + { DEVICE_ATI_R580_RADEON_X19006, R_520 }, + { DEVICE_ATI_R580_RADEON_X19007, R_520 }, + { DEVICE_ATI_R580_RADEON_X19008, R_520 }, + { DEVICE_ATI_R580_RADEON_X19009, R_520 }, + { DEVICE_ATI_R580_RADEON_X190010, R_520 }, + { DEVICE_ATI_R580_RADEON_X190011, R_520 }, + { DEVICE_ATI_R580_RADEON_X190012, R_520 }, + { DEVICE_ATI_R580_RADEON_X190013, R_520 }, + { DEVICE_ATI_R580_RADEON_X190014, R_520 }, + { DEVICE_ATI_R580_RADEON_X190015, R_520 }, + { DEVICE_ATI_R580_FIREGL_V7300_V7350, R_520 }, + { DEVICE_ATI_R580_FIREGL_V7300_V73502, R_520 }, #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; -/* Restore on exit */ -static uint32_t SAVED_OV0_GRAPHICS_KEY_CLR = 0; -static uint32_t SAVED_OV0_GRAPHICS_KEY_MSK = 0; -static uint32_t SAVED_OV0_VID_KEY_CLR = 0; -static uint32_t SAVED_OV0_VID_KEY_MSK = 0; -static uint32_t SAVED_OV0_KEY_CNTL = 0; -#ifdef WORDS_BIGENDIAN -static uint32_t SAVED_CONFIG_CNTL = 0; -#if defined(RAGE128) -#define APER_0_BIG_ENDIAN_16BPP_SWAP (1<<0) -#define APER_0_BIG_ENDIAN_32BPP_SWAP (2<<0) -#else -#define RADEON_SURFACE_CNTL 0x0b00 -#define RADEON_NONSURF_AP0_SWP_16BPP (1 << 20) -#define RADEON_NONSURF_AP0_SWP_32BPP (1 << 21) -#endif -#endif #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,(uint8_t*)(radeon_mmio_base),addr) -#define OUTREG8(addr,val) SETREG(uint8_t,(uint8_t*)(radeon_mmio_base),addr,val) - +#define INREG8(addr) GETREG(uint8_t,(uint8_t *)(radeon_mmio_base),addr) +#define OUTREG8(addr,val) SETREG(uint8_t,(uint8_t *)(radeon_mmio_base),addr,val) static inline uint32_t INREG (uint32_t addr) { - uint32_t tmp = GETREG(uint32_t,(uint8_t*)(radeon_mmio_base),addr); - return le2me_32(tmp); + uint32_t tmp = GETREG(uint32_t,(uint8_t *)(radeon_mmio_base),addr); + return le2me_32(tmp); } -//#define OUTREG(addr,val) SETREG(uint32_t,(uint8_t*)(radeon_mmio_base),addr,val) -#define OUTREG(addr,val) SETREG(uint32_t,(uint8_t*)(radeon_mmio_base),addr,le2me_32(val)) -#define OUTREGP(addr,val,mask) \ +#define OUTREG(addr,val) SETREG(uint32_t,(uint8_t *)(radeon_mmio_base),addr,le2me_32(val)) +#define OUTREGP(addr,val,mask) \ do { \ unsigned int _tmp = INREG(addr); \ _tmp &= (mask); \ @@ -260,7 +601,7 @@ static __inline__ uint32_t INPLL(uint32_t addr) #define OUTPLL(addr,val) OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000001f) | 0x00000080); \ OUTREG(CLOCK_CNTL_DATA, val) -#define OUTPLLP(addr,val,mask) \ +#define OUTPLLP(addr,val,mask) \ do { \ unsigned int _tmp = INPLL(addr); \ _tmp &= (mask); \ @@ -268,6 +609,85 @@ static __inline__ uint32_t INPLL(uint32_t addr) OUTPLL(addr, _tmp); \ } while (0) +#ifndef RAGE128 +enum radeon_montype +{ + MT_NONE, + MT_CRT, /* CRT-(cathode ray tube) analog monitor. (15-pin VGA connector) */ + MT_LCD, /* Liquid Crystal Display */ + MT_DFP, /* DFP-digital flat panel monitor. (24-pin DVI-I connector) */ + MT_CTV, /* Composite TV out (not in VE) */ + MT_STV /* S-Video TV out (probably in VE only) */ +}; + +typedef struct radeon_info_s +{ + int hasCRTC2; + int crtDispType; + int dviDispType; +}rinfo_t; + +static rinfo_t rinfo; + +static char * GET_MON_NAME(int type) +{ + char *pret; + switch(type) + { + case MT_NONE: pret = "no"; break; + case MT_CRT: pret = "CRT"; break; + case MT_DFP: pret = "DFP"; break; + case MT_LCD: pret = "LCD"; break; + case MT_CTV: pret = "CTV"; break; + case MT_STV: pret = "STV"; break; + default: pret = "Unknown"; + } + return pret; +} + +static void radeon_get_moninfo (rinfo_t *rinfo) +{ + unsigned int tmp; + + tmp = INREG(RADEON_BIOS_4_SCRATCH); + + if (rinfo->hasCRTC2) { + /* primary DVI port */ + if (tmp & 0x08) + rinfo->dviDispType = MT_DFP; + else if (tmp & 0x4) + rinfo->dviDispType = MT_LCD; + else if (tmp & 0x200) + rinfo->dviDispType = MT_CRT; + else if (tmp & 0x10) + rinfo->dviDispType = MT_CTV; + else if (tmp & 0x20) + rinfo->dviDispType = MT_STV; + + /* secondary CRT port */ + if (tmp & 0x2) + rinfo->crtDispType = MT_CRT; + else if (tmp & 0x800) + rinfo->crtDispType = MT_DFP; + else if (tmp & 0x400) + rinfo->crtDispType = MT_LCD; + else if (tmp & 0x1000) + rinfo->crtDispType = MT_CTV; + else if (tmp & 0x2000) + rinfo->crtDispType = MT_STV; + } else { + rinfo->dviDispType = MT_NONE; + + tmp = INREG(FP_GEN_CNTL); + + if (tmp & FP_EN_TMDS) + rinfo->crtDispType = MT_DFP; + else + rinfo->crtDispType = MT_CRT; + } +} +#endif + static uint32_t radeon_vid_get_dbpp( void ) { uint32_t dbpp,retval; @@ -295,35 +715,32 @@ static int radeon_is_interlace( void ) 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); +#ifndef RAGE128 + if(rinfo.hasCRTC2 && + (rinfo.dviDispType == MT_CTV || rinfo.dviDispType == MT_STV)) + h_total = INREG(CRTC2_H_TOTAL_DISP); + else +#endif + 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); +#ifndef RAGE128 + if(rinfo.hasCRTC2 && + (rinfo.dviDispType == MT_CTV || rinfo.dviDispType == MT_STV)) + v_total = INREG(CRTC2_V_TOTAL_DISP); + else +#endif + v_total = INREG(CRTC_V_TOTAL_DISP); yres = (v_total >> 16) & 0xffff; return yres + 1; } -/* get flat panel x resolution*/ -static uint32_t radeon_get_fp_xres( void ){ - uint32_t xres=(INREG(FP_HORZ_STRETCH)&0x00fff000)>>16; - xres=(xres+1)*8; - return xres; -} - -/* get flat panel y resolution*/ -static uint32_t radeon_get_fp_yres( void ){ - uint32_t yres=(INREG(FP_VERT_STRETCH)&0x00fff000)>>12; - return yres+1; -} - static void radeon_wait_vsync(void) { int i; @@ -361,7 +778,7 @@ static void radeon_engine_reset( void ) radeon_engine_flush(); clock_cntl_index = INREG(CLOCK_CNTL_INDEX); - mclk_cntl = INPLL(MCLK_CNTL); + mclk_cntl = INPLL(MCLK_CNTL); OUTPLL(MCLK_CNTL, mclk_cntl | FORCE_GCP | FORCE_PIPE3D_CP); @@ -373,7 +790,7 @@ static void radeon_engine_reset( void ) gen_reset_cntl & (uint32_t)(~SOFT_RESET_GUI)); INREG(GEN_RESET_CNTL); - OUTPLL(MCLK_CNTL, mclk_cntl); + OUTPLL(MCLK_CNTL, mclk_cntl); OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index); OUTREG(GEN_RESET_CNTL, gen_reset_cntl); } @@ -385,7 +802,7 @@ static __inline__ void radeon_engine_flush ( void ) /* initiate flush */ OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL, - ~RB2D_DC_FLUSH_ALL); + ~RB2D_DC_FLUSH_ALL); for (i=0; i < 2000000; i++) { if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY)) @@ -464,9 +881,8 @@ static void radeon_engine_restore( void ) radeon_fifo_wait(1); #if defined(WORDS_BIGENDIAN) -#ifdef RADEON - OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN); -#endif + OUTREGP(DP_DATATYPE, + HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN); #else OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN); #endif @@ -578,19 +994,19 @@ REF_TRANSFORM trans[2] = {1.1678, 0.0, 1.7980, -0.2139, -0.5345, 2.1186, 0.0} /* BT.709 */ }; /**************************************************************************** - * SetTransform * - * Function: Calculates and sets color space transform from supplied * - * reference transform, gamma, brightness, contrast, hue and * - * saturation. * - * Inputs: bright - brightness * - * cont - contrast * - * sat - saturation * - * hue - hue * - * red_intensity - intense of red component * - * green_intensity - intense of green component * - * blue_intensity - intense of blue component * - * ref - index to the table of refernce transforms * - * Outputs: NONE * + * SetTransform * + * Function: Calculates and sets color space transform from supplied * + * reference transform, gamma, brightness, contrast, hue and * + * saturation. * + * Inputs: bright - brightness * + * cont - contrast * + * sat - saturation * + * hue - hue * + * red_intensity - intense of red component * + * green_intensity - intense of green component * + * blue_intensity - intense of blue component * + * ref - index to the table of refernce transforms * + * Outputs: NONE * ****************************************************************************/ static void radeon_set_transform(float bright, float cont, float sat, @@ -635,7 +1051,7 @@ static void radeon_set_transform(float bright, float cont, float sat, CAdjBCr = sat * OvHueSin * trans[ref].RefBCb; #if 0 /* default constants */ - CAdjLuma = 1.16455078125; + CAdjLuma = 1.16455078125; CAdjRCb = 0.0; CAdjRCr = 1.59619140625; @@ -669,7 +1085,7 @@ static void radeon_set_transform(float bright, float cont, float sat, /* Whatever docs say about R200 having 3.8 format instead of 3.11 as in Radeon is a lie */ #if 0 - if(RadeonFamily == 100) + if(!IsR200) { #endif dwOvLuma =(((int)(OvLuma * 2048.0))&0x7fff)<<17; @@ -744,7 +1160,9 @@ GAMMA_SETTINGS r100_def_gamma[6] = static void make_default_gamma_correction( void ) { size_t i; - if(RadeonFamily == 100) { + if((besr.chip_flags & R_100)==R_100|| + (besr.chip_flags & R_120)==R_120|| + (besr.chip_flags & R_150)==R_150){ OUTREG(OV0_LIN_TRANS_A, 0x12A00000); OUTREG(OV0_LIN_TRANS_B, 0x199018FE); OUTREG(OV0_LIN_TRANS_C, 0x12A0F9B0); @@ -754,24 +1172,23 @@ static void make_default_gamma_correction( void ) for(i=0; i<6; i++){ OUTREG(r100_def_gamma[i].gammaReg, (r100_def_gamma[i].gammaSlope<<16) | - r100_def_gamma[i].gammaOffset); + r100_def_gamma[i].gammaOffset); } } else{ - OUTREG(OV0_LIN_TRANS_A, 0x12a00000); - OUTREG(OV0_LIN_TRANS_B, 0x1990190e); - OUTREG(OV0_LIN_TRANS_C, 0x12a0f9c0); - OUTREG(OV0_LIN_TRANS_D, 0xf3000442); - OUTREG(OV0_LIN_TRANS_E, 0x12a02040); + OUTREG(OV0_LIN_TRANS_A, 0x12a20000); + OUTREG(OV0_LIN_TRANS_B, 0x198a190e); + OUTREG(OV0_LIN_TRANS_C, 0x12a2f9da); + OUTREG(OV0_LIN_TRANS_D, 0xf2fe0442); + OUTREG(OV0_LIN_TRANS_E, 0x12a22046); OUTREG(OV0_LIN_TRANS_F, 0x175f); - /* Default Gamma, Of 18 segments for gamma cure, all segments in R200 are programmable, while only lower 4 and upper 2 segments are programmable in Radeon*/ for(i=0; i<18; i++){ OUTREG(r200_def_gamma[i].gammaReg, (r200_def_gamma[i].gammaSlope<<16) | - r200_def_gamma[i].gammaOffset); + r200_def_gamma[i].gammaOffset); } } } @@ -780,7 +1197,9 @@ static void make_default_gamma_correction( void ) static void radeon_vid_make_default(void) { #ifdef RAGE128 - OUTREG(OV0_COLOUR_CNTL,0x00101000UL); /* Default brightness and saturation for Rage128 */ + besr.saturation = 0x0F; + besr.brightness = 0; + OUTREG(OV0_COLOUR_CNTL,0x000F0F00UL); /* Default brihgtness and saturation for Rage128 */ #else make_default_gamma_correction(); #endif @@ -794,133 +1213,12 @@ static void radeon_vid_make_default(void) besr.ckey_cntl = VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_TRUE|CMP_MIX_AND; } -static unsigned short ati_card_ids[] = -{ -#ifdef RAGE128 - /* - This driver should be compatible with Rage128 (pro) chips. - (include adaptive deinterlacing!!!). - Moreover: the same logic can be used with Mach64 chips. - (I mean: mach64xx, 3d rage, 3d rage IIc, 3D rage pro, 3d rage mobility). - but they are incompatible by i/o ports. So if enthusiasts will want - then they can redefine OUTREG and INREG macros and redefine OV0_* - constants. Also it seems that mach64 chips supports only: YUY2, YV12, UYVY - fourccs (422 and 420 formats only). - */ -/* Rage128 Pro GL */ - DEVICE_ATI_RAGE_128_PA_PRO, - DEVICE_ATI_RAGE_128_PB_PRO, - DEVICE_ATI_RAGE_128_PC_PRO, - DEVICE_ATI_RAGE_128_PD_PRO, - DEVICE_ATI_RAGE_128_PE_PRO, - DEVICE_ATI_RAGE_128_PF_PRO, -/* Rage128 Pro VR */ - DEVICE_ATI_RAGE_128_PG_PRO, - DEVICE_ATI_RAGE_128_PH_PRO, - DEVICE_ATI_RAGE_128_PI_PRO, - DEVICE_ATI_RAGE_128_PJ_PRO, - DEVICE_ATI_RAGE_128_PK_PRO, - DEVICE_ATI_RAGE_128_PL_PRO, - DEVICE_ATI_RAGE_128_PM_PRO, - DEVICE_ATI_RAGE_128_PN_PRO, - DEVICE_ATI_RAGE_128_PO_PRO, - DEVICE_ATI_RAGE_128_PP_PRO, - DEVICE_ATI_RAGE_128_PQ_PRO, - DEVICE_ATI_RAGE_128_PR_PRO, - DEVICE_ATI_RAGE_128_PS_PRO, - DEVICE_ATI_RAGE_128_PT_PRO, - DEVICE_ATI_RAGE_128_PU_PRO, - DEVICE_ATI_RAGE_128_PV_PRO, - DEVICE_ATI_RAGE_128_PW_PRO, - DEVICE_ATI_RAGE_128_PX_PRO, -/* Rage128 GL */ - DEVICE_ATI_RAGE_128_RE_SG, - DEVICE_ATI_RAGE_128_RF_SG, - DEVICE_ATI_RAGE_128_RG, - DEVICE_ATI_RAGE_128_RK_VR, - DEVICE_ATI_RAGE_128_RL_VR, - DEVICE_ATI_RAGE_128_SE_4X, - DEVICE_ATI_RAGE_128_SF_4X, - DEVICE_ATI_RAGE_128_SG_4X, - DEVICE_ATI_RAGE_128_SH, - DEVICE_ATI_RAGE_128_SK_4X, - DEVICE_ATI_RAGE_128_SL_4X, - DEVICE_ATI_RAGE_128_SM_4X, - DEVICE_ATI_RAGE_128_4X, - DEVICE_ATI_RAGE_128_PRO, - DEVICE_ATI_RAGE_128_PRO2, - DEVICE_ATI_RAGE_128_PRO3, -/* these seem to be based on rage 128 instead of mach64 */ - DEVICE_ATI_RAGE_MOBILITY_M3, - DEVICE_ATI_RAGE_MOBILITY_M32 -#else -/* Radeons (indeed: Rage 256 Pro ;) */ - DEVICE_ATI_RADEON_R100_QD, - DEVICE_ATI_RADEON_R100_QE, - DEVICE_ATI_RADEON_R100_QF, - DEVICE_ATI_RADEON_R100_QG, - DEVICE_ATI_RADEON_RV100_QY, - DEVICE_ATI_RADEON_RV100_QZ, - DEVICE_ATI_RADEON_MOBILITY_M7, - DEVICE_ATI_RADEON_RV200_LX, - DEVICE_ATI_RADEON_MOBILITY_M6, - DEVICE_ATI_RADEON_MOBILITY_M62, - DEVICE_ATI_RADEON_MOBILITY_U1, - DEVICE_ATI_R200_BB_RADEON, - DEVICE_ATI_RADEON_R200_QH, - DEVICE_ATI_RADEON_R200_QI, - DEVICE_ATI_RADEON_R200_QJ, - DEVICE_ATI_RADEON_R200_QK, - DEVICE_ATI_RADEON_R200_QL, - DEVICE_ATI_RADEON_R200_QM, - DEVICE_ATI_RADEON_R200_QH2, - DEVICE_ATI_RADEON_R200_QI2, - DEVICE_ATI_RADEON_R200_QJ2, - DEVICE_ATI_RADEON_R200_QK2, - DEVICE_ATI_RADEON_RV200_QW, - DEVICE_ATI_RADEON_RV200_QX, - DEVICE_ATI_RADEON_RV250_ID, - DEVICE_ATI_RADEON_RV250_IE, - DEVICE_ATI_RADEON_RV250_IF, - DEVICE_ATI_RADEON_RV250_IG, - DEVICE_ATI_RADEON_R250_LD, - DEVICE_ATI_RADEON_R250_LE, - DEVICE_ATI_RADEON_R250_MOBILITY, - DEVICE_ATI_RADEON_R250_LG, - DEVICE_ATI_RV370_5B60_RADEON, - DEVICE_ATI_M9_5C61_RADEON, - DEVICE_ATI_M9_5C63_RADEON, - DEVICE_ATI_RV280_RADEON_9200, - DEVICE_ATI_RV280_RADEON_92002, - DEVICE_ATI_RV280_RADEON_92003, - DEVICE_ATI_RV280_RADEON_92004, - DEVICE_ATI_RV280_RADEON_92005, - DEVICE_ATI_RV280_RADEON_92006, - DEVICE_ATI_RADEON_R300_ND, - DEVICE_ATI_RADEON_R300_NE, - DEVICE_ATI_RV350_NF_RADEON, - DEVICE_ATI_RADEON_R300_NG, - DEVICE_ATI_R300_AE_RADEON, - DEVICE_ATI_R300_AF_RADEON, - DEVICE_ATI_RV350_AP_RADEON, - DEVICE_ATI_RV350_AQ_RADEON, - DEVICE_ATI_RV350_AR_RADEON, - DEVICE_ATI_RV350_AS_RADEON, - DEVICE_ATI_R350_AH_RADEON, - DEVICE_ATI_R350_AI_RADEON, - DEVICE_ATI_RADEON_R350_RADEON2, - DEVICE_ATI_RV350_NJ_RADEON, - DEVICE_ATI_RV350_MOBILITY_RADEON, - DEVICE_ATI_RV350_MOBILITY_RADEON2 -#endif -}; - static int find_chip(unsigned chip_id) { unsigned i; - for(i = 0;i < sizeof(ati_card_ids)/sizeof(unsigned short);i++) + for(i = 0;i < sizeof(ati_card_ids)/sizeof(ati_card_ids_t);i++) { - if(chip_id == ati_card_ids[i]) return i; + if(chip_id == ati_card_ids[i].id) return i; } return -1; } @@ -949,8 +1247,7 @@ static vidix_capability_t def_cap = { 0, 0, 0, 0} }; -#ifndef RAGE128 -#ifdef HAVE_X11 +#if !defined(RAGE128) && defined(HAVE_X11) static void probe_fireGL_driver(void) { Display *dp = XOpenDisplay ((void*)0); int n = 0; @@ -972,16 +1269,15 @@ static void probe_fireGL_driver(void) { firegl_shift = 0x500000; if (!ext_fglrx) { printf(", but DRI seems not to be activated\n"); - printf(RADEON_MSG" Output may not work correctly, check your DRI configuration!"); + printf(RADEON_MSG" Output may not work correctly, check your DRI configration!"); } printf("\n"); } } } #endif -#endif -static int radeon_probe( int verbose,int force ) +static int radeon_probe(int verbose, int force) { pciinfo_t lst[MAX_PCI_DEVICES]; unsigned i,num_pci; @@ -1000,121 +1296,19 @@ static int radeon_probe( int verbose,int force ) { if(lst[i].vendor == VENDOR_ATI) { - int idx; + int idx; const char *dname; idx = find_chip(lst[i].device); if(idx == -1 && force == PROBE_NORMAL) continue; dname = pci_device_name(VENDOR_ATI,lst[i].device); dname = dname ? dname : "Unknown chip"; printf(RADEON_MSG" Found chip: %s\n",dname); -#if 0 - if ((lst[i].command & PCI_COMMAND_IO) == 0) - { - printf("[radeon] Device is disabled, ignoring\n"); - continue; - } -#endif -#ifndef RAGE128 - if(idx != -1) -#ifdef HAVE_X11 - probe_fireGL_driver(); -#endif - { - switch(ati_card_ids[idx]) { - /* Original radeon */ - case DEVICE_ATI_RADEON_R100_QD: - case DEVICE_ATI_RADEON_R100_QE: - case DEVICE_ATI_RADEON_R100_QF: - case DEVICE_ATI_RADEON_R100_QG: - RadeonFamily = 100; - break; - - /* Radeon VE / Radeon Mobility */ - case DEVICE_ATI_RADEON_RV100_QY: - case DEVICE_ATI_RADEON_RV100_QZ: - case DEVICE_ATI_RADEON_MOBILITY_M6: - case DEVICE_ATI_RADEON_MOBILITY_M62: - case DEVICE_ATI_RADEON_MOBILITY_U1: - RadeonFamily = 120; - break; - - /* Radeon 7500 / Radeon Mobility 7500 */ - case DEVICE_ATI_RADEON_RV200_QW: - case DEVICE_ATI_RADEON_RV200_QX: - case DEVICE_ATI_RADEON_MOBILITY_M7: - case DEVICE_ATI_RADEON_RV200_LX: - RadeonFamily = 150; - break; - - /* Radeon 8500 */ - case DEVICE_ATI_R200_BB_RADEON: - case DEVICE_ATI_RADEON_R200_QH: - case DEVICE_ATI_RADEON_R200_QI: - case DEVICE_ATI_RADEON_R200_QJ: - case DEVICE_ATI_RADEON_R200_QK: - case DEVICE_ATI_RADEON_R200_QL: - case DEVICE_ATI_RADEON_R200_QM: - case DEVICE_ATI_RADEON_R200_QH2: - case DEVICE_ATI_RADEON_R200_QI2: - case DEVICE_ATI_RADEON_R200_QJ2: - case DEVICE_ATI_RADEON_R200_QK2: - RadeonFamily = 200; - break; - - /* Radeon 9000 */ - case DEVICE_ATI_RADEON_RV250_ID: - case DEVICE_ATI_RADEON_RV250_IE: - case DEVICE_ATI_RADEON_RV250_IF: - case DEVICE_ATI_RADEON_RV250_IG: - case DEVICE_ATI_RADEON_R250_LD: - case DEVICE_ATI_RADEON_R250_LE: - case DEVICE_ATI_RADEON_R250_MOBILITY: - case DEVICE_ATI_RADEON_R250_LG: - case DEVICE_ATI_M9_5C61_RADEON: - case DEVICE_ATI_M9_5C63_RADEON: - RadeonFamily = 250; - break; - - /* Radeon 9200 */ - case DEVICE_ATI_RV280_RADEON_9200: - case DEVICE_ATI_RV280_RADEON_92002: - case DEVICE_ATI_RV280_RADEON_92003: - case DEVICE_ATI_RV280_RADEON_92004: - case DEVICE_ATI_RV280_RADEON_92005: - case DEVICE_ATI_RV280_RADEON_92006: - RadeonFamily = 280; - break; - - /* Radeon 9700 */ - case DEVICE_ATI_RADEON_R300_ND: - case DEVICE_ATI_RADEON_R300_NE: - case DEVICE_ATI_RV350_NF_RADEON: - case DEVICE_ATI_RADEON_R300_NG: - case DEVICE_ATI_R300_AE_RADEON: - case DEVICE_ATI_R300_AF_RADEON: - RadeonFamily = 300; - break; - - /* Radeon 9600/9800 */ - case DEVICE_ATI_RV370_5B60_RADEON: - case DEVICE_ATI_RV350_AP_RADEON: - case DEVICE_ATI_RV350_AQ_RADEON: - case DEVICE_ATI_RV350_AR_RADEON: - case DEVICE_ATI_RV350_AS_RADEON: - case DEVICE_ATI_RADEON_R350_RADEON2: - case DEVICE_ATI_R350_AH_RADEON: - case DEVICE_ATI_R350_AI_RADEON: - case DEVICE_ATI_RV350_NJ_RADEON: - case DEVICE_ATI_RV350_MOBILITY_RADEON: - case DEVICE_ATI_RV350_MOBILITY_RADEON2: - RadeonFamily = 350; - break; - - default: - break; - } - } -#endif + if ((lst[i].command & PCI_COMMAND_IO) == 0) + { + printf("[radeon] Device is disabled, ignoring\n"); + continue; + } + memset(&besr,0,sizeof(bes_registers_t)); if(force > PROBE_NORMAL) { printf(RADEON_MSG" Driver was forced. Was found %sknown chip\n",idx == -1 ? "un" : ""); @@ -1124,7 +1318,12 @@ static int radeon_probe( int verbose,int force ) #else printf(RADEON_MSG" Assuming it as Radeon1\n"); #endif + besr.chip_flags=R_100|R_OVL_SHIFT; } +#if !defined(RAGE128) && defined(HAVE_X11) + probe_fireGL_driver(); +#endif + if(idx != -1) besr.chip_flags=ati_card_ids[idx].flags; def_cap.device_id = lst[i].device; err = 0; memcpy(&pci_info,&lst[i],sizeof(pciinfo_t)); @@ -1137,11 +1336,45 @@ static int radeon_probe( int verbose,int force ) return err; } -static void radeon_vid_dump_regs( void ); /* forward declaration */ +typedef struct saved_regs_s +{ + uint32_t ov0_vid_key_clr; + uint32_t ov0_vid_key_msk; + uint32_t ov0_graphics_key_clr; + uint32_t ov0_graphics_key_msk; + uint32_t ov0_key_cntl; + uint32_t disp_merge_cntl; +}saved_regs_t; +static saved_regs_t savreg; + +static void save_regs( void ) +{ + radeon_fifo_wait(6); + savreg.ov0_vid_key_clr = INREG(OV0_VID_KEY_CLR); + savreg.ov0_vid_key_msk = INREG(OV0_VID_KEY_MSK); + savreg.ov0_graphics_key_clr = INREG(OV0_GRAPHICS_KEY_CLR); + savreg.ov0_graphics_key_msk = INREG(OV0_GRAPHICS_KEY_MSK); + savreg.ov0_key_cntl = INREG(OV0_KEY_CNTL); + savreg.disp_merge_cntl = INREG(DISP_MERGE_CNTL); +} -static int radeon_init( void ) +static void restore_regs( void ) +{ + radeon_fifo_wait(6); + OUTREG(OV0_VID_KEY_CLR,savreg.ov0_vid_key_clr); + OUTREG(OV0_VID_KEY_MSK,savreg.ov0_vid_key_msk); + OUTREG(OV0_GRAPHICS_KEY_CLR,savreg.ov0_graphics_key_clr); + OUTREG(OV0_GRAPHICS_KEY_MSK,savreg.ov0_graphics_key_msk); + OUTREG(OV0_KEY_CNTL,savreg.ov0_key_cntl); + OUTREG(DISP_MERGE_CNTL,savreg.disp_merge_cntl); +} + +static int radeon_init(void) { int err; + + if(__verbose>0) printf("[radeon_vid] version %d\n", VIDIX_VERSION); + if(!probed) { printf(RADEON_MSG" Driver was not probed but is being initializing\n"); @@ -1164,102 +1397,38 @@ static int radeon_init( void ) /* Rage Mobility (rage128) also has memsize bug */ if (radeon_ram_size == 0 && (def_cap.device_id == DEVICE_ATI_RAGE_MOBILITY_M3 || - def_cap.device_id == DEVICE_ATI_RAGE_128_RL_VR || def_cap.device_id == DEVICE_ATI_RAGE_MOBILITY_M32)) { printf(RADEON_MSG" Workarounding buggy Rage Mobility M3 (0 vs. 8MB ram)\n"); radeon_ram_size = 8192*1024; } -#endif - printf(RADEON_MSG" Video memory = %uMb\n",radeon_ram_size/0x100000); -#ifdef WIN32 - //mapping large areas of video ram will fail on windows - if(radeon_ram_size > 16*1024*1024)radeon_ram_size=16*1024*1024; #endif if((radeon_mem_base = map_phys_mem(pci_info.base0,radeon_ram_size))==(void *)-1) return ENOMEM; - memset(&besr,0,sizeof(bes_registers_t)); radeon_vid_make_default(); + printf(RADEON_MSG" Video memory = %uMb\n",radeon_ram_size/0x100000); err = mtrr_set_type(pci_info.base0,radeon_ram_size,MTRR_TYPE_WRCOMB); if(!err) printf(RADEON_MSG" Set write-combining type of video memory\n"); - - radeon_fifo_wait(3); - SAVED_OV0_GRAPHICS_KEY_CLR = INREG(OV0_GRAPHICS_KEY_CLR); - SAVED_OV0_GRAPHICS_KEY_MSK = INREG(OV0_GRAPHICS_KEY_MSK); - SAVED_OV0_VID_KEY_CLR = INREG(OV0_VID_KEY_CLR); - SAVED_OV0_VID_KEY_MSK = INREG(OV0_VID_KEY_MSK); - SAVED_OV0_KEY_CNTL = INREG(OV0_KEY_CNTL); - printf(RADEON_MSG" Saved overlay colorkey settings\n"); - -#ifdef RADEON - switch(RadeonFamily) - { - case 100: - case 120: - case 150: - case 250: - case 280: - is_shift_required=1; - break; - default: - break; - } -#endif - -/* XXX: hack, but it works for me (tm) */ -#ifdef WORDS_BIGENDIAN -#if defined(RAGE128) - /* code from gatos */ - { - SAVED_CONFIG_CNTL = INREG(CONFIG_CNTL); - OUTREG(CONFIG_CNTL, SAVED_CONFIG_CNTL & - ~(APER_0_BIG_ENDIAN_16BPP_SWAP|APER_0_BIG_ENDIAN_32BPP_SWAP)); - -// printf("saved: %x, current: %x\n", SAVED_CONFIG_CNTL, -// INREG(CONFIG_CNTL)); - } -#else - /*code from radeon_video.c*/ - { - SAVED_CONFIG_CNTL = INREG(RADEON_SURFACE_CNTL); -/* OUTREG(RADEON_SURFACE_CNTL, (SAVED_CONFIG_CNTL | - RADEON_NONSURF_AP0_SWP_32BPP) & ~RADEON_NONSURF_AP0_SWP_16BPP); -*/ - OUTREG(RADEON_SURFACE_CNTL, SAVED_CONFIG_CNTL & ~(RADEON_NONSURF_AP0_SWP_32BPP - | RADEON_NONSURF_AP0_SWP_16BPP)); - -/* - OUTREG(RADEON_SURFACE_CNTL, (SAVED_CONFIG_CNTL | RADEON_NONSURF_AP0_SWP_32BPP) - & ~RADEON_NONSURF_AP0_SWP_16BPP); -*/ - } -#endif +#ifndef RAGE128 + { + memset(&rinfo,0,sizeof(rinfo_t)); + if((besr.chip_flags&R_100) != R_100) rinfo.hasCRTC2 = 1; + + radeon_get_moninfo(&rinfo); + if(rinfo.hasCRTC2) { + printf(RADEON_MSG" DVI port has %s monitor connected\n",GET_MON_NAME(rinfo.dviDispType)); + printf(RADEON_MSG" CRT port has %s monitor connected\n",GET_MON_NAME(rinfo.crtDispType)); + } + else + printf(RADEON_MSG" CRT port has %s monitor connected\n",GET_MON_NAME(rinfo.crtDispType)); + } #endif - - if(__verbose > 1) radeon_vid_dump_regs(); + save_regs(); return 0; } -static void radeon_destroy( void ) -{ - /* remove colorkeying */ - radeon_fifo_wait(3); - OUTREG(OV0_GRAPHICS_KEY_CLR, SAVED_OV0_GRAPHICS_KEY_CLR); - OUTREG(OV0_GRAPHICS_KEY_MSK, SAVED_OV0_GRAPHICS_KEY_MSK); - OUTREG(OV0_VID_KEY_CLR, SAVED_OV0_VID_KEY_CLR); - OUTREG(OV0_VID_KEY_MSK, SAVED_OV0_VID_KEY_MSK); - OUTREG(OV0_KEY_CNTL, SAVED_OV0_KEY_CNTL); - printf(RADEON_MSG" Restored overlay colorkey settings\n"); - -#ifdef WORDS_BIGENDIAN -#if defined(RAGE128) - OUTREG(CONFIG_CNTL, SAVED_CONFIG_CNTL); -// printf("saved: %x, restored: %x\n", SAVED_CONFIG_CNTL, -// INREG(CONFIG_CNTL)); -#else - OUTREG(RADEON_SURFACE_CNTL, SAVED_CONFIG_CNTL); -#endif -#endif - +static void radeon_destroy(void) +{ + restore_regs(); unmap_phys_mem(radeon_mem_base,radeon_ram_size); unmap_phys_mem(radeon_mmio_base,0xFFFF); } @@ -1271,26 +1440,42 @@ static int radeon_get_caps(vidix_capability_t *to) } /* - Full list of fourcc which are supported by Win2K redeon driver: + Full list of fourcc which are supported by Win2K radeon driver: YUY2, UYVY, DDES, OGLT, OGL2, OGLS, OGLB, OGNT, OGNZ, OGNS, IF09, YVU9, IMC4, M2IA, IYUV, VBID, DXT1, DXT2, DXT3, DXT4, DXT5 */ -static uint32_t supported_fourcc[] = -{ - IMGFMT_Y800, IMGFMT_Y8, IMGFMT_YVU9, IMGFMT_IF09, - IMGFMT_YV12, IMGFMT_I420, IMGFMT_IYUV, - IMGFMT_UYVY, IMGFMT_YUY2, IMGFMT_YVYU, - IMGFMT_RGB15, IMGFMT_BGR15, - IMGFMT_RGB16, IMGFMT_BGR16, - IMGFMT_RGB32, IMGFMT_BGR32 +typedef struct fourcc_desc_s +{ + uint32_t fourcc; + unsigned max_srcw; +}fourcc_desc_t; + +static fourcc_desc_t supported_fourcc[] = +{ + { IMGFMT_Y800, 1567 }, + { IMGFMT_YVU9, 1567 }, + { IMGFMT_IF09, 1567 }, + { IMGFMT_YV12, 1567 }, + { IMGFMT_I420, 1567 }, + { IMGFMT_IYUV, 1567 }, + { IMGFMT_UYVY, 1551 }, + { IMGFMT_YUY2, 1551 }, + { IMGFMT_YVYU, 1551 }, + { IMGFMT_RGB15, 1551 }, + { IMGFMT_BGR15, 1551 }, + { IMGFMT_RGB16, 1551 }, + { IMGFMT_BGR16, 1551 }, + { IMGFMT_RGB32, 775 }, + { IMGFMT_BGR32, 775 } }; -inline static int is_supported_fourcc(uint32_t fourcc) +__inline__ static int is_supported_fourcc(uint32_t fourcc) { - unsigned int i; - for(i=0;iflags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY; + to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY | + VID_CAP_BLEND; return 0; } else to->depth = to->flags = 0; return ENOSYS; } +static double H_scale_ratio; static void radeon_vid_dump_regs( void ) { size_t i; @@ -1320,7 +1507,7 @@ static void radeon_vid_dump_regs( void ) printf(RADEON_MSG"radeon_overlay_off=%08X\n",radeon_overlay_off); printf(RADEON_MSG"radeon_ram_size=%08X\n",radeon_ram_size); printf(RADEON_MSG"video mode: %ux%u@%u\n",radeon_get_xres(),radeon_get_yres(),radeon_vid_get_dbpp()); - printf(RADEON_MSG"flatpanel size: %ux%u\n",radeon_get_fp_xres(),radeon_get_fp_yres()); + printf(RADEON_MSG"H_scale_ratio=%8.2f\n",H_scale_ratio); printf(RADEON_MSG"*** Begin of OV0 registers dump ***\n"); for(i=0;i 1) printf(RADEON_MSG"we wanted: scaler=%08X\n",bes_flags); - if(__verbose > 1) radeon_vid_dump_regs(); + if(__verbose > VERBOSE_LEVEL) printf(RADEON_MSG"we wanted: scaler=%08X\n",bes_flags); + if(__verbose > VERBOSE_LEVEL) radeon_vid_dump_regs(); +} + +/* Goal of this function: hide RGB background and provide black screen around movie. + Useful in '-vo fbdev:vidix -fs -zoom' mode. + Reverse effect to colorkey */ +#ifdef RAGE128 +static void radeon_vid_exclusive( void ) +{ +/* this function works only with Rage128. + Radeon should has something the same */ + unsigned screenw,screenh; + screenw = radeon_get_xres(); + screenh = radeon_get_yres(); + radeon_fifo_wait(2); + OUTREG(OV0_EXCLUSIVE_VERT,(((screenh-1)<<16)&EXCL_VERT_END_MASK)); + OUTREG(OV0_EXCLUSIVE_HORZ,(((screenw/8+1)<<8)&EXCL_HORZ_END_MASK)|EXCL_HORZ_EXCLUSIVE_EN); +} + +static void radeon_vid_non_exclusive( void ) +{ + OUTREG(OV0_EXCLUSIVE_HORZ,0); } +#endif static unsigned radeon_query_pitch(unsigned fourcc,const vidix_yuv_t *spitch) { @@ -1519,10 +1694,9 @@ static unsigned radeon_query_pitch(unsigned fourcc,const vidix_yuv_t *spitch) if(spy > 16 && spu == spy/2 && spv == spy/2) pitch = spy; else pitch = 32; break; - /* 4:1:0 */ case IMGFMT_IF09: case IMGFMT_YVU9: - if(spy > 32 && spu == spy/4 && spv == spy/4) pitch = spy; + if(spy >= 64 && spu == spy/4 && spv == spy/4) pitch = spy; else pitch = 64; break; default: @@ -1533,41 +1707,971 @@ static unsigned radeon_query_pitch(unsigned fourcc,const vidix_yuv_t *spitch) return pitch; } +static void Calc_H_INC_STEP_BY ( + int fieldvalue_OV0_SURFACE_FORMAT, + double H_scale_ratio, + int DisallowFourTapVertFiltering, + int DisallowFourTapUVVertFiltering, + uint32_t *val_OV0_P1_H_INC, + uint32_t *val_OV0_P1_H_STEP_BY, + uint32_t *val_OV0_P23_H_INC, + uint32_t *val_OV0_P23_H_STEP_BY, + int *P1GroupSize, + int *P1StepSize, + int *P23StepSize ) +{ + + double ClocksNeededFor16Pixels; + + switch (fieldvalue_OV0_SURFACE_FORMAT) + { + case 3: + case 4: /*16BPP (ARGB1555 and RGB565) */ + /* All colour components are fetched in pairs */ + *P1GroupSize = 2; + /* We don't support four tap in this mode because G's are split between two bytes. In theory we could support it if */ + /* we saved part of the G when fetching the R, and then filter the G, followed by the B in the following cycles. */ + if (H_scale_ratio>=.5) + { + /* We are actually generating two pixels (but 3 colour components) per tick. Thus we don't have to skip */ + /* until we reach .5. P1 and P23 are the same. */ + *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); + *val_OV0_P1_H_STEP_BY = 1; + *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 1; + *P1StepSize = 1; + *P23StepSize = 1; + } + else if (H_scale_ratio>=.25) + { + /* Step by two */ + *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5); + *val_OV0_P1_H_STEP_BY = 2; + *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 2; + *P1StepSize = 2; + *P23StepSize = 2; + } + else if (H_scale_ratio>=.125) + { + /* Step by four */ + *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); + *val_OV0_P1_H_STEP_BY = 3; + *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 3; + *P1StepSize = 4; + *P23StepSize = 4; + } + else if (H_scale_ratio>=.0625) + { + /* Step by eight */ + *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5); + *val_OV0_P1_H_STEP_BY = 4; + *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 4; + *P1StepSize = 8; + *P23StepSize = 8; + } + else if (H_scale_ratio>=0.03125) + { + /* Step by sixteen */ + *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5); + *val_OV0_P1_H_STEP_BY = 5; + *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 5; + *P1StepSize = 16; + *P23StepSize = 16; + } + else + { + H_scale_ratio=0.03125; + *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5); + *val_OV0_P1_H_STEP_BY = 5; + *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 5; + *P1StepSize = 16; + *P23StepSize = 16; + } + break; + case 6: /*32BPP RGB */ + if (H_scale_ratio>=1.5 && !DisallowFourTapVertFiltering) + { + /* All colour components are fetched in pairs */ + *P1GroupSize = 2; + /* With four tap filtering, we can generate two colour components every clock, or two pixels every three */ + /* clocks. This means that we will have four tap filtering when scaling 1.5 or more. */ + *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); + *val_OV0_P1_H_STEP_BY = 0; + *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 0; + *P1StepSize = 1; + *P23StepSize = 1; + } + else if (H_scale_ratio>=0.75) + { + /* Four G colour components are fetched at once */ + *P1GroupSize = 4; + /* R and B colour components are fetched in pairs */ + /* With two tap filtering, we can generate four colour components every clock. */ + /* This means that we will have two tap filtering when scaling 1.0 or more. */ + *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); + *val_OV0_P1_H_STEP_BY = 1; + *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 1; + *P1StepSize = 1; + *P23StepSize = 1; + } + else if (H_scale_ratio>=0.375) + { + /* Step by two. */ + /* Four G colour components are fetched at once */ + *P1GroupSize = 4; + /* R and B colour components are fetched in pairs */ + *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5); + *val_OV0_P1_H_STEP_BY = 2; + *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 2; + *P1StepSize = 2; + *P23StepSize = 2; + } + else if (H_scale_ratio>=0.25) + { + /* Step by two. */ + /* Four G colour components are fetched at once */ + *P1GroupSize = 4; + /* R and B colour components are fetched in pairs */ + *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5); + *val_OV0_P1_H_STEP_BY = 2; + *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 3; + *P1StepSize = 2; + *P23StepSize = 4; + } + else if (H_scale_ratio>=0.1875) + { + /* Step by four */ + /* Four G colour components are fetched at once */ + *P1GroupSize = 4; + /* R and B colour components are fetched in pairs */ + *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); + *val_OV0_P1_H_STEP_BY = 3; + *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 3; + *P1StepSize = 4; + *P23StepSize = 4; + } + else if (H_scale_ratio>=0.125) + { + /* Step by four */ + /* Four G colour components are fetched at once */ + *P1GroupSize = 4; + /* R and B colour components are fetched in pairs */ + *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); + *val_OV0_P1_H_STEP_BY = 3; + *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 4; + *P1StepSize = 4; + *P23StepSize = 8; + } + else if (H_scale_ratio>=0.09375) + { + /* Step by eight */ + /* Four G colour components are fetched at once */ + *P1GroupSize = 4; + /* R and B colour components are fetched in pairs */ + *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5); + *val_OV0_P1_H_STEP_BY = 4; + *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 4; + *P1StepSize = 8; + *P23StepSize = 8; + } + else if (H_scale_ratio>=0.0625) + { + /* Step by eight */ + /* Four G colour components are fetched at once */ + *P1GroupSize = 4; + /* R and B colour components are fetched in pairs */ + *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5); + *val_OV0_P1_H_STEP_BY = 5; + *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 5; + *P1StepSize = 16; + *P23StepSize = 16; + } + else + { + H_scale_ratio=0.0625; + *P1GroupSize = 4; + *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5); + *val_OV0_P1_H_STEP_BY = 5; + *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 5; + *P1StepSize = 16; + *P23StepSize = 16; + } + break; + case 9: + /*ToDo_Active: In mode 9 there is a possibility that HScale ratio may be set to an illegal value, so we have extra conditions in the if statement. For consistancy, these conditions be added to the other modes as well. */ + /* four tap on both (unless Y is too wide) */ + if ((H_scale_ratio>=(ClocksNeededFor16Pixels=8+2+2) / 16.0) && + ((uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5)<=0x3000) && + ((uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5)<=0x2000) && + !DisallowFourTapVertFiltering && !DisallowFourTapUVVertFiltering) + { /*0.75 */ + /* Colour components are fetched in pairs */ + *P1GroupSize = 2; + *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); + *val_OV0_P1_H_STEP_BY = 0; + *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 0; + *P1StepSize = 1; + *P23StepSize = 1; + } + /* two tap on Y (because it is too big for four tap), four tap on UV */ + else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=4+2+2) / 16.0) && + ((uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5)<=0x3000) && + ((uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5)<=0x2000) && + DisallowFourTapVertFiltering && !DisallowFourTapUVVertFiltering) + { /*0.75 */ + *P1GroupSize = 4; + *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); + *val_OV0_P1_H_STEP_BY = 1; + *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 0; + *P1StepSize = 1; + *P23StepSize = 1; + } + /* We scale the Y with the four tap filters, but UV's are generated + with dual two tap configuration. */ + else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=8+1+1) / 16.0) && + ((uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5)<=0x3000) && + ((uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5)<=0x2000) && + !DisallowFourTapVertFiltering) + { /*0.625 */ + *P1GroupSize = 2; + *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); + *val_OV0_P1_H_STEP_BY = 0; + *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 1; + *P1StepSize = 1; + *P23StepSize = 1; + } + /* We scale the Y, U, and V with the two tap filters */ + else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=4+1+1) / 16.0) && + ((uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5)<=0x3000) && + ((uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5)<=0x2000)) + { /*0.375 */ + *P1GroupSize = 4; + *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); + *val_OV0_P1_H_STEP_BY = 1; + *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 1; + *P1StepSize = 1; + *P23StepSize = 1; + } + /* We scale step the U and V by two to allow more bandwidth for fetching Y's, + thus we won't drop Y's yet. */ + else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=4+.5+.5) / 16.0) && + ((uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5)<=0x3000) && + ((uint16_t)((1/(H_scale_ratio*4*2)) * (