diff options
Diffstat (limited to 'drivers/radeon_vid.c')
-rw-r--r-- | drivers/radeon_vid.c | 1549 |
1 files changed, 0 insertions, 1549 deletions
diff --git a/drivers/radeon_vid.c b/drivers/radeon_vid.c deleted file mode 100644 index 9367d4b36a..0000000000 --- a/drivers/radeon_vid.c +++ /dev/null @@ -1,1549 +0,0 @@ -/* - * BES YUV video overlay driver for Radeon/Rage128Pro/Rage128 cards - * - * Copyright (C) 2001 Nick Kurshev - * - * This file is partly based on mga_vid and sis_vid from MPlayer. - * Code from CVS of GATOS project and X11 trees was also used. - * - * SPECIAL THANKS TO: Hans-Peter Raschke for active testing and hacking - * Rage128(pro) stuff of this driver. - * - * This file is part of MPlayer. - * - * MPlayer is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * MPlayer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#define RADEON_VID_VERSION "1.2.1" - -/* - It's entirely possible this major conflicts with something else - mknod /dev/radeon_vid c 178 0 - or - mknod /dev/rage128_vid c 178 0 - for Rage128/Rage128Pro chips (although it doesn't matter) - +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - TESTED and WORKING formats: YUY2, UYVY, IYUV, I420, YV12 - ----------------------------------------------------------- - TODO: - Highest priority: fbvid.h compatibility - High priority: Fixing BUGS - Middle priority: RGB/BGR 2-32, YVU9, IF09 support - Low priority: CLPL, IYU1, IYU2, UYNV, CYUV, YUNV, YVYU, Y41P, Y211, Y41T, - ^^^^ - Y42T, V422, V655, CLJR, YUVP, UYVP, Mpeg PES (mpeg-1,2) support - ........................................................... - BUGS and LACKS: - Color and video keys don't work -*/ - -#include <linux/config.h> -#include <linux/version.h> -#include <linux/module.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/string.h> -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/pci.h> -#include <linux/ioport.h> -#include <linux/init.h> -#include <linux/byteorder/swab.h> - -#include "radeon_vid.h" -#include "radeon.h" - -#ifdef CONFIG_MTRR -#include <asm/mtrr.h> -#endif - -#include <asm/uaccess.h> -#include <asm/system.h> -#include <asm/io.h> - -#define TRUE 1 -#define FALSE 0 - -#define RADEON_VID_MAJOR 178 - - -MODULE_AUTHOR("Nick Kurshev <nickols_k@mail.ru>"); -#ifdef RAGE128 -MODULE_DESCRIPTION("Accelerated YUV BES driver for Rage128. Version: "RADEON_VID_VERSION); -#else -MODULE_DESCRIPTION("Accelerated YUV BES driver for Radeons. Version: "RADEON_VID_VERSION); -#endif -#ifdef MODULE_LICENSE -MODULE_LICENSE("GPL"); -#endif -#ifdef CONFIG_MTRR -MODULE_PARM(mtrr, "i"); -MODULE_PARM_DESC(mtrr, "Tune MTRR (touch=1(default))"); -static int mtrr __initdata = 1; -static struct { int vram; int vram_valid; } smtrr; -#endif -MODULE_PARM(swap_fourcc, "i"); -MODULE_PARM_DESC(swap_fourcc, "Swap fourcc (don't swap=0(default))"); -static int swap_fourcc __initdata = 0; - -#ifdef RAGE128 -#define RVID_MSG "rage128_vid: " -#define X_ADJUST 0 -#else -#define RVID_MSG "radeon_vid: " -#define X_ADJUST 8 -#ifndef RADEON -#define RADEON -#endif -#endif - -#undef DEBUG -#if DEBUG -#define RTRACE printk -#else -#define RTRACE(...) ((void)0) -#endif - -#ifndef min -#define min(a,b) (a < b ? a : b) -#endif - -#ifndef RAGE128 -#if defined(__i386__) -/* Ugly but only way */ -#undef AVOID_FPU -static inline double FastSin(double x) -{ - register double res; - __asm__ volatile("fsin":"=t"(res):"0"(x)); - return res; -} -#undef sin -#define sin(x) FastSin(x) - -static inline double FastCos(double x) -{ - register double res; - __asm__ volatile("fcos":"=t"(res):"0"(x)); - return res; -} -#undef cos -#define cos(x) FastCos(x) -#else -#include "generic_math.h" -#endif /*__386__*/ -#endif /*RAGE128*/ - -#if !defined( RAGE128 ) && !defined( AVOID_FPU ) -#define RADEON_FPU 1 -#endif - -typedef struct bes_registers_s -{ - /* base address of yuv framebuffer */ - uint32_t yuv_base; - uint32_t fourcc; - 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_buf0_base_adrs; - /* These ones are for auto flip: maybe in the future */ - uint32_t vid_buf1_base_adrs; - uint32_t vid_buf2_base_adrs; - uint32_t vid_buf3_base_adrs; - uint32_t vid_buf4_base_adrs; - uint32_t vid_buf5_base_adrs; - - 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 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; - - int deinterlace_on; - uint32_t deinterlace_pattern; - -} bes_registers_t; - -typedef struct video_registers_s -{ -#ifdef DEBUG - const char * sname; -#endif - uint32_t name; - uint32_t value; -}video_registers_t; - -static bes_registers_t besr; -#ifndef RAGE128 -static int IsR200=0; -#endif -#ifdef DEBUG -#define DECLARE_VREG(name) { #name, name, 0 } -#else -#define DECLARE_VREG(name) { name, 0 } -#endif -#ifdef DEBUG -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) -}; -#endif -static uint32_t radeon_vid_in_use = 0; - -static uint8_t *radeon_mmio_base = 0; -static uint32_t radeon_mem_base = 0; -static int32_t radeon_overlay_off = 0; -static uint32_t radeon_ram_size = 0; -#define PARAM_BUFF_SIZE 4096 -static uint8_t *radeon_param_buff = NULL; -static uint32_t radeon_param_buff_size=0; -static uint32_t radeon_param_buff_len=0; /* real length of buffer */ -static mga_vid_config_t radeon_config; - -static char *fourcc_format_name(int format) -{ - switch(format) - { - case IMGFMT_RGB8: return "RGB 8-bit"; - case IMGFMT_RGB15: return "RGB 15-bit"; - case IMGFMT_RGB16: return "RGB 16-bit"; - case IMGFMT_RGB24: return "RGB 24-bit"; - case IMGFMT_RGB32: return "RGB 32-bit"; - case IMGFMT_BGR8: return "BGR 8-bit"; - case IMGFMT_BGR15: return "BGR 15-bit"; - case IMGFMT_BGR16: return "BGR 16-bit"; - case IMGFMT_BGR24: return "BGR 24-bit"; - case IMGFMT_BGR32: return "BGR 32-bit"; - case IMGFMT_YVU9: return "Planar YVU9"; - case IMGFMT_IF09: return "Planar IF09"; - case IMGFMT_YV12: return "Planar YV12"; - case IMGFMT_I420: return "Planar I420"; - case IMGFMT_IYUV: return "Planar IYUV"; - case IMGFMT_CLPL: return "Planar CLPL"; - case IMGFMT_Y800: return "Planar Y800"; - case IMGFMT_Y8: return "Planar Y8"; - case IMGFMT_IUYV: return "Packed IUYV"; - case IMGFMT_IY41: return "Packed IY41"; - case IMGFMT_IYU1: return "Packed IYU1"; - case IMGFMT_IYU2: return "Packed IYU2"; - case IMGFMT_UYNV: return "Packed UYNV"; - case IMGFMT_cyuv: return "Packed CYUV"; - case IMGFMT_Y422: return "Packed Y422"; - case IMGFMT_YUY2: return "Packed YUY2"; - case IMGFMT_YUNV: return "Packed YUNV"; - case IMGFMT_UYVY: return "Packed UYVY"; -// case IMGFMT_YVYU: return "Packed YVYU"; - case IMGFMT_Y41P: return "Packed Y41P"; - case IMGFMT_Y211: return "Packed Y211"; - case IMGFMT_Y41T: return "Packed Y41T"; - case IMGFMT_Y42T: return "Packed Y42T"; - case IMGFMT_V422: return "Packed V422"; - case IMGFMT_V655: return "Packed V655"; - case IMGFMT_CLJR: return "Packed CLJR"; - case IMGFMT_YUVP: return "Packed YUVP"; - case IMGFMT_UYVP: return "Packed UYVP"; - case IMGFMT_MPEGPES: return "Mpeg PES"; - } - return "Unknown"; -} - - -/* - * IO macros - */ - -#define INREG8(addr) readb((radeon_mmio_base)+addr) -#define OUTREG8(addr,val) writeb(val, (radeon_mmio_base)+addr) -#define INREG(addr) readl((radeon_mmio_base)+addr) -#define OUTREG(addr,val) writel(val, (radeon_mmio_base)+addr) -#define OUTREGP(addr,val,mask) \ - do { \ - unsigned int tmp = INREG(addr); \ - tmp &= (mask); \ - tmp |= (val); \ - OUTREG(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 __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 __inline__ void radeon_fifo_wait (int entries) -{ - int i; - - for (i=0; i<2000000; i++) - if ((INREG(RBBM_STATUS) & 0x7f) >= entries) - return; -} - - -static __inline__ void radeon_engine_idle ( void ) -{ - int i; - - /* ensure FIFO is empty before waiting for idle */ - radeon_fifo_wait (64); - - for (i=0; i<2000000; i++) { - if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) { - radeon_engine_flush (); - return; - } - } -} - -#if 0 -static void __init radeon_vid_save_state( void ) -{ - size_t i; - for(i=0;i<sizeof(vregs)/sizeof(video_registers_t);i++) - vregs[i].value = INREG(vregs[i].name); -} - -static void __exit radeon_vid_restore_state( void ) -{ - size_t i; - radeon_fifo_wait(2); - OUTREG(OV0_REG_LOAD_CNTL, REG_LD_CTL_LOCK); - radeon_engine_idle(); - while(!(INREG(OV0_REG_LOAD_CNTL)®_LD_CTL_LOCK_READBACK)); - radeon_fifo_wait(15); - for(i=0;i<sizeof(vregs)/sizeof(video_registers_t);i++) - { - radeon_fifo_wait(1); - OUTREG(vregs[i].name,vregs[i].value); - } - OUTREG(OV0_REG_LOAD_CNTL, 0); -} -#endif -#ifdef DEBUG -static void radeon_vid_dump_regs( void ) -{ - size_t i; - printk(RVID_MSG"*** Begin of OV0 registers dump ***\n"); - for(i=0;i<sizeof(vregs)/sizeof(video_registers_t);i++) - printk(RVID_MSG"%s = %08X\n",vregs[i].sname,INREG(vregs[i].name)); - printk(RVID_MSG"*** End of OV0 registers dump ***\n"); -} -#endif - -#ifdef RADEON_FPU -/* Reference color space transform data */ -typedef struct tagREF_TRANSFORM -{ - float RefLuma; - float RefRCb; - float RefRCr; - float RefGCb; - float RefGCr; - float RefBCb; - float RefBCr; -} REF_TRANSFORM; - -/* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces */ -REF_TRANSFORM trans[2] = -{ - {1.1678, 0.0, 1.6007, -0.3929, -0.8154, 2.0232, 0.0}, /* BT.601 */ - {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 * - * ref - index to the table of refernce transforms * - * Outputs: NONE * - ****************************************************************************/ - -static void radeon_set_transform(float bright, float cont, float sat, - float hue, unsigned ref) -{ - float OvHueSin, OvHueCos; - float CAdjLuma, CAdjOff; - float CAdjRCb, CAdjRCr; - float CAdjGCb, CAdjGCr; - float CAdjBCb, CAdjBCr; - float OvLuma, OvROff, OvGOff, OvBOff; - float OvRCb, OvRCr; - float OvGCb, OvGCr; - float OvBCb, OvBCr; - float Loff = 64.0; - float Coff = 512.0f; - - u32 dwOvLuma, dwOvROff, dwOvGOff, dwOvBOff; - u32 dwOvRCb, dwOvRCr; - u32 dwOvGCb, dwOvGCr; - u32 dwOvBCb, dwOvBCr; - - if (ref >= 2) return; - - OvHueSin = sin((double)hue); - OvHueCos = cos((double)hue); - - CAdjLuma = cont * trans[ref].RefLuma; - CAdjOff = cont * trans[ref].RefLuma * bright * 1023.0; - - CAdjRCb = sat * -OvHueSin * trans[ref].RefRCr; - CAdjRCr = sat * OvHueCos * trans[ref].RefRCr; - CAdjGCb = sat * (OvHueCos * trans[ref].RefGCb - OvHueSin * trans[ref].RefGCr); - CAdjGCr = sat * (OvHueSin * trans[ref].RefGCb + OvHueCos * trans[ref].RefGCr); - CAdjBCb = sat * OvHueCos * trans[ref].RefBCb; - CAdjBCr = sat * OvHueSin * trans[ref].RefBCb; - -#if 0 /* default constants */ - CAdjLuma = 1.16455078125; - - CAdjRCb = 0.0; - CAdjRCr = 1.59619140625; - CAdjGCb = -0.39111328125; - CAdjGCr = -0.8125; - CAdjBCb = 2.01708984375; - CAdjBCr = 0; -#endif - OvLuma = CAdjLuma; - OvRCb = CAdjRCb; - OvRCr = CAdjRCr; - OvGCb = CAdjGCb; - OvGCr = CAdjGCr; - OvBCb = CAdjBCb; - OvBCr = CAdjBCr; - OvROff = CAdjOff - - OvLuma * Loff - (OvRCb + OvRCr) * Coff; - OvGOff = CAdjOff - - OvLuma * Loff - (OvGCb + OvGCr) * Coff; - OvBOff = CAdjOff - - OvLuma * Loff - (OvBCb + OvBCr) * Coff; -#if 0 /* default constants */ - OvROff = -888.5; - OvGOff = 545; - OvBOff = -1104; -#endif - - dwOvROff = ((int)(OvROff * 2.0)) & 0x1fff; - dwOvGOff = (int)(OvGOff * 2.0) & 0x1fff; - dwOvBOff = (int)(OvBOff * 2.0) & 0x1fff; - if(!IsR200) - { - dwOvLuma =(((int)(OvLuma * 2048.0))&0x7fff)<<17; - dwOvRCb = (((int)(OvRCb * 2048.0))&0x7fff)<<1; - dwOvRCr = (((int)(OvRCr * 2048.0))&0x7fff)<<17; - dwOvGCb = (((int)(OvGCb * 2048.0))&0x7fff)<<1; - dwOvGCr = (((int)(OvGCr * 2048.0))&0x7fff)<<17; - dwOvBCb = (((int)(OvBCb * 2048.0))&0x7fff)<<1; - dwOvBCr = (((int)(OvBCr * 2048.0))&0x7fff)<<17; - } - else - { - dwOvLuma = (((int)(OvLuma * 256.0))&0x7ff)<<20; - dwOvRCb = (((int)(OvRCb * 256.0))&0x7ff)<<4; - dwOvRCr = (((int)(OvRCr * 256.0))&0x7ff)<<20; - dwOvGCb = (((int)(OvGCb * 256.0))&0x7ff)<<4; - dwOvGCr = (((int)(OvGCr * 256.0))&0x7ff)<<20; - dwOvBCb = (((int)(OvBCb * 256.0))&0x7ff)<<4; - dwOvBCr = (((int)(OvBCr * 256.0))&0x7ff)<<20; - } - - OUTREG(OV0_LIN_TRANS_A, dwOvRCb | dwOvLuma); - OUTREG(OV0_LIN_TRANS_B, dwOvROff | dwOvRCr); - OUTREG(OV0_LIN_TRANS_C, dwOvGCb | dwOvLuma); - OUTREG(OV0_LIN_TRANS_D, dwOvGOff | dwOvGCr); - OUTREG(OV0_LIN_TRANS_E, dwOvBCb | dwOvLuma); - OUTREG(OV0_LIN_TRANS_F, dwOvBOff | dwOvBCr); -} -#endif - -#ifndef RAGE128 -/* Gamma curve definition */ -typedef struct -{ - unsigned int gammaReg; - unsigned int gammaSlope; - unsigned int gammaOffset; -}GAMMA_SETTINGS; - -/* Recommended gamma curve parameters */ -GAMMA_SETTINGS r200_def_gamma[18] = -{ - {OV0_GAMMA_0_F, 0x100, 0x0000}, - {OV0_GAMMA_10_1F, 0x100, 0x0020}, - {OV0_GAMMA_20_3F, 0x100, 0x0040}, - {OV0_GAMMA_40_7F, 0x100, 0x0080}, - {OV0_GAMMA_80_BF, 0x100, 0x0100}, - {OV0_GAMMA_C0_FF, 0x100, 0x0100}, - {OV0_GAMMA_100_13F, 0x100, 0x0200}, - {OV0_GAMMA_140_17F, 0x100, 0x0200}, - {OV0_GAMMA_180_1BF, 0x100, 0x0300}, - {OV0_GAMMA_1C0_1FF, 0x100, 0x0300}, - {OV0_GAMMA_200_23F, 0x100, 0x0400}, - {OV0_GAMMA_240_27F, 0x100, 0x0400}, - {OV0_GAMMA_280_2BF, 0x100, 0x0500}, - {OV0_GAMMA_2C0_2FF, 0x100, 0x0500}, - {OV0_GAMMA_300_33F, 0x100, 0x0600}, - {OV0_GAMMA_340_37F, 0x100, 0x0600}, - {OV0_GAMMA_380_3BF, 0x100, 0x0700}, - {OV0_GAMMA_3C0_3FF, 0x100, 0x0700} -}; - -GAMMA_SETTINGS r100_def_gamma[6] = -{ - {OV0_GAMMA_0_F, 0x100, 0x0000}, - {OV0_GAMMA_10_1F, 0x100, 0x0020}, - {OV0_GAMMA_20_3F, 0x100, 0x0040}, - {OV0_GAMMA_40_7F, 0x100, 0x0080}, - {OV0_GAMMA_380_3BF, 0x100, 0x0100}, - {OV0_GAMMA_3C0_3FF, 0x100, 0x0100} -}; - -static void make_default_gamma_correction( void ) -{ - size_t i; - if(!IsR200){ - OUTREG(OV0_LIN_TRANS_A, 0x12A00000); - OUTREG(OV0_LIN_TRANS_B, 0x199018FE); - OUTREG(OV0_LIN_TRANS_C, 0x12A0F9B0); - OUTREG(OV0_LIN_TRANS_D, 0xF2F0043B); - OUTREG(OV0_LIN_TRANS_E, 0x12A02050); - OUTREG(OV0_LIN_TRANS_F, 0x0000174E); - for(i=0; i<6; i++){ - OUTREG(r100_def_gamma[i].gammaReg, - (r100_def_gamma[i].gammaSlope<<16) | - 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_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); - } - } -} -#endif - -static void radeon_vid_stop_video( void ) -{ - radeon_engine_idle(); - OUTREG(OV0_SCALE_CNTL, SCALER_SOFT_RESET); - OUTREG(OV0_EXCLUSIVE_HORZ, 0); - OUTREG(OV0_AUTO_FLIP_CNTL, 0); /* maybe */ - OUTREG(OV0_FILTER_CNTL, FILTER_HARDCODED_COEF); - OUTREG(OV0_KEY_CNTL, GRAPHIC_KEY_FN_NE); - OUTREG(OV0_TEST, 0); -} - -static void radeon_vid_display_video( void ) -{ - int bes_flags; - radeon_fifo_wait(2); - OUTREG(OV0_REG_LOAD_CNTL, REG_LD_CTL_LOCK); - radeon_engine_idle(); - while(!(INREG(OV0_REG_LOAD_CNTL)®_LD_CTL_LOCK_READBACK)); - radeon_fifo_wait(15); - OUTREG(OV0_AUTO_FLIP_CNTL,OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD); - OUTREG(OV0_AUTO_FLIP_CNTL,(INREG(OV0_AUTO_FLIP_CNTL)^OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE)); - OUTREG(OV0_AUTO_FLIP_CNTL,(INREG(OV0_AUTO_FLIP_CNTL)^OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE)); - - OUTREG(OV0_DEINTERLACE_PATTERN,besr.deinterlace_pattern); -#ifdef RAGE128 - OUTREG(OV0_COLOUR_CNTL, (besr.brightness & 0x7f) | - (besr.saturation << 8) | - (besr.saturation << 16)); -#endif - radeon_fifo_wait(2); - if(besr.ckey_on) - { - OUTREG(OV0_GRAPHICS_KEY_MSK, besr.graphics_key_msk); - OUTREG(OV0_GRAPHICS_KEY_CLR, besr.graphics_key_clr); - OUTREG(OV0_KEY_CNTL,GRAPHIC_KEY_FN_EQ|VIDEO_KEY_FN_FALSE|CMP_MIX_OR); - } - else - { - OUTREG(OV0_GRAPHICS_KEY_MSK, 0ULL); - OUTREG(OV0_GRAPHICS_KEY_CLR, 0ULL); - OUTREG(OV0_KEY_CNTL,GRAPHIC_KEY_FN_NE); - } - - OUTREG(OV0_H_INC, besr.h_inc); - OUTREG(OV0_STEP_BY, besr.step_by); - OUTREG(OV0_Y_X_START, besr.y_x_start); - OUTREG(OV0_Y_X_END, besr.y_x_end); - OUTREG(OV0_V_INC, besr.v_inc); - OUTREG(OV0_P1_BLANK_LINES_AT_TOP, besr.p1_blank_lines_at_top); - OUTREG(OV0_P23_BLANK_LINES_AT_TOP, besr.p23_blank_lines_at_top); - OUTREG(OV0_VID_BUF_PITCH0_VALUE, besr.vid_buf_pitch0_value); - OUTREG(OV0_VID_BUF_PITCH1_VALUE, besr.vid_buf_pitch1_value); - OUTREG(OV0_P1_X_START_END, besr.p1_x_start_end); - OUTREG(OV0_P2_X_START_END, besr.p2_x_start_end); - OUTREG(OV0_P3_X_START_END, besr.p3_x_start_end); -#ifdef RADEON - OUTREG(OV0_BASE_ADDR, besr.base_addr); -#endif - OUTREG(OV0_VID_BUF0_BASE_ADRS, besr.vid_buf0_base_adrs); - OUTREG(OV0_VID_BUF1_BASE_ADRS, besr.vid_buf1_base_adrs); - OUTREG(OV0_VID_BUF2_BASE_ADRS, besr.vid_buf2_base_adrs); - radeon_fifo_wait(9); - OUTREG(OV0_VID_BUF3_BASE_ADRS, besr.vid_buf3_base_adrs); - OUTREG(OV0_VID_BUF4_BASE_ADRS, besr.vid_buf4_base_adrs); - OUTREG(OV0_VID_BUF5_BASE_ADRS, besr.vid_buf5_base_adrs); - OUTREG(OV0_P1_V_ACCUM_INIT, besr.p1_v_accum_init); - OUTREG(OV0_P1_H_ACCUM_INIT, besr.p1_h_accum_init); - OUTREG(OV0_P23_H_ACCUM_INIT, besr.p23_h_accum_init); - OUTREG(OV0_P23_V_ACCUM_INIT, besr.p23_v_accum_init); - -#ifdef RADEON - bes_flags = SCALER_ENABLE | - SCALER_SMART_SWITCH; -// SCALER_HORZ_PICK_NEAREST; -#else - bes_flags = SCALER_ENABLE | - SCALER_SMART_SWITCH | - SCALER_Y2R_TEMP | - SCALER_PIX_EXPAND; -#endif - if(besr.double_buff) bes_flags |= SCALER_DOUBLE_BUFFER; - if(besr.deinterlace_on) bes_flags |= SCALER_ADAPTIVE_DEINT; -#ifdef RAGE128 - bes_flags |= SCALER_BURST_PER_PLANE; -#endif - switch(besr.fourcc) - { - case IMGFMT_RGB15: - case IMGFMT_BGR15: bes_flags |= SCALER_SOURCE_15BPP; break; - case IMGFMT_RGB16: - case IMGFMT_BGR16: bes_flags |= SCALER_SOURCE_16BPP; break; - case IMGFMT_RGB24: - case IMGFMT_BGR24: bes_flags |= SCALER_SOURCE_24BPP; break; - case IMGFMT_RGB32: - case IMGFMT_BGR32: bes_flags |= SCALER_SOURCE_32BPP; break; - /* 4:1:0*/ - case IMGFMT_IF09: - case IMGFMT_YVU9: bes_flags |= SCALER_SOURCE_YUV9; break; - /* 4:2:0 */ - case IMGFMT_IYUV: - case IMGFMT_I420: - case IMGFMT_YV12: bes_flags |= SCALER_SOURCE_YUV12; - break; - /* 4:2:2 */ - case IMGFMT_UYVY: bes_flags |= SCALER_SOURCE_YVYU422; break; - case IMGFMT_YUY2: - default: bes_flags |= SCALER_SOURCE_VYUY422; break; - } - OUTREG(OV0_SCALE_CNTL, bes_flags); - OUTREG(OV0_REG_LOAD_CNTL, 0); -#ifdef DEBUG - radeon_vid_dump_regs(); -#endif -} - -void radeon_vid_set_color_key(int ckey_on, uint8_t R, uint8_t G, uint8_t B) -{ - besr.ckey_on = ckey_on; - besr.graphics_key_msk=(1ULL<<radeon_vid_get_dbpp()) - 1; - besr.graphics_key_clr=(R<<16)|(G<<8)|(B)|(0x00 << 24); -} - - -#define XXX_SRC_X 0 -#define XXX_SRC_Y 0 - -static int radeon_vid_init_video( mga_vid_config_t *config ) -{ - uint32_t tmp,src_w,src_h,pitch,h_inc,step_by,left,leftUV,top; - int is_420; -RTRACE(RVID_MSG"usr_config: version = %x format=%x card=%x ram=%u src(%ux%u) dest(%u:%ux%u:%u) frame_size=%u num_frames=%u\n" - ,(uint32_t)config->version - ,(uint32_t)config->format - ,(uint32_t)config->card_type - ,(uint32_t)config->ram_size - ,(uint32_t)config->src_width - ,(uint32_t)config->src_height - ,(uint32_t)config->x_org - ,(uint32_t)config->y_org - ,(uint32_t)config->dest_width - ,(uint32_t)config->dest_height - ,(uint32_t)config->frame_size - ,(uint32_t)config->num_frames); - radeon_vid_stop_video(); - left = XXX_SRC_X << 16; - top = XXX_SRC_Y << 16; - src_h = config->src_height; - src_w = config->src_width; - switch(config->format) - { - case IMGFMT_RGB15: - case IMGFMT_BGR15: - case IMGFMT_RGB16: - case IMGFMT_BGR16: - case IMGFMT_RGB24: - case IMGFMT_BGR24: - case IMGFMT_RGB32: - case IMGFMT_BGR32: - /* 4:1:0 */ - case IMGFMT_IF09: - case IMGFMT_YVU9: - /* 4:2:0 */ - case IMGFMT_IYUV: - case IMGFMT_YV12: - case IMGFMT_I420: - /* 4:2:2 */ - case IMGFMT_UYVY: - case IMGFMT_YUY2: - break; - default: - printk(RVID_MSG"Unsupported pixel format: 0x%X\n",config->format); - return -1; - } - is_420 = 0; - if(config->format == IMGFMT_YV12 || - config->format == IMGFMT_I420 || - config->format == IMGFMT_IYUV) is_420 = 1; - switch(config->format) - { - /* 4:1:0 */ - case IMGFMT_YVU9: - case IMGFMT_IF09: - /* 4:2:0 */ - case IMGFMT_IYUV: - case IMGFMT_YV12: - case IMGFMT_I420: pitch = (src_w + 31) & ~31; break; - /* 4:2:2 */ - default: - case IMGFMT_UYVY: - case IMGFMT_YUY2: - case IMGFMT_RGB15: - case IMGFMT_BGR15: - case IMGFMT_RGB16: - case IMGFMT_BGR16: pitch = ((src_w*2) + 15) & ~15; break; - case IMGFMT_RGB24: - case IMGFMT_BGR24: pitch = ((src_w*3) + 15) & ~15; break; - case IMGFMT_RGB32: - case IMGFMT_BGR32: pitch = ((src_w*4) + 15) & ~15; break; - } - if(radeon_is_dbl_scan()) config->dest_height *= 2; - else - if(radeon_is_interlace()) config->dest_height /= 2; - besr.dest_bpp = radeon_vid_get_dbpp(); - besr.fourcc = config->format; - besr.v_inc = (src_h << 20) / config->dest_height; - h_inc = (src_w << 12) / config->dest_width; - step_by = 1; - - while(h_inc >= (2 << 12)) { - step_by++; - h_inc >>= 1; - } - - /* keep everything in 16.16 */ - besr.base_addr = radeon_mem_base; - if(is_420) - { - uint32_t d1line,d2line,d3line; - d1line = top*pitch; - d2line = src_h*pitch+(d1line>>1); - d3line = d2line+((src_h*pitch)>>2); - d1line += (left >> 16) & ~15; - d2line += (left >> 17) & ~15; - d3line += (left >> 17) & ~15; - besr.vid_buf0_base_adrs=((radeon_overlay_off+d1line)&VIF_BUF0_BASE_ADRS_MASK); - besr.vid_buf1_base_adrs=((radeon_overlay_off+d2line)&VIF_BUF1_BASE_ADRS_MASK)|VIF_BUF1_PITCH_SEL; - besr.vid_buf2_base_adrs=((radeon_overlay_off+d3line)&VIF_BUF2_BASE_ADRS_MASK)|VIF_BUF2_PITCH_SEL; - if(besr.fourcc == IMGFMT_I420 || besr.fourcc == IMGFMT_IYUV) - { - uint32_t tmp; - tmp = besr.vid_buf1_base_adrs; - besr.vid_buf1_base_adrs = besr.vid_buf2_base_adrs; - besr.vid_buf2_base_adrs = tmp; - } - } - else - { - besr.vid_buf0_base_adrs = radeon_overlay_off; - besr.vid_buf0_base_adrs += ((left & ~7) << 1)&VIF_BUF0_BASE_ADRS_MASK; - besr.vid_buf1_base_adrs = besr.vid_buf0_base_adrs; - besr.vid_buf2_base_adrs = besr.vid_buf0_base_adrs; - } - besr.vid_buf3_base_adrs = besr.vid_buf0_base_adrs+config->frame_size; - besr.vid_buf4_base_adrs = besr.vid_buf1_base_adrs+config->frame_size; - besr.vid_buf5_base_adrs = besr.vid_buf2_base_adrs+config->frame_size; - - tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3); - besr.p1_h_accum_init = ((tmp << 4) & 0x000f8000) | - ((tmp << 12) & 0xf0000000); - - tmp = ((left >> 1) & 0x0001ffff) + 0x00028000 + (h_inc << 2); - besr.p23_h_accum_init = ((tmp << 4) & 0x000f8000) | - ((tmp << 12) & 0x70000000); - tmp = (top & 0x0000ffff) + 0x00018000; - besr.p1_v_accum_init = ((tmp << 4) & OV0_P1_V_ACCUM_INIT_MASK) - |(OV0_P1_MAX_LN_IN_PER_LN_OUT & 1); - - tmp = ((top >> 1) & 0x0000ffff) + 0x00018000; - besr.p23_v_accum_init = is_420 ? ((tmp << 4) & OV0_P23_V_ACCUM_INIT_MASK) - |(OV0_P23_MAX_LN_IN_PER_LN_OUT & 1) : 0; - - leftUV = (left >> 17) & 15; - left = (left >> 16) & 15; - besr.h_inc = h_inc | ((h_inc >> 1) << 16); - besr.step_by = step_by | (step_by << 8); - besr.y_x_start = (config->x_org+X_ADJUST) | (config->y_org << 16); - besr.y_x_end = (config->x_org + config->dest_width+X_ADJUST) | ((config->y_org + config->dest_height) << 16); - besr.p1_blank_lines_at_top = P1_BLNK_LN_AT_TOP_M1_MASK|((src_h-1)<<16); - if(is_420) - { - src_h = (src_h + 1) >> 1; - besr.p23_blank_lines_at_top = P23_BLNK_LN_AT_TOP_M1_MASK|((src_h-1)<<16); - } - else besr.p23_blank_lines_at_top = 0; - besr.vid_buf_pitch0_value = pitch; - besr.vid_buf_pitch1_value = is_420 ? pitch>>1 : pitch; - besr.p1_x_start_end = (src_w+left-1)|(left<<16); - src_w>>=1; - besr.p2_x_start_end = (src_w+left-1)|(leftUV<<16); - besr.p3_x_start_end = besr.p2_x_start_end; - return 0; -} - -static void radeon_vid_frame_sel(int frame) -{ - uint32_t off0,off1,off2; - if(!besr.double_buff) return; - if(frame%2) - { - off0 = besr.vid_buf3_base_adrs; - off1 = besr.vid_buf4_base_adrs; - off2 = besr.vid_buf5_base_adrs; - } - else - { - off0 = besr.vid_buf0_base_adrs; - off1 = besr.vid_buf1_base_adrs; - off2 = besr.vid_buf2_base_adrs; - } - OUTREG(OV0_REG_LOAD_CNTL, REG_LD_CTL_LOCK); - while(!(INREG(OV0_REG_LOAD_CNTL)®_LD_CTL_LOCK_READBACK)); - OUTREG(OV0_VID_BUF0_BASE_ADRS, off0); - OUTREG(OV0_VID_BUF1_BASE_ADRS, off1); - OUTREG(OV0_VID_BUF2_BASE_ADRS, off2); - OUTREG(OV0_REG_LOAD_CNTL, 0); -} - -static void radeon_vid_make_default(void) -{ -#ifdef RAGE128 - OUTREG(OV0_COLOUR_CNTL,0x00101000UL); /* Default brihgtness and saturation for Rage128 */ -#else - make_default_gamma_correction(); -#endif - besr.deinterlace_pattern = 0x900AAAAA; - OUTREG(OV0_DEINTERLACE_PATTERN,besr.deinterlace_pattern); - besr.deinterlace_on=1; - besr.double_buff=1; -} - - -static void radeon_vid_preset(void) -{ -#ifdef RAGE128 - unsigned tmp; - tmp = INREG(OV0_COLOUR_CNTL); - besr.saturation = (tmp>>8)&0x1f; - besr.brightness = tmp & 0x7f; -#endif - besr.graphics_key_clr = INREG(OV0_GRAPHICS_KEY_CLR); - besr.deinterlace_pattern = INREG(OV0_DEINTERLACE_PATTERN); -} - -static int video_on = 0; - -static int radeon_vid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) -{ - int frame; - - switch(cmd) - { - case MGA_VID_CONFIG: - RTRACE(RVID_MSG"radeon_mmio_base = %p\n",radeon_mmio_base); - RTRACE(RVID_MSG"radeon_mem_base = %08x\n",radeon_mem_base); - RTRACE(RVID_MSG"Received configuration\n"); - - if(copy_from_user(&radeon_config,(mga_vid_config_t*) arg,sizeof(mga_vid_config_t))) - { - printk(RVID_MSG"failed copy from userspace\n"); - return -EFAULT; - } - if(radeon_config.version != MGA_VID_VERSION){ - printk(RVID_MSG"incompatible version! driver: %X requested: %X\n",MGA_VID_VERSION,radeon_config.version); - return -EFAULT; - } - - if(radeon_config.frame_size==0 || radeon_config.frame_size>1024*768*2){ - printk(RVID_MSG"illegal frame_size: %d\n",radeon_config.frame_size); - return -EFAULT; - } - - if(radeon_config.num_frames<1){ - printk(RVID_MSG"illegal num_frames: %d\n",radeon_config.num_frames); - return -EFAULT; - } - if(radeon_config.num_frames==1) besr.double_buff=0; - if(!besr.double_buff) radeon_config.num_frames=1; - else radeon_config.num_frames=2; - radeon_config.card_type = 0; - radeon_config.ram_size = radeon_ram_size; - radeon_overlay_off = radeon_ram_size*0x100000 - radeon_config.frame_size*radeon_config.num_frames; - radeon_overlay_off &= 0xffff0000; - if(radeon_overlay_off < 0){ - printk(RVID_MSG"not enough video memory. Need: %u has: %u\n",radeon_config.frame_size*radeon_config.num_frames,radeon_ram_size*0x100000); - return -EFAULT; - } - RTRACE(RVID_MSG"using video overlay at offset %08X\n",radeon_overlay_off); - if (copy_to_user((mga_vid_config_t *) arg, &radeon_config, sizeof(mga_vid_config_t))) - { - printk(RVID_MSG"failed copy to userspace\n"); - return -EFAULT; - } - radeon_vid_set_color_key(radeon_config.colkey_on, - radeon_config.colkey |