/*
* 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
|