diff options
| author | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2003-01-13 23:36:01 +0000 |
|---|---|---|
| committer | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2003-01-13 23:36:01 +0000 |
| commit | 9baa6d2f372d3e09280e1103d7bfcf048f6457ec (patch) | |
| tree | cf3bfc3fb392fe58ed612a5a09c11d176eb17e99 /src/video_out/vidix/drivers | |
| parent | 989188f25474868841d8a5148873a5995be58c6f (diff) | |
| download | xine-lib-9baa6d2f372d3e09280e1103d7bfcf048f6457ec.tar.gz xine-lib-9baa6d2f372d3e09280e1103d7bfcf048f6457ec.tar.bz2 | |
big vidix driver update by James Stembridge
CVS patchset: 3907
CVS date: 2003/01/13 23:36:01
Diffstat (limited to 'src/video_out/vidix/drivers')
| -rw-r--r-- | src/video_out/vidix/drivers/Makefile.am | 19 | ||||
| -rw-r--r-- | src/video_out/vidix/drivers/genfb_vid.c | 31 | ||||
| -rw-r--r-- | src/video_out/vidix/drivers/mach64_vid.c | 340 | ||||
| -rw-r--r-- | src/video_out/vidix/drivers/mga_vid.c | 1808 | ||||
| -rw-r--r-- | src/video_out/vidix/drivers/nvidia_vid.c | 32 | ||||
| -rw-r--r-- | src/video_out/vidix/drivers/pm3_regs.h | 346 | ||||
| -rw-r--r-- | src/video_out/vidix/drivers/pm3_vid.c | 367 | ||||
| -rw-r--r-- | src/video_out/vidix/drivers/radeon.h | 6 | ||||
| -rw-r--r-- | src/video_out/vidix/drivers/radeon_vid.c | 1755 |
9 files changed, 3245 insertions, 1459 deletions
diff --git a/src/video_out/vidix/drivers/Makefile.am b/src/video_out/vidix/drivers/Makefile.am index a68628646..9b76a591e 100644 --- a/src/video_out/vidix/drivers/Makefile.am +++ b/src/video_out/vidix/drivers/Makefile.am @@ -5,11 +5,10 @@ libdir = $(XINE_PLUGINDIR)/vidix if HAVE_VIDIX vidix_drivers = \ - genfb_vid.la \ mach64_vid.la \ mga_crtc2_vid.la \ mga_vid.la \ - nvidia_vid.la \ + pm2_vid.la \ pm3_vid.la \ radeon_vid.la \ rage128_vid.la @@ -37,6 +36,10 @@ rage128_vid_la_SOURCES = rage128_vid.c rage128_vid_la_LIBADD = $(top_builddir)/src/video_out/libdha/libdha.la rage128_vid_la_LDFLAGS = -avoid-version -module +pm2_vid_la_SOURCES = pm2_vid.c +pm2_vid_la_LIBADD = $(top_builddir)/src/video_out/libdha/libdha.la +pm2_vid_la_LDFLAGS = -avoid-version -module + pm3_vid_la_SOURCES = pm3_vid.c pm3_vid_la_LIBADD = $(top_builddir)/src/video_out/libdha/libdha.la pm3_vid_la_LDFLAGS = -avoid-version -module @@ -45,20 +48,12 @@ mach64_vid.lo: source='$*.c' object='$@' libtool=yes \ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' \ $(CCDEPMODE) $(depcomp) \ - $(LTCOMPILE) -DRAGE128 -c -o $@ `test -f $*.c || echo '$(srcdir)/'`$*.c + $(LTCOMPILE) -c -o $@ `test -f $*.c || echo '$(srcdir)/'`$*.c mach64_vid_la_SOURCES = mach64_vid.c mach64_vid_la_LIBADD = $(top_builddir)/src/video_out/libdha/libdha.la mach64_vid_la_LDFLAGS = -avoid-version -module -nvidia_vid_la_SOURCES = nvidia_vid.c -nvidia_vid_la_LIBADD = $(top_builddir)/src/video_out/libdha/libdha.la -lm -nvidia_vid_la_LDFLAGS = -avoid-version -module - -genfb_vid_la_SOURCES = genfb_vid.c -genfb_vid_la_LIBADD = $(top_builddir)/src/video_out/libdha/libdha.la -lm -genfb_vid_la_LDFLAGS = -avoid-version -module - mga_vid_la_SOURCES = mga_vid.c mga_vid_la_LIBADD = $(top_builddir)/src/video_out/libdha/libdha.la -lm mga_vid_la_LDFLAGS = -avoid-version -module @@ -79,7 +74,7 @@ mga_crtc2_vid_la_SOURCES = mga_crtc2_vid.c mga_crtc2_vid_la_LIBADD = $(top_builddir)/src/video_out/libdha/libdha.la -lm mga_crtc2_vid_la_LDFLAGS = -avoid-version -module -noinst_HEADERS = mach64.h nvidia.h pm3_regs.h radeon.h +noinst_HEADERS = mach64.h nvidia.h glint_regs.h pm3_regs.h radeon.h AM_CPPFLAGS = -I$(top_srcdir)/src/video_out/vidix \ -I$(top_srcdir)/src/video_out/libdha diff --git a/src/video_out/vidix/drivers/genfb_vid.c b/src/video_out/vidix/drivers/genfb_vid.c index 82633eda3..83623a26a 100644 --- a/src/video_out/vidix/drivers/genfb_vid.c +++ b/src/video_out/vidix/drivers/genfb_vid.c @@ -6,13 +6,14 @@ #include <inttypes.h> #include <fcntl.h> -#include "vidix.h" -#include "fourcc.h" -#include "libdha.h" -#include "pci_ids.h" -#include "pci_names.h" +#include "../vidix.h" +#include "../fourcc.h" +#include "../../libdha/libdha.h" +#include "../../libdha/pci_ids.h" +#include "../../libdha/pci_names.h" #define DEMO_DRIVER 1 +#define VIDIX_STATIC genfb_ #define GENFB_MSG "[genfb-demo-driver] " @@ -44,12 +45,12 @@ static vidix_capability_t genfb_cap = { 0, 0, 0, 0 } }; -unsigned int vixGetVersion(void) +unsigned int VIDIX_NAME(vixGetVersion)(void) { return(VIDIX_VERSION); } -int vixProbe(int verbose,int force) +int VIDIX_NAME(vixProbe)(int verbose,int force) { #if 0 int err = 0; @@ -96,7 +97,7 @@ int vixProbe(int verbose,int force) #endif } -int vixInit(void) +int VIDIX_NAME(vixInit)(const char *args) { printf(GENFB_MSG"init\n"); @@ -109,19 +110,19 @@ int vixInit(void) return(0); } -void vixDestroy(void) +void VIDIX_NAME(vixDestroy)(void) { printf(GENFB_MSG"destory\n"); return; } -int vixGetCapability(vidix_capability_t *to) +int VIDIX_NAME(vixGetCapability)(vidix_capability_t *to) { memcpy(to, &genfb_cap, sizeof(vidix_capability_t)); return(0); } -int vixQueryFourcc(vidix_fourcc_t *to) +int VIDIX_NAME(vixQueryFourcc)(vidix_fourcc_t *to) { printf(GENFB_MSG"query fourcc (%x)\n", to->fourcc); @@ -135,7 +136,7 @@ int vixQueryFourcc(vidix_fourcc_t *to) return(0); } -int vixConfigPlayback(vidix_playback_t *info) +int VIDIX_NAME(vixConfigPlayback)(vidix_playback_t *info) { printf(GENFB_MSG"config playback\n"); @@ -155,19 +156,19 @@ int vixConfigPlayback(vidix_playback_t *info) return(0); } -int vixPlaybackOn(void) +int VIDIX_NAME(vixPlaybackOn)(void) { printf(GENFB_MSG"playback on\n"); return(0); } -int vixPlaybackOff(void) +int VIDIX_NAME(vixPlaybackOff)(void) { printf(GENFB_MSG"playback off\n"); return(0); } -int vixPlaybackFrameSelect(unsigned int frame) +int VIDIX_NAME(vixPlaybackFrameSelect)(unsigned int frame) { printf(GENFB_MSG"frameselect: %d\n", frame); return(0); diff --git a/src/video_out/vidix/drivers/mach64_vid.c b/src/video_out/vidix/drivers/mach64_vid.c index 8c4f00868..746af5865 100644 --- a/src/video_out/vidix/drivers/mach64_vid.c +++ b/src/video_out/vidix/drivers/mach64_vid.c @@ -5,10 +5,6 @@ Licence: GPL WARNING: THIS DRIVER IS IN BETTA STAGE */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <errno.h> #include <stdio.h> #include <stdlib.h> @@ -16,6 +12,7 @@ #include <math.h> #include <inttypes.h> #include <fcntl.h> +#include <limits.h> #include <sys/mman.h> /* for m(un)lock */ #ifdef HAVE_MALLOC_H #include <malloc.h> @@ -24,17 +21,20 @@ #endif #endif - #include "vidix.h" #include "fourcc.h" #include "libdha.h" #include "pci_ids.h" #include "pci_names.h" +#include "bswap.h" #include "mach64.h" #define UNUSED(x) ((void)(x)) /**< Removes warning about unused arguments */ +#define MACH64_MSG "mach64_vid:" + +#define VIDIX_STATIC mach64_ #ifdef MACH64_ENABLE_BM @@ -174,8 +174,11 @@ static video_registers_t vregs[] = #define INREG8(addr) GETREG(uint8_t,(uint32_t)mach64_mmio_base,((addr)^0x100)<<2) #define OUTREG8(addr,val) SETREG(uint8_t,(uint32_t)mach64_mmio_base,((addr)^0x100)<<2,val) -#define INREG(addr) GETREG(uint32_t,(uint32_t)mach64_mmio_base,((addr)^0x100)<<2) -#define OUTREG(addr,val) SETREG(uint32_t,(uint32_t)mach64_mmio_base,((addr)^0x100)<<2,val) +static inline uint32_t INREG (uint32_t addr) { + uint32_t tmp = GETREG(uint32_t,(uint32_t)mach64_mmio_base,((addr)^0x100)<<2); + return le2me_32(tmp); +} +#define OUTREG(addr,val) SETREG(uint32_t,(uint32_t)mach64_mmio_base,((addr)^0x100)<<2,le2me_32(val)) #define OUTREGP(addr,val,mask) \ do { \ @@ -227,6 +230,7 @@ static void mach64_engine_reset( void ) { /* Kill off bus mastering with extreme predjudice... */ OUTREG(BUS_CNTL, INREG(BUS_CNTL) | BUS_MASTER_DIS); + OUTREG(CRTC_INT_CNTL,INREG(CRTC_INT_CNTL)&~(CRTC_BUSMASTER_EOL_INT|CRTC_BUSMASTER_EOL_INT_EN)); /* Reset engine -- This is accomplished by setting bit 8 of the GEN_TEST_CNTL register high, then low (per the documentation, it's on high to low transition that the GUI engine gets reset...) */ @@ -329,7 +333,7 @@ static int mach64_get_vert_stretch(void) int yres= mach64_get_yres(); if(!supports_lcd_v_stretch){ - if(__verbose>0) printf("[mach64] vertical stretching not supported\n"); + if(__verbose>0) printf(MACH64_MSG" vertical stretching not supported\n"); return 1<<16; } @@ -352,7 +356,7 @@ static int mach64_get_vert_stretch(void) OUTREG(LCD_INDEX, lcd_index); - if(__verbose>0) printf("[mach64] vertical stretching factor= %d\n", ret); + if(__verbose>0) printf(MACH64_MSG" vertical stretching factor= %d\n", ret); return ret; } @@ -375,80 +379,89 @@ static void mach64_vid_make_default() static void mach64_vid_dump_regs( void ) { size_t i; - printf("[mach64] *** Begin of DRIVER variables dump ***\n"); - printf("[mach64] mach64_mmio_base=%p\n",mach64_mmio_base); - printf("[mach64] mach64_mem_base=%p\n",mach64_mem_base); - printf("[mach64] mach64_overlay_off=%08X\n",mach64_overlay_offset); - printf("[mach64] mach64_ram_size=%08X\n",mach64_ram_size); - printf("[mach64] video mode: %ux%u@%u\n",mach64_get_xres(),mach64_get_yres(),mach64_vid_get_dbpp()); - printf("[mach64] *** Begin of OV0 registers dump ***\n"); + printf(MACH64_MSG" *** Begin of DRIVER variables dump ***\n"); + printf(MACH64_MSG" mach64_mmio_base=%p\n",mach64_mmio_base); + printf(MACH64_MSG" mach64_mem_base=%p\n",mach64_mem_base); + printf(MACH64_MSG" mach64_overlay_off=%08X\n",mach64_overlay_offset); + printf(MACH64_MSG" mach64_ram_size=%08X\n",mach64_ram_size); + printf(MACH64_MSG" video mode: %ux%u@%u\n",mach64_get_xres(),mach64_get_yres(),mach64_vid_get_dbpp()); + printf(MACH64_MSG" *** Begin of OV0 registers dump ***\n"); for(i=0;i<sizeof(vregs)/sizeof(video_registers_t);i++) { mach64_wait_for_idle(); - printf("[mach64] %s = %08X\n",vregs[i].sname,INREG(vregs[i].name)); + mach64_fifo_wait(2); + printf(MACH64_MSG" %s = %08X\n",vregs[i].sname,INREG(vregs[i].name)); } - printf("[mach64] *** End of OV0 registers dump ***\n"); + printf(MACH64_MSG" *** End of OV0 registers dump ***\n"); } -unsigned int vixGetVersion(void) +unsigned int VIDIX_NAME(vixGetVersion)(void) { return(VIDIX_VERSION); } -static unsigned short ati_card_ids[] = +typedef struct ati_chip_id_s +{ + unsigned short id; + unsigned short is_agp; +}ati_chip_id_t; + +static ati_chip_id_t ati_card_ids[] = { - DEVICE_ATI_215CT_MACH64_CT, - DEVICE_ATI_210888CX_MACH64_CX, - DEVICE_ATI_210888ET_MACH64_ET, - DEVICE_ATI_MACH64_VT, - DEVICE_ATI_210888GX_MACH64_GX, - DEVICE_ATI_264LT_MACH64_LT, - DEVICE_ATI_264VT_MACH64_VT, - DEVICE_ATI_264VT3_MACH64_VT3, - DEVICE_ATI_264VT4_MACH64_VT4, + { DEVICE_ATI_215CT_MACH64_CT, 0 }, + { DEVICE_ATI_210888CX_MACH64_CX, 0 }, + { DEVICE_ATI_210888ET_MACH64_ET, 0 }, + { DEVICE_ATI_MACH64_VT, 0 }, + { DEVICE_ATI_210888GX_MACH64_GX, 0 }, + { DEVICE_ATI_264LT_MACH64_LT, 0 }, + { DEVICE_ATI_264VT_MACH64_VT, 0 }, + { DEVICE_ATI_264VT3_MACH64_VT3, 0 }, + { DEVICE_ATI_264VT4_MACH64_VT4, 0 }, /**/ - DEVICE_ATI_3D_RAGE_PRO, - DEVICE_ATI_3D_RAGE_PRO2, - DEVICE_ATI_3D_RAGE_PRO3, - DEVICE_ATI_3D_RAGE_PRO4, - DEVICE_ATI_RAGE_XC, - DEVICE_ATI_RAGE_XL_AGP, - DEVICE_ATI_RAGE_XC_AGP, - DEVICE_ATI_RAGE_XL, - DEVICE_ATI_3D_RAGE_PRO5, - DEVICE_ATI_3D_RAGE_PRO6, - DEVICE_ATI_RAGE_XL2, - DEVICE_ATI_RAGE_XC2, - DEVICE_ATI_3D_RAGE_I_II, - DEVICE_ATI_3D_RAGE_II, - DEVICE_ATI_3D_RAGE_IIC, - DEVICE_ATI_3D_RAGE_IIC2, - DEVICE_ATI_3D_RAGE_IIC3, - DEVICE_ATI_3D_RAGE_IIC4, - DEVICE_ATI_3D_RAGE_LT, - DEVICE_ATI_3D_RAGE_LT2, - DEVICE_ATI_3D_RAGE_LT_G, - DEVICE_ATI_3D_RAGE_LT3, - DEVICE_ATI_RAGE_MOBILITY_P_M, - DEVICE_ATI_RAGE_MOBILITY_L, - DEVICE_ATI_3D_RAGE_LT4, - DEVICE_ATI_3D_RAGE_LT5, - DEVICE_ATI_RAGE_MOBILITY_P_M2, - DEVICE_ATI_RAGE_MOBILITY_L2 + { DEVICE_ATI_3D_RAGE_PRO, 1 }, + { DEVICE_ATI_3D_RAGE_PRO2, 1 }, + { DEVICE_ATI_3D_RAGE_PRO3, 0 }, + { DEVICE_ATI_3D_RAGE_PRO4, 0 }, + { DEVICE_ATI_RAGE_XC, 0 }, + { DEVICE_ATI_RAGE_XL_AGP, 1 }, + { DEVICE_ATI_RAGE_XC_AGP, 1 }, + { DEVICE_ATI_RAGE_XL, 0 }, + { DEVICE_ATI_3D_RAGE_PRO5, 0 }, + { DEVICE_ATI_3D_RAGE_PRO6, 0 }, + { DEVICE_ATI_RAGE_XL2, 0 }, + { DEVICE_ATI_RAGE_XC2, 0 }, + { DEVICE_ATI_3D_RAGE_I_II, 0 }, + { DEVICE_ATI_3D_RAGE_II, 0 }, + { DEVICE_ATI_3D_RAGE_IIC, 1 }, + { DEVICE_ATI_3D_RAGE_IIC2, 0 }, + { DEVICE_ATI_3D_RAGE_IIC3, 0 }, + { DEVICE_ATI_3D_RAGE_IIC4, 1 }, + { DEVICE_ATI_3D_RAGE_LT, 1 }, + { DEVICE_ATI_3D_RAGE_LT2, 1 }, + { DEVICE_ATI_3D_RAGE_LT_G, 0 }, + { DEVICE_ATI_3D_RAGE_LT3, 0 }, + { DEVICE_ATI_RAGE_MOBILITY_P_M, 1 }, + { DEVICE_ATI_RAGE_MOBILITY_L, 1 }, + { DEVICE_ATI_3D_RAGE_LT4, 0 }, + { DEVICE_ATI_3D_RAGE_LT5, 0 }, + { DEVICE_ATI_RAGE_MOBILITY_P_M2, 0 }, + { DEVICE_ATI_RAGE_MOBILITY_L2, 0 } }; +static int is_agp; + 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_chip_id_t);i++) { - if(chip_id == ati_card_ids[i]) return i; + if(chip_id == ati_card_ids[i].id) return i; } return -1; } -int vixProbe(int verbose,int force) +int VIDIX_NAME(vixProbe)(int verbose,int force) { pciinfo_t lst[MAX_PCI_DEVICES]; unsigned i,num_pci; @@ -457,7 +470,7 @@ int vixProbe(int verbose,int force) err = pci_scan(lst,&num_pci); if(err) { - printf("[mach64] Error occured during pci scan: %s\n",strerror(err)); + printf(MACH64_MSG" Error occured during pci scan: %s\n",strerror(err)); return err; } else @@ -473,13 +486,14 @@ int vixProbe(int verbose,int force) if(idx == -1 && force == PROBE_NORMAL) continue; dname = pci_device_name(VENDOR_ATI,lst[i].device); dname = dname ? dname : "Unknown chip"; - printf("[mach64] Found chip: %s\n",dname); + printf(MACH64_MSG" Found chip: %s\n",dname); if(force > PROBE_NORMAL) { - printf("[mach64] Driver was forced. Was found %sknown chip\n",idx == -1 ? "un" : ""); + printf(MACH64_MSG" Driver was forced. Was found %sknown chip\n",idx == -1 ? "un" : ""); if(idx == -1) - printf("[mach64] Assuming it as Mach64\n"); + printf(MACH64_MSG" Assuming it as Mach64\n"); } + if(idx != -1) is_agp = ati_card_ids[idx].is_agp; mach64_cap.device_id = lst[i].device; err = 0; memcpy(&pci_info,&lst[i],sizeof(pciinfo_t)); @@ -488,7 +502,7 @@ int vixProbe(int verbose,int force) } } } - if(err && verbose) printf("[mach64] Can't find chip\n"); + if(err && verbose) printf(MACH64_MSG" Can't find chip\n"); return err; } @@ -502,17 +516,75 @@ static void reset_regs( void ) } } -int vixInit(void) +typedef struct saved_regs_s +{ + uint32_t overlay_video_key_clr; + uint32_t overlay_video_key_msk; + uint32_t overlay_graphics_key_clr; + uint32_t overlay_graphics_key_msk; + uint32_t overlay_key_cntl; +}saved_regs_t; +static saved_regs_t savreg; + +static void save_regs( void ) +{ + mach64_fifo_wait(6); + savreg.overlay_video_key_clr = INREG(OVERLAY_VIDEO_KEY_CLR); + savreg.overlay_video_key_msk = INREG(OVERLAY_VIDEO_KEY_MSK); + savreg.overlay_graphics_key_clr = INREG(OVERLAY_GRAPHICS_KEY_CLR); + savreg.overlay_graphics_key_msk = INREG(OVERLAY_GRAPHICS_KEY_MSK); + savreg.overlay_key_cntl = INREG(OVERLAY_KEY_CNTL); +} + +static void restore_regs( void ) +{ + mach64_fifo_wait(6); + OUTREG(OVERLAY_VIDEO_KEY_CLR,savreg.overlay_video_key_clr); + OUTREG(OVERLAY_VIDEO_KEY_MSK,savreg.overlay_video_key_msk); + OUTREG(OVERLAY_GRAPHICS_KEY_CLR,savreg.overlay_graphics_key_clr); + OUTREG(OVERLAY_GRAPHICS_KEY_MSK,savreg.overlay_graphics_key_msk); + OUTREG(OVERLAY_KEY_CNTL,savreg.overlay_key_cntl); +} + +static int forced_irq=UINT_MAX; +static int can_use_irq=0; +static int irq_installed=0; +static void init_irq(void) +{ + irq_installed=1; + if(forced_irq != UINT_MAX) pci_info.irq=forced_irq; + if(hwirq_install(pci_info.bus,pci_info.card,pci_info.func, + 2,CRTC_INT_CNTL,CRTC_BUSMASTER_EOL_INT) == 0) + { + can_use_irq=1; + if(__verbose) printf(MACH64_MSG" Will use %u irq line\n",pci_info.irq); + } + else + if(__verbose) printf(MACH64_MSG" Can't initialize irq handling: %s\n" + MACH64_MSG"irq_param: line=%u pin=%u gnt=%u lat=%u\n" + ,strerror(errno) + ,pci_info.irq,pci_info.ipin,pci_info.gnt,pci_info.lat); +} + +int VIDIX_NAME(vixInit)(const char *args) { int err; +#ifdef MACH64_ENABLE_BM unsigned i; +#endif if(!probed) { - printf("[mach64] Driver was not probed but is being initializing\n"); + printf(MACH64_MSG" Driver was not probed but is being initializing\n"); return EINTR; } - if(__verbose>0) printf("[mach64] version %s\n", VERSION); - + if(__verbose>0) printf(MACH64_MSG" version %d args='%s'\n", VIDIX_VERSION,args); + if(args) + if(strncmp(args,"irq=",4) == 0) + { + forced_irq=atoi(&args[4]); + if(__verbose>0) printf(MACH64_MSG" forcing IRQ to %u\n",forced_irq); + } + if((mach64_mmio_base = map_phys_mem(pci_info.base2,0x4000))==(void *)-1) return ENOMEM; mach64_wait_for_idle(); mach64_ram_size = INREG(MEM_CNTL) & CTL_MEM_SIZEB; @@ -522,10 +594,11 @@ int vixInit(void) mach64_ram_size *= 0x400; /* KB -> bytes */ if((mach64_mem_base = map_phys_mem(pci_info.base0,mach64_ram_size))==(void *)-1) return ENOMEM; memset(&besr,0,sizeof(bes_registers_t)); - printf("[mach64] Video memory = %uMb\n",mach64_ram_size/0x100000); + printf(MACH64_MSG" Video memory = %uMb\n",mach64_ram_size/0x100000); err = mtrr_set_type(pci_info.base0,mach64_ram_size,MTRR_TYPE_WRCOMB); - if(!err) printf("[mach64] Set write-combining type of video memory\n"); + if(!err) printf(MACH64_MSG" Set write-combining type of video memory\n"); + save_regs(); /* check if planar formats are supported */ supports_planar=0; mach64_wait_for_idle(); @@ -541,7 +614,7 @@ int vixInit(void) if(INREG(SCALER_BUF0_OFFSET_U)) supports_planar=1; } - printf("[mach64] Planar YUV formats are %s supported\n",supports_planar?"":"not"); + printf(MACH64_MSG" Planar YUV formats are %s supported\n",supports_planar?"":"not"); supports_colour_adj=0; OUTREG(SCALER_COLOUR_CNTL,-1); if(INREG(SCALER_COLOUR_CNTL)) supports_colour_adj=1; @@ -549,12 +622,12 @@ int vixInit(void) OUTREG(IDCT_CONTROL,-1); if(INREG(IDCT_CONTROL)) supports_idct=1; OUTREG(IDCT_CONTROL,0); - printf("[mach64] IDCT is %s supported\n",supports_idct?"":"not"); + printf(MACH64_MSG" IDCT is %s supported\n",supports_idct?"":"not"); supports_subpic=0; OUTREG(SUBPIC_CNTL,-1); if(INREG(SUBPIC_CNTL)) supports_subpic=1; OUTREG(SUBPIC_CNTL,0); - printf("[mach64] subpictures are %s supported\n",supports_subpic?"":"not"); + printf(MACH64_MSG" subpictures are %s supported\n",supports_subpic?"":"not"); if( mach64_cap.device_id==DEVICE_ATI_RAGE_MOBILITY_P_M || mach64_cap.device_id==DEVICE_ATI_RAGE_MOBILITY_P_M2 || mach64_cap.device_id==DEVICE_ATI_RAGE_MOBILITY_L @@ -567,13 +640,15 @@ int vixInit(void) mach64_vid_make_default(); if(__verbose > VERBOSE_LEVEL) mach64_vid_dump_regs(); #ifdef MACH64_ENABLE_BM + if(!(INREG(BUS_CNTL) & BUS_MASTER_DIS)) + OUTREG(BUS_CNTL,INREG(BUS_CNTL)|BUS_MSTR_RESET); if(bm_open() == 0) { mach64_cap.flags |= FLAG_DMA | FLAG_EQ_DMA; if((dma_phys_addrs = malloc(mach64_ram_size*sizeof(unsigned long)/4096)) == 0) { out_mem: - printf("[mach64] Can't allocate temopary buffer for DMA\n"); + printf(MACH64_MSG" Can't allocate temporary buffer for DMA\n"); mach64_cap.flags &= ~FLAG_DMA & ~FLAG_EQ_DMA; return 0; } @@ -585,20 +660,36 @@ int vixInit(void) for(i=0;i<64;i++) if((mach64_dma_desc_base[i] = memalign(4096,mach64_ram_size*sizeof(bm_list_descriptor)/4096)) == 0) goto out_mem; +#if 0 + if(!is_agp) + { + long tst; + if(pci_config_read(pci_info.bus,pci_info.card,pci_info.func,4,4,&pci_command) == 0) + pci_config_write(pci_info.bus,pci_info.card,pci_info.func,4,4,pci_command|0x14); + pci_config_read(pci_info.bus,pci_info.card,pci_info.func,4,4,&tst); + } +#endif } else - if(__verbose) printf("[mach64] Can't initialize busmastering: %s\n",strerror(errno)); + if(__verbose) printf(MACH64_MSG" Can't initialize busmastering: %s\n",strerror(errno)); #endif return 0; } -void vixDestroy(void) +void VIDIX_NAME(vixDestroy)(void) { +#ifdef MACH64_ENABLE_BM unsigned i; +#endif + restore_regs(); +#ifdef MACH64_ENABLE_BM + mach64_engine_reset(); +#endif unmap_phys_mem(mach64_mem_base,mach64_ram_size); unmap_phys_mem(mach64_mmio_base,0x4000); #ifdef MACH64_ENABLE_BM bm_close(); + if(can_use_irq && irq_installed) hwirq_uninstall(pci_info.bus,pci_info.card,pci_info.func); if(dma_phys_addrs) free(dma_phys_addrs); for(i=0;i<64;i++) { @@ -607,7 +698,7 @@ void vixDestroy(void) #endif } -int vixGetCapability(vidix_capability_t *to) +int VIDIX_NAME(vixGetCapability)(vidix_capability_t *to) { memcpy(to, &mach64_cap, sizeof(vidix_capability_t)); return 0; @@ -745,9 +836,8 @@ static void mach64_vid_display_video( void ) As for me - I would prefer to limit movie's width with 360 but it provides only half of picture but with perfect quality. (NK) */ - mach64_fifo_wait(4); + mach64_fifo_wait(10); OUTREG(OVERLAY_SCALE_CNTL, sc); - mach64_wait_for_idle(); switch(besr.fourcc) @@ -849,7 +939,7 @@ for(i=0; i<32; i++){ } } #endif - if(__verbose>0) printf("[mach64] ecp: %d\n", ecp); + if(__verbose>0) printf(MACH64_MSG" ecp: %d\n", ecp); v_inc = src_h * mach64_get_vert_stretch(); if(mach64_is_interlace()) v_inc<<=1; @@ -931,7 +1021,6 @@ for(i=0; i<32; i++){ if(mach64_is_interlace()) y_pos/=2; besr.y_x_end = y_pos | ((config->dest.x + dest_w) << 16); besr.height_width = ((src_w - left)<<16) | (src_h - top); - return 0; } @@ -955,7 +1044,7 @@ static int is_supported_fourcc(uint32_t fourcc) } } -int vixQueryFourcc(vidix_fourcc_t *to) +int VIDIX_NAME(vixQueryFourcc)(vidix_fourcc_t *to) { if(is_supported_fourcc(to->fourcc)) { @@ -971,14 +1060,14 @@ int vixQueryFourcc(vidix_fourcc_t *to) return ENOSYS; } -int vixConfigPlayback(vidix_playback_t *info) +int VIDIX_NAME(vixConfigPlayback)(vidix_playback_t *info) { unsigned rgb_size,nfr; uint32_t mach64_video_size; if(!is_supported_fourcc(info->fourcc)) return ENOSYS; if(info->src.h > 720 || info->src.w > 720) { - printf("[mach64] Can't apply width or height > 720\n"); + printf(MACH64_MSG" Can't apply width or height > 720\n"); return EINVAL; } if(info->num_frames>VID_PLAY_MAXFRAMES) info->num_frames=VID_PLAY_MAXFRAMES; @@ -1011,7 +1100,7 @@ int vixConfigPlayback(vidix_playback_t *info) return 0; } -int vixPlaybackOn(void) +int VIDIX_NAME(vixPlaybackOn)(void) { int err; unsigned dw,dh; @@ -1023,19 +1112,19 @@ int vixPlaybackOn(void) err = INREG(SCALER_BUF_PITCH) == besr.vid_buf_pitch ? 0 : EINTR; if(err) { - printf("[mach64] *** Internal fatal error ***: Detected pitch corruption\n" - "[mach64] Try decrease number of buffers\n"); + printf(MACH64_MSG" *** Internal fatal error ***: Detected pitch corruption\n" + MACH64_MSG" Try decrease number of buffers\n"); } return err; } -int vixPlaybackOff(void) +int VIDIX_NAME(vixPlaybackOff)(void) { mach64_vid_stop_video(); return 0; } -int vixPlaybackFrameSelect(unsigned int frame) +int VIDIX_NAME(vixPlaybackFrameSelect)(unsigned int frame) { uint32_t off[6]; int i; @@ -1050,7 +1139,7 @@ int vixPlaybackFrameSelect(unsigned int frame) off[i] = mach64_buffer_base[frame][i]; off[i+3]= mach64_buffer_base[last_frame][i]; } - if(__verbose > VERBOSE_LEVEL) printf("mach64_vid: flip_page = %u\n",frame); + if(__verbose > VERBOSE_LEVEL) printf(MACH64_MSG" flip_page = %u\n",frame); #if 0 // delay routine so the individual frames can be ssen better { @@ -1080,14 +1169,14 @@ vidix_video_eq_t equal = , 0, 0, 0, 0, 0, 0, 0, 0 }; -int vixPlaybackGetEq( vidix_video_eq_t * eq) +int VIDIX_NAME(vixPlaybackGetEq)( vidix_video_eq_t * eq) { memcpy(eq,&equal,sizeof(vidix_video_eq_t)); if(!supports_colour_adj) eq->cap = VEQ_CAP_BRIGHTNESS; return 0; } -int vixPlaybackSetEq( const vidix_video_eq_t * eq) +int VIDIX_NAME(vixPlaybackSetEq)( const vidix_video_eq_t * eq) { int br,sat; if(eq->cap & VEQ_CAP_BRIGHTNESS) equal.brightness = eq->brightness; @@ -1126,13 +1215,13 @@ int vixPlaybackSetEq( const vidix_video_eq_t * eq) return 0; } -int vixGetGrKeys(vidix_grkey_t *grkey) +int VIDIX_NAME(vixGetGrKeys)(vidix_grkey_t *grkey) { memcpy(grkey, &mach64_grkey, sizeof(vidix_grkey_t)); return(0); } -int vixSetGrKeys(const vidix_grkey_t *grkey) +int VIDIX_NAME(vixSetGrKeys)(const vidix_grkey_t *grkey) { memcpy(&mach64_grkey, grkey, sizeof(vidix_grkey_t)); @@ -1213,6 +1302,9 @@ static int mach64_setup_frame( vidix_dma_t * dmai ) dmai->internal[dmai->idx] = mach64_dma_desc_base[dmai->idx]; dest_ptr = dmai->dest_offset; count = dmai->size; +#if 0 +printf("MACH64_DMA_REQUEST va=%X size=%X\n",dmai->src,dmai->size); +#endif for(i=0;i<n;i++) { list[i].framebuf_offset = mach64_overlay_offset + dest_ptr; /* offset within of video memory */ @@ -1220,42 +1312,70 @@ static int mach64_setup_frame( vidix_dma_t * dmai ) list[i].command = (count > 4096 ? 4096 : (count | DMA_GUI_COMMAND__EOL)); list[i].reserved = 0; #if 0 -printf("MACH64_DMA_TABLE[%i] %X %X %X %X\n",i,list[i].framebuf_offset,list[i].sys_addr,list[i].command,list[i].reserved); +printf("MACH64_DMA_TABLE[%i] fboff=%X pa=%X cmd=%X rsrvd=%X\n",i,list[i].framebuf_offset,list[i].sys_addr,list[i].command,list[i].reserved); #endif dest_ptr += 4096; count -= 4096; } + cpu_flush(list,4096); } return 0; } -static int mach64_transfer_frame( unsigned long ba_dma_desc ) +static int mach64_transfer_frame( unsigned long ba_dma_desc,int sync_mode ) { + uint32_t crtc_int; mach64_wait_for_idle(); - OUTREG(BUS_CNTL,(INREG(BUS_CNTL)|BUS_MSTR_RESET)); - OUTREG(CRTC_INT_CNTL,INREG(CRTC_INT_CNTL)|CRTC_BUSMASTER_EOL_INT|CRTC_BUSMASTER_EOL_INT_EN); - OUTREG(BUS_CNTL,(INREG(BUS_CNTL)|BUS_EXT_REG_EN|BUS_READ_BURST|BUS_PCI_READ_RETRY_EN) &(~BUS_MASTER_DIS)); + mach64_fifo_wait(10); + OUTREG(BUS_CNTL,(INREG(BUS_CNTL)|BUS_EXT_REG_EN)&(~BUS_MASTER_DIS)); + crtc_int = INREG(CRTC_INT_CNTL); + if(sync_mode && can_use_irq) OUTREG(CRTC_INT_CNTL,crtc_int|CRTC_BUSMASTER_EOL_INT|CRTC_BUSMASTER_EOL_INT_EN); + else OUTREG(CRTC_INT_CNTL,crtc_int|CRTC_BUSMASTER_EOL_INT); OUTREG(BM_SYSTEM_TABLE,ba_dma_desc|SYSTEM_TRIGGER_SYSTEM_TO_VIDEO); if(__verbose > VERBOSE_LEVEL) mach64_vid_dump_regs(); +#if 0 + mach64_fifo_wait(4); + mach64_fifo_wait(16); + printf("MACH64_DMA_DBG: bm_fb_off=%08X bm_sysmem_addr=%08X bm_cmd=%08X bm_status=%08X bm_agp_base=%08X bm_agp_cntl=%08X\n", + INREG(BM_FRAME_BUF_OFFSET), + INREG(BM_SYSTEM_MEM_ADDR), + INREG(BM_COMMAND), + INREG(BM_STATUS), + INREG(AGP_BASE), + INREG(AGP_CNTL)); +#endif return 0; } +int VIDIX_NAME(vixQueryDMAStatus)( void ) +{ + int bm_off; + unsigned crtc_int_cntl; + crtc_int_cntl = INREG(CRTC_INT_CNTL); + bm_off = crtc_int_cntl & CRTC_BUSMASTER_EOL_INT; +// if(bm_off) OUTREG(CRTC_INT_CNTL,crtc_int_cntl | CRTC_BUSMASTER_EOL_INT); + return bm_off?0:1; +} -int vixPlaybackCopyFrame( vidix_dma_t * dmai ) +int VIDIX_NAME(vixPlaybackCopyFrame)( vidix_dma_t * dmai ) { - int retval; + int retval,sync_mode; if(!(dmai->flags & BM_DMA_FIXED_BUFFS)) if(bm_lock_mem(dmai->src,dmai->size) != 0) return errno; + sync_mode = (dmai->flags & BM_DMA_SYNC) == BM_DMA_SYNC; + if(sync_mode) + { + if(!irq_installed) init_irq(); + /* burn CPU instead of PCI bus here */ + while(vixQueryDMAStatus()!=0){ + if(can_use_irq) hwirq_wait(pci_info.irq); + else usleep(0); /* ugly but may help */ + } + } + mach64_engine_reset(); retval = mach64_setup_frame(dmai); VIRT_TO_CARD(mach64_dma_desc_base[dmai->idx],1,&bus_addr_dma_desc); - if(retval == 0) retval = mach64_transfer_frame(bus_addr_dma_desc); + if(retval == 0) retval = mach64_transfer_frame(bus_addr_dma_desc,sync_mode); if(!(dmai->flags & BM_DMA_FIXED_BUFFS)) bm_unlock_mem(dmai->src,dmai->size); return retval; } - -int vixQueryDMAStatus( void ) -{ - int bm_off; - bm_off = INREG(CRTC_INT_CNTL) & CRTC_BUSMASTER_EOL_INT; - return bm_off?0:1; -} #endif diff --git a/src/video_out/vidix/drivers/mga_vid.c b/src/video_out/vidix/drivers/mga_vid.c index 39b2176b2..2e2f5c4b7 100644 --- a/src/video_out/vidix/drivers/mga_vid.c +++ b/src/video_out/vidix/drivers/mga_vid.c @@ -1,18 +1,21 @@ /* - Matrox MGA driver - - ported to VIDIX by Alex Beregszaszi - - YUY2 support (see config.format) added by A'rpi/ESP-team - double buffering added by A'rpi/ESP-team - - Brightness/contrast support by Nick Kurshev/Dariush Pietrzak (eyck) and me - - TODO: - * fix memory size detection (current reading pci userconfig isn't - working as requested - returns the max avail. ram on arch?) - * translate all non-english comments to english -*/ + * Matrox MGA driver + * + * ported to VIDIX by Alex Beregszaszi + * + * YUY2 support (see config.format) added by A'rpi/ESP-team + * double buffering added by A'rpi/ESP-team + * + * Brightness/contrast support by Nick Kurshev/Dariush Pietrzak (eyck) and me + * + * Fixed Brightness/Contrast + * Rewrite or read/write kabi@users.sf.net + * + * TODO: + * * fix memory size detection (current reading pci userconfig isn't + * working as requested - returns the max avail. ram on arch?) + * * translate all non-english comments to english + */ /* * Original copyright: @@ -20,14 +23,14 @@ * mga_vid.c * * Copyright (C) 1999 Aaron Holtzman - * - * Module skeleton based on gutted agpgart module by Jeff Hartmann + * + * Module skeleton based on gutted agpgart module by Jeff Hartmann * <slicer@ionet.net> * * Matrox MGA G200/G400 YUV Video Interface module Version 0.1.0 - * + * * BES == Back End Scaler - * + * * This software has been released under the terms of the GNU Public * license. See http://www.gnu.org/copyleft/gpl.html for details. */ @@ -64,14 +67,22 @@ #define ENOTSUP EOPNOTSUPP #endif +#ifdef CRTC2 +#define VIDIX_STATIC mga_crtc2_ +#define MGA_MSG "mga_crtc2_vid:" +#else +#define VIDIX_STATIC mga_ +#define MGA_MSG "mga_vid:" +#endif + /* from radeon_vid */ #define GETREG(TYPE,PTR,OFFZ) (*((volatile TYPE*)((PTR)+(OFFZ)))) #define SETREG(TYPE,PTR,OFFZ,VAL) (*((volatile TYPE*)((PTR)+(OFFZ))))=VAL -#define readb(addr) GETREG(uint8_t,(uint32_t)(addr),0) -#define writeb(val,addr) SETREG(uint8_t,(uint32_t)(addr),0,val) -#define readl(addr) GETREG(uint32_t,(uint32_t)(addr),0) -#define writel(val,addr) SETREG(uint32_t,(uint32_t)(addr),0,val) +#define readb(addr) GETREG(uint8_t,(uint32_t)(mga_mmio_base + addr),0) +#define writeb(addr, val) SETREG(uint8_t,(uint32_t)(mga_mmio_base + addr),0,val) +#define readl(addr) GETREG(uint32_t,(uint32_t)(mga_mmio_base + addr),0) +#define writel(addr, val) SETREG(uint32_t,(uint32_t)(mga_mmio_base + addr),0,val) static int mga_verbose = 0; @@ -87,7 +98,7 @@ static int vid_overlay_on = 0; /* mapped physical addresses */ static uint8_t *mga_mmio_base = 0; -static uint32_t mga_mem_base = 0; +static uint8_t* mga_mem_base = 0; static int mga_src_base = 0; /* YUV buffer position in video memory */ @@ -119,74 +130,74 @@ static vidix_capability_t mga_cap = -1, FLAG_UPSCALER | FLAG_DOWNSCALER | FLAG_EQUALIZER, VENDOR_MATROX, - -1, /* will be set in vixProbe */ + -1, /* will be set in VIDIX_NAME(vixProbe) */ { 0, 0, 0, 0} }; /* MATROX BES registers */ typedef struct bes_registers_s { - //BES Control - uint32_t besctl; - //BES Global control - uint32_t besglobctl; - //Luma control (brightness and contrast) - uint32_t beslumactl; - //Line pitch - uint32_t bespitch; - - //Buffer A-1 Chroma 3 plane org - uint32_t besa1c3org; - //Buffer A-1 Chroma org - uint32_t besa1corg; - //Buffer A-1 Luma org - uint32_t besa1org; - - //Buffer A-2 Chroma 3 plane org - uint32_t besa2c3org; - //Buffer A-2 Chroma org - uint32_t besa2corg; - //Buffer A-2 Luma org - uint32_t besa2org; - - //Buffer B-1 Chroma 3 plane org - uint32_t besb1c3org; - //Buffer B-1 Chroma org - uint32_t besb1corg; - //Buffer B-1 Luma org - uint32_t besb1org; - - //Buffer B-2 Chroma 3 plane org - uint32_t besb2c3org; - //Buffer B-2 Chroma org - uint32_t besb2corg; - //Buffer B-2 Luma org - uint32_t besb2org; - - //BES Horizontal coord - uint32_t beshcoord; - //BES Horizontal inverse scaling [5.14] - uint32_t beshiscal; - //BES Horizontal source start [10.14] (for scaling) - uint32_t beshsrcst; - //BES Horizontal source ending [10.14] (for scaling) - uint32_t beshsrcend; - //BES Horizontal source last - uint32_t beshsrclst; - - - //BES Vertical coord - uint32_t besvcoord; - //BES Vertical inverse scaling [5.14] - uint32_t besviscal; - //BES Field 1 vertical source last position - uint32_t besv1srclst; - //BES Field 1 weight start - uint32_t besv1wght; - //BES Field 2 vertical source last position - uint32_t besv2srclst; - //BES Field 2 weight start - uint32_t besv2wght; + //BES Control + uint32_t besctl; + //BES Global control + uint32_t besglobctl; + //Luma control (brightness and contrast) + uint32_t beslumactl; + //Line pitch + uint32_t bespitch; + + //Buffer A-1 Chroma 3 plane org + uint32_t besa1c3org; + //Buffer A-1 Chroma org + uint32_t besa1corg; + //Buffer A-1 Luma org + uint32_t besa1org; + + //Buffer A-2 Chroma 3 plane org + uint32_t besa2c3org; + //Buffer A-2 Chroma org + uint32_t besa2corg; + //Buffer A-2 Luma org + uint32_t besa2org; + + //Buffer B-1 Chroma 3 plane org + uint32_t besb1c3org; + //Buffer B-1 Chroma org + uint32_t besb1corg; + //Buffer B-1 Luma org + uint32_t besb1org; + + //Buffer B-2 Chroma 3 plane org + uint32_t besb2c3org; + //Buffer B-2 Chroma org + uint32_t besb2corg; + //Buffer B-2 Luma org + uint32_t besb2org; + + //BES Horizontal coord + uint32_t beshcoord; + //BES Horizontal inverse scaling [5.14] + uint32_t beshiscal; + //BES Horizontal source start [10.14] (for scaling) + uint32_t beshsrcst; + //BES Horizontal source ending [10.14] (for scaling) + uint32_t beshsrcend; + //BES Horizontal source last + uint32_t beshsrclst; + + + //BES Vertical coord + uint32_t besvcoord; + //BES Vertical inverse scaling [5.14] + uint32_t besviscal; + //BES Field 1 vertical source last position + uint32_t besv1srclst; + //BES Field 1 weight start + uint32_t besv1wght; + //BES Field 2 vertical source last position + uint32_t besv2srclst; + //BES Field 2 weight start + uint32_t besv2wght; } bes_registers_t; static bes_registers_t regs; @@ -194,27 +205,28 @@ static bes_registers_t regs; #ifdef CRTC2 typedef struct crtc2_registers_s { - uint32_t c2ctl; - uint32_t c2datactl; - uint32_t c2misc; - uint32_t c2hparam; - uint32_t c2hsync; - uint32_t c2offset; - uint32_t c2pl2startadd0; - uint32_t c2pl2startadd1; - uint32_t c2pl3startadd0; - uint32_t c2pl3startadd1; - uint32_t c2preload; - uint32_t c2spicstartadd0; - uint32_t c2spicstartadd1; - uint32_t c2startadd0; - uint32_t c2startadd1; - uint32_t c2subpiclut; - uint32_t c2vcount; - uint32_t c2vparam; - uint32_t c2vsync; + uint32_t c2ctl; + uint32_t c2datactl; + uint32_t c2misc; + uint32_t c2hparam; + uint32_t c2hsync; + uint32_t c2offset; + uint32_t c2pl2startadd0; + uint32_t c2pl2startadd1; + uint32_t c2pl3startadd0; + uint32_t c2pl3startadd1; + uint32_t c2preload; + uint32_t c2spicstartadd0; + uint32_t c2spicstartadd1; + uint32_t c2startadd0; + uint32_t c2startadd1; + uint32_t c2subpiclut; + uint32_t c2vcount; + uint32_t c2vparam; + uint32_t c2vsync; } crtc2_registers_t; static crtc2_registers_t cregs; +static crtc2_registers_t cregs_save; #endif //All register offsets are converted to word aligned offsets (32 bit) @@ -245,7 +257,7 @@ static crtc2_registers_t cregs; #ifdef CRTC2 /*CRTC2 registers*/ #define XMISCCTRL 0x1e -#define C2CTL 0x3c10 +#define C2CTL 0x3c10 #define C2DATACTL 0x3c4c #define C2MISC 0x3c44 #define C2HPARAM 0x3c14 @@ -276,7 +288,7 @@ static crtc2_registers_t cregs; #define BESA1CORG 0x3d10 #define BESA1ORG 0x3d00 -#define BESA2C3ORG 0x3d64 +#define BESA2C3ORG 0x3d64 #define BESA2CORG 0x3d14 #define BESA2ORG 0x3d04 @@ -306,43 +318,45 @@ static crtc2_registers_t cregs; #define IEN 0x1e1c #define ICLEAR 0x1e18 #define STATUS 0x1e14 +#define CRTCEXTX 0x1fde +#define CRTCEXTD 0x1fdf #ifdef CRTC2 static void crtc2_frame_sel(int frame) { -switch(frame) { -case 0: + switch(frame) { + case 0: cregs.c2pl2startadd0=regs.besa1corg; cregs.c2pl3startadd0=regs.besa1c3org; cregs.c2startadd0=regs.besa1org; break; -case 1: + case 1: cregs.c2pl2startadd0=regs.besa2corg; cregs.c2pl3startadd0=regs.besa2c3org; cregs.c2startadd0=regs.besa2org; break; -case 2: + case 2: cregs.c2pl2startadd0=regs.besb1corg; cregs.c2pl3startadd0=regs.besb1c3org; cregs.c2startadd0=regs.besb1org; break; -case 3: + case 3: cregs.c2pl2startadd0=regs.besb2corg; cregs.c2pl3startadd0=regs.besb2c3org; cregs.c2startadd0=regs.besb2org; break; -} - writel(cregs.c2startadd0, mga_mmio_base + C2STARTADD0); - writel(cregs.c2pl2startadd0, mga_mmio_base + C2PL2STARTADD0); - writel(cregs.c2pl3startadd0, mga_mmio_base + C2PL3STARTADD0); + } + writel(C2STARTADD0, cregs.c2startadd0); + writel(C2PL2STARTADD0, cregs.c2pl2startadd0); + writel(C2PL3STARTADD0, cregs.c2pl3startadd0); } #endif -int vixPlaybackFrameSelect(unsigned int frame) +int VIDIX_NAME(vixPlaybackFrameSelect)(unsigned int frame) { mga_next_frame = frame; - if (mga_verbose>1) printf("[mga] frameselect: %d\n", mga_next_frame); + if (mga_verbose>1) printf(MGA_MSG" frameselect: %d\n", mga_next_frame); #if MGA_ALLOW_IRQ if (mga_irq == -1) #endif @@ -350,11 +364,10 @@ int vixPlaybackFrameSelect(unsigned int frame) //we don't need the vcount protection as we're only hitting //one register (and it doesn't seem to be double buffered) regs.besctl = (regs.besctl & ~0x07000000) + (mga_next_frame << 25); - writel( regs.besctl, mga_mmio_base + BESCTL ); + writel(BESCTL, regs.besctl); -// writel( regs.besglobctl + ((readl(mga_mmio_base + VCOUNT)+2)<<16), - writel( regs.besglobctl + (MGA_VSYNC_POS<<16), - mga_mmio_base + BESGLOBCTL); + // writel( regs.besglobctl + ((readl(VCOUNT)+2)<<16), + writel(BESGLOBCTL, regs.besglobctl + (MGA_VSYNC_POS<<16)); #ifdef CRTC2 crtc2_frame_sel(mga_next_frame); #endif @@ -366,328 +379,335 @@ int vixPlaybackFrameSelect(unsigned int frame) static void mga_vid_write_regs(int restore) { - //Make sure internal registers don't get updated until we're done - writel( (readl(mga_mmio_base + VCOUNT)-1)<<16, - mga_mmio_base + BESGLOBCTL); - - // color or coordinate keying - - if(restore && colkey_saved){ - // restore it - colkey_saved=0; - - printf("[mga] Restoring colorkey (ON: %d %02X:%02X:%02X)\n", - colkey_on,colkey_color[0],colkey_color[1],colkey_color[2]); - - // Set color key registers: - writeb( XKEYOPMODE, mga_mmio_base + PALWTADD); - writeb( colkey_on, mga_mmio_base + X_DATAREG); - - writeb( XCOLKEY0RED, mga_mmio_base + PALWTADD); - writeb( colkey_color[0], mga_mmio_base + X_DATAREG); - writeb( XCOLKEY0GREEN, mga_mmio_base + PALWTADD); - writeb( colkey_color[1], mga_mmio_base + X_DATAREG); - writeb( XCOLKEY0BLUE, mga_mmio_base + PALWTADD); - writeb( colkey_color[2], mga_mmio_base + X_DATAREG); - writeb( X_COLKEY, mga_mmio_base + PALWTADD); - writeb( colkey_color[3], mga_mmio_base + X_DATAREG); - - writeb( XCOLMSK0RED, mga_mmio_base + PALWTADD); - writeb( colkey_mask[0], mga_mmio_base + X_DATAREG); - writeb( XCOLMSK0GREEN, mga_mmio_base + PALWTADD); - writeb( colkey_mask[1], mga_mmio_base + X_DATAREG); - writeb( XCOLMSK0BLUE, mga_mmio_base + PALWTADD); - writeb( colkey_mask[2], mga_mmio_base + X_DATAREG); - writeb( XCOLMSK, mga_mmio_base + PALWTADD); - writeb( colkey_mask[3], mga_mmio_base + X_DATAREG); - - } else if(!colkey_saved){ - // save it - colkey_saved=1; - // Get color key registers: - writeb( XKEYOPMODE, mga_mmio_base + PALWTADD); - colkey_on=(unsigned char)readb(mga_mmio_base + X_DATAREG) & 1; - - writeb( XCOLKEY0RED, mga_mmio_base + PALWTADD); - colkey_color[0]=(unsigned char)readb(mga_mmio_base + X_DATAREG); - writeb( XCOLKEY0GREEN, mga_mmio_base + PALWTADD); - colkey_color[1]=(unsigned char)readb(mga_mmio_base + X_DATAREG); - writeb( XCOLKEY0BLUE, mga_mmio_base + PALWTADD); - colkey_color[2]=(unsigned char)readb(mga_mmio_base + X_DATAREG); - writeb( X_COLKEY, mga_mmio_base + PALWTADD); - colkey_color[3]=(unsigned char)readb(mga_mmio_base + X_DATAREG); - - writeb( XCOLMSK0RED, mga_mmio_base + PALWTADD); - colkey_mask[0]=(unsigned char)readb(mga_mmio_base + X_DATAREG); - writeb( XCOLMSK0GREEN, mga_mmio_base + PALWTADD); - colkey_mask[1]=(unsigned char)readb(mga_mmio_base + X_DATAREG); - writeb( XCOLMSK0BLUE, mga_mmio_base + PALWTADD); - colkey_mask[2]=(unsigned char)readb(mga_mmio_base + X_DATAREG); - writeb( XCOLMSK, mga_mmio_base + PALWTADD); - colkey_mask[3]=(unsigned char)readb(mga_mmio_base + X_DATAREG); - - printf("[mga] Saved colorkey (ON: %d %02X:%02X:%02X)\n", - colkey_on,colkey_color[0],colkey_color[1],colkey_color[2]); + //Make sure internal registers don't get updated until we're done + writel(BESGLOBCTL, (readl(VCOUNT)-1)<<16); - } - -if(!restore){ - writeb( XKEYOPMODE, mga_mmio_base + PALWTADD); - writeb( mga_grkey.ckey.op == CKEY_TRUE, mga_mmio_base + X_DATAREG); + // color or coordinate keying + + if (restore && colkey_saved) + { + // restore it + colkey_saved = 0; + + // Set color key registers: + writeb(PALWTADD, XKEYOPMODE); + writeb(X_DATAREG, colkey_on); + + writeb(PALWTADD, XCOLKEY0RED); + writeb(X_DATAREG, colkey_color[0]); + writeb(PALWTADD, XCOLKEY0GREEN); + writeb(X_DATAREG, colkey_color[1]); + writeb(PALWTADD, XCOLKEY0BLUE); + writeb(X_DATAREG, colkey_color[2]); + writeb(PALWTADD, X_COLKEY); + writeb(X_DATAREG, colkey_color[3]); + + writeb(PALWTADD, XCOLMSK0RED); + writeb(X_DATAREG, colkey_mask[0]); + writeb(PALWTADD, XCOLMSK0GREEN); + writeb(X_DATAREG, colkey_mask[1]); + writeb(PALWTADD, XCOLMSK0BLUE); + writeb(X_DATAREG, colkey_mask[2]); + writeb(PALWTADD, XCOLMSK); + writeb(X_DATAREG, colkey_mask[3]); + + printf(MGA_MSG" Restored colorkey (ON: %d %02X:%02X:%02X)\n", + colkey_on,colkey_color[0],colkey_color[1],colkey_color[2]); + + } else if (!colkey_saved) { + // save it + colkey_saved=1; + // Get color key registers: + writeb(PALWTADD, XKEYOPMODE); + colkey_on = readb(X_DATAREG) & 1; + + writeb(PALWTADD, XCOLKEY0RED); + colkey_color[0]=(unsigned char)readb(X_DATAREG); + writeb(PALWTADD, XCOLKEY0GREEN); + colkey_color[1]=(unsigned char)readb(X_DATAREG); + writeb(PALWTADD, XCOLKEY0BLUE); + colkey_color[2]=(unsigned char)readb(X_DATAREG); + writeb(PALWTADD, X_COLKEY); + colkey_color[3]=(unsigned char)readb(X_DATAREG); + + writeb(PALWTADD, XCOLMSK0RED); + colkey_mask[0]=(unsigned char)readb(X_DATAREG); + writeb(PALWTADD, XCOLMSK0GREEN); + colkey_mask[1]=(unsigned char)readb(X_DATAREG); + writeb(PALWTADD, XCOLMSK0BLUE); + colkey_mask[2]=(unsigned char)readb(X_DATAREG); + writeb(PALWTADD, XCOLMSK); + colkey_mask[3]=(unsigned char)readb(X_DATAREG); + + printf(MGA_MSG" Saved colorkey (ON: %d %02X:%02X:%02X)\n", + colkey_on,colkey_color[0],colkey_color[1],colkey_color[2]); + } + + if (!restore) + { + writeb(PALWTADD, XKEYOPMODE); + writeb(X_DATAREG, (mga_grkey.ckey.op == CKEY_TRUE)); if ( mga_grkey.ckey.op == CKEY_TRUE ) { - uint32_t r=0, g=0, b=0; - - writeb( XMULCTRL, mga_mmio_base + PALWTADD); - switch (readb (mga_mmio_base + X_DATAREG)) - { - case BPP_8: - /* Need to look up the color index, just using - color 0 for now. */ - break; - - case BPP_15: - r = mga_grkey.ckey.red >> 3; - g = mga_grkey.ckey.green >> 3; - b = mga_grkey.ckey.blue >> 3; - break; - - case BPP_16: - r = mga_grkey.ckey.red >> 3; - g = mga_grkey.ckey.green >> 2; - b = mga_grkey.ckey.blue >> 3; - break; - - case BPP_24: - case BPP_32_DIR: - case BPP_32_PAL: - r = mga_grkey.ckey.red; - g = mga_grkey.ckey.green; - b = mga_grkey.ckey.blue; - break; - } + uint32_t r=0, g=0, b=0; + + writeb(PALWTADD, XMULCTRL); + switch (readb(X_DATAREG)) + { + case BPP_8: + /* Need to look up the color index, just using + color 0 for now. */ + break; + case BPP_15: + r = mga_grkey.ckey.red >> 3; + g = mga_grkey.ckey.green >> 3; + b = mga_grkey.ckey.blue >> 3; + break; + case BPP_16: + r = mga_grkey.ckey.red >> 3; + g = mga_grkey.ckey.green >> 2; + b = mga_grkey.ckey.blue >> 3; + break; + case BPP_24: + case BPP_32_DIR: + case BPP_32_PAL: + r = mga_grkey.ckey.red; + g = mga_grkey.ckey.green; + b = mga_grkey.ckey.blue; + break; + } - // Disable color keying on alpha channel - writeb( XCOLMSK, mga_mmio_base + PALWTADD); - writeb( 0x00, mga_mmio_base + X_DATAREG); - writeb( X_COLKEY, mga_mmio_base + PALWTADD); - writeb( 0x00, mga_mmio_base + X_DATAREG); - - - // Set up color key registers - writeb( XCOLKEY0RED, mga_mmio_base + PALWTADD); - writeb( r, mga_mmio_base + X_DATAREG); - writeb( XCOLKEY0GREEN, mga_mmio_base + PALWTADD); - writeb( g, mga_mmio_base + X_DATAREG); - writeb( XCOLKEY0BLUE, mga_mmio_base + PALWTADD); - writeb( b, mga_mmio_base + X_DATAREG); - - // Set up color key mask registers - writeb( XCOLMSK0RED, mga_mmio_base + PALWTADD); - writeb( 0xff, mga_mmio_base + X_DATAREG); - writeb( XCOLMSK0GREEN, mga_mmio_base + PALWTADD); - writeb( 0xff, mga_mmio_base + X_DATAREG); - writeb( XCOLMSK0BLUE, mga_mmio_base + PALWTADD); - writeb( 0xff, mga_mmio_base + X_DATAREG); + // Disable color keying on alpha channel + writeb(PALWTADD, XCOLMSK); + writeb(X_DATAREG, 0x00); + writeb(PALWTADD, X_COLKEY); + writeb(X_DATAREG, 0x00); + + + // Set up color key registers + writeb(PALWTADD, XCOLKEY0RED); + writeb(X_DATAREG, r); + writeb(PALWTADD, XCOLKEY0GREEN); + writeb(X_DATAREG, g); + writeb(PALWTADD, XCOLKEY0BLUE); + writeb(X_DATAREG, b); + + // Set up color key mask registers + writeb(PALWTADD, XCOLMSK0RED); + writeb(X_DATAREG, 0xff); + writeb(PALWTADD, XCOLMSK0GREEN); + writeb(X_DATAREG, 0xff); + writeb(PALWTADD, XCOLMSK0BLUE); + writeb(X_DATAREG, 0xff); } + } -} + // Backend Scaler + writel(BESCTL, regs.besctl); + if (is_g400) + writel(BESLUMACTL, regs.beslumactl); + writel(BESPITCH, regs.bespitch); + + writel(BESA1ORG, regs.besa1org); + writel(BESA1CORG, regs.besa1corg); + writel(BESA2ORG, regs.besa2org); + writel(BESA2CORG, regs.besa2corg); + writel(BESB1ORG, regs.besb1org); + writel(BESB1CORG, regs.besb1corg); + writel(BESB2ORG, regs.besb2org); + writel(BESB2CORG, regs.besb2corg); + if(is_g400) + { + writel(BESA1C3ORG, regs.besa1c3org); + writel(BESA2C3ORG, regs.besa2c3org); + writel(BESB1C3ORG, regs.besb1c3org); + writel(BESB2C3ORG, regs.besb2c3org); + } - // Backend Scaler - writel( regs.besctl, mga_mmio_base + BESCTL); - if(is_g400) - writel( regs.beslumactl, mga_mmio_base + BESLUMACTL); - writel( regs.bespitch, mga_mmio_base + BESPITCH); - - writel( regs.besa1org, mga_mmio_base + BESA1ORG); - writel( regs.besa1corg, mga_mmio_base + BESA1CORG); - writel( regs.besa2org, mga_mmio_base + BESA2ORG); - writel( regs.besa2corg, mga_mmio_base + BESA2CORG); - writel( regs.besb1org, mga_mmio_base + BESB1ORG); - writel( regs.besb1corg, mga_mmio_base + BESB1CORG); - writel( regs.besb2org, mga_mmio_base + BESB2ORG); - writel( regs.besb2corg, mga_mmio_base + BESB2CORG); - if(is_g400) - { - writel( regs.besa1c3org, mga_mmio_base + BESA1C3ORG); - writel( regs.besa2c3org, mga_mmio_base + BESA2C3ORG); - writel( regs.besb1c3org, mga_mmio_base + BESB1C3ORG); - writel( regs.besb2c3org, mga_mmio_base + BESB2C3ORG); - } + writel(BESHCOORD, regs.beshcoord); + writel(BESHISCAL, regs.beshiscal); + writel(BESHSRCST, regs.beshsrcst); + writel(BESHSRCEND, regs.beshsrcend); + writel(BESHSRCLST, regs.beshsrclst); - writel( regs.beshcoord, mga_mmio_base + BESHCOORD); - writel( regs.beshiscal, mga_mmio_base + BESHISCAL); - writel( regs.beshsrcst, mga_mmio_base + BESHSRCST); - writel( regs.beshsrcend, mga_mmio_base + BESHSRCEND); - writel( regs.beshsrclst, mga_mmio_base + BESHSRCLST); - - writel( regs.besvcoord, mga_mmio_base + BESVCOORD); - writel( regs.besviscal, mga_mmio_base + BESVISCAL); - - writel( regs.besv1srclst, mga_mmio_base + BESV1SRCLST); - writel( regs.besv1wght, mga_mmio_base + BESV1WGHT); - writel( regs.besv2srclst, mga_mmio_base + BESV2SRCLST); - writel( regs.besv2wght, mga_mmio_base + BESV2WGHT); - - //update the registers somewhere between 1 and 2 frames from now. - writel( regs.besglobctl + ((readl(mga_mmio_base + VCOUNT)+2)<<16), - mga_mmio_base + BESGLOBCTL); + writel(BESVCOORD, regs.besvcoord); + writel(BESVISCAL, regs.besviscal); - if (mga_verbose > 1) - { - printf("[mga] wrote BES registers\n"); - printf("[mga] BESCTL = 0x%08x\n", - readl(mga_mmio_base + BESCTL)); - printf("[mga] BESGLOBCTL = 0x%08x\n", - readl(mga_mmio_base + BESGLOBCTL)); - printf("[mga] BESSTATUS= 0x%08x\n", - readl(mga_mmio_base + BESSTATUS)); - } + writel(BESV1SRCLST, regs.besv1srclst); + writel(BESV1WGHT, regs.besv1wght); + writel(BESV2SRCLST, regs.besv2srclst); + writel(BESV2WGHT, regs.besv2wght); + + //update the registers somewhere between 1 and 2 frames from now. + writel(BESGLOBCTL, regs.besglobctl + ((readl(VCOUNT)+2)<<16)); + + if (mga_verbose > 1) + { + printf(MGA_MSG" wrote BES registers\n"); + printf(MGA_MSG" BESCTL = 0x%08x\n", readl(BESCTL)); + printf(MGA_MSG" BESGLOBCTL = 0x%08x\n", readl(BESGLOBCTL)); + printf(MGA_MSG" BESSTATUS= 0x%08x\n", readl(BESSTATUS)); + } #ifdef CRTC2 -// printf("c2ctl:0x%08x c2datactl:0x%08x\n",readl(mga_mmio_base + C2CTL),readl(mga_mmio_base + C2DATACTL)); -// printf("c2misc:0x%08x\n",readl(mga_mmio_base + C2MISC)); -// printf("c2ctl:0x%08x c2datactl:0x%08x\n",cregs.c2ctl,cregs.c2datactl); - -// writel(cregs.c2ctl, mga_mmio_base + C2CTL); - - writel(((readl(mga_mmio_base + C2CTL) & ~0x03e00000) + (cregs.c2ctl & 0x03e00000)), mga_mmio_base + C2CTL); - writel(((readl(mga_mmio_base + C2DATACTL) & ~0x000000ff) + (cregs.c2datactl & 0x000000ff)), mga_mmio_base + C2DATACTL); - // ctrc2 - // disable CRTC2 acording to specs -// writel(cregs.c2ctl & 0xfffffff0, mga_mmio_base + C2CTL); - // je to treba ??? -// writeb((readb(mga_mmio_base + XMISCCTRL) & 0x19) | 0xa2, mga_mmio_base + XMISCCTRL); // MAFC - mfcsel & vdoutsel -// writeb((readb(mga_mmio_base + XMISCCTRL) & 0x19) | 0x92, mga_mmio_base + XMISCCTRL); -// writeb((readb(mga_mmio_base + XMISCCTRL) & ~0xe9) + 0xa2, mga_mmio_base + XMISCCTRL); -// writel(cregs.c2datactl, mga_mmio_base + C2DATACTL); -// writel(cregs.c2hparam, mga_mmio_base + C2HPARAM); -// writel(cregs.c2hsync, mga_mmio_base + C2HSYNC); -// writel(cregs.c2vparam, mga_mmio_base + C2VPARAM); -// writel(cregs.c2vsync, mga_mmio_base + C2VSYNC); - writel(cregs.c2misc, mga_mmio_base + C2MISC); - - if (mga_verbose > 1) printf("[mga] c2offset = %d\n",cregs.c2offset); - - writel(cregs.c2offset, mga_mmio_base + C2OFFSET); - writel(cregs.c2startadd0, mga_mmio_base + C2STARTADD0); -// writel(cregs.c2startadd1, mga_mmio_base + C2STARTADD1); - writel(cregs.c2pl2startadd0, mga_mmio_base + C2PL2STARTADD0); -// writel(cregs.c2pl2startadd1, mga_mmio_base + C2PL2STARTADD1); - writel(cregs.c2pl3startadd0, mga_mmio_base + C2PL3STARTADD0); -// writel(cregs.c2pl3startadd1, mga_mmio_base + C2PL3STARTADD1); - writel(cregs.c2spicstartadd0, mga_mmio_base + C2SPICSTARTADD0); -// writel(cregs.c2spicstartadd1, mga_mmio_base + C2SPICSTARTADD1); -// writel(cregs.c2subpiclut, mga_mmio_base + C2SUBPICLUT); -// writel(cregs.c2preload, mga_mmio_base + C2PRELOAD); - // finaly enable everything -// writel(cregs.c2ctl, mga_mmio_base + C2CTL); -// printf("c2ctl:0x%08x c2datactl:0x%08x\n",readl(mga_mmio_base + C2CTL),readl(mga_mmio_base + C2DATACTL)); -// printf("c2misc:0x%08x\n", readl(mga_mmio_base + C2MISC)); -#endif + if (cregs_save.c2ctl == 0) + { + //int i; + cregs_save.c2ctl = readl(C2CTL); + cregs_save.c2datactl = readl(C2DATACTL); + cregs_save.c2misc = readl(C2MISC); + + //for (i = 0; i <= 8; i++) { writeb(CRTCEXTX, i); printf("CRTCEXT%d %x\n", i, readb(CRTCEXTD)); } + //printf("c2ctl:0x%08x c2datactl:0x%08x\n", cregs_save.c2ctl, cregs_save.c2datactl); + //printf("c2misc:0x%08x\n", readl(C2MISC)); + //printf("c2ctl:0x%08x c2datactl:0x%08x\n", cregs.c2ctl, cregs.c2datactl); + } + if (restore) + { + writel(C2CTL, cregs_save.c2ctl); + writel(C2DATACTL, cregs_save.c2datactl); + writel(C2MISC, cregs_save.c2misc); + return; + } + // writel(C2CTL, cregs.c2ctl); + + writel(C2CTL, ((readl(C2CTL) & ~0x03e00000) + (cregs.c2ctl & 0x03e00000))); + writel(C2DATACTL, ((readl(C2DATACTL) & ~0x000000ff) + (cregs.c2datactl & 0x000000ff))); + // ctrc2 + // disable CRTC2 acording to specs + // writel(C2CTL, cregs.c2ctl & 0xfffffff0); + // je to treba ??? + // writeb(XMISCCTRL, (readb(XMISCCTRL) & 0x19) | 0xa2); // MAFC - mfcsel & vdoutsel + // writeb(XMISCCTRL, (readb(XMISCCTRL) & 0x19) | 0x92); + // writeb(XMISCCTRL, (readb(XMISCCTRL) & ~0xe9) + 0xa2); + writel(C2DATACTL, cregs.c2datactl); + writel(C2HPARAM, cregs.c2hparam); + writel(C2HSYNC, cregs.c2hsync); + writel(C2VPARAM, cregs.c2vparam); + writel(C2VSYNC, cregs.c2vsync); + //xx + //writel(C2MISC, cregs.c2misc); + + if (mga_verbose > 1) printf(MGA_MSG" c2offset = %d\n", cregs.c2offset); + + writel(C2OFFSET, cregs.c2offset); + writel(C2STARTADD0, cregs.c2startadd0); + // writel(C2STARTADD1, cregs.c2startadd1); + writel(C2PL2STARTADD0, cregs.c2pl2startadd0); + // writel(C2PL2STARTADD1, cregs.c2pl2startadd1); + writel(C2PL3STARTADD0, cregs.c2pl3startadd0); + // writel(C2PL3STARTADD1, cregs.c2pl3startadd1); + writel(C2SPICSTARTADD0, cregs.c2spicstartadd0); + + //xx + //writel(C2SPICSTARTADD1, cregs.c2spicstartadd1); + //writel(C2SUBPICLUT, cregs.c2subpiclut); + //writel(C2PRELOAD, cregs.c2preload); + + // finaly enable everything + writel(C2CTL, cregs.c2ctl); + // printf("c2ctl:0x%08x c2datactl:0x%08x\n",readl(C2CTL), readl(C2DATACTL)); + // printf("c2misc:0x%08x\n", readl(C2MISC)); +#endif } #ifdef MGA_ALLOW_IRQ -static void enable_irq(){ - long int cc; - - cc = readl(mga_mmio_base + IEN); -// printf("*** !!! IRQREG = %d\n", (int)(cc&0xff)); - - writeb( 0x11, mga_mmio_base + CRTCX); - - writeb(0x20, mga_mmio_base + CRTCD ); /* clear 0, enable off */ - writeb(0x00, mga_mmio_base + CRTCD ); /* enable on */ - writeb(0x10, mga_mmio_base + CRTCD ); /* clear = 1 */ - - writel( regs.besglobctl , mga_mmio_base + BESGLOBCTL); - - return; +static void enable_irq() +{ + long int cc; + + cc = readl(IEN); + // printf("*** !!! IRQREG = %d\n", (int)(cc&0xff)); + + writeb(CRTCX, 0x11); + + writeb(CRTCD, 0x20); /* clear 0, enable off */ + writeb(CRTCD, 0x00); /* enable on */ + writeb(CRTCD, 0x10); /* clear = 1 */ + + writel(BESGLOBCTL, regs.besglobctl); + + return; } static void disable_irq() { - writeb( 0x11, mga_mmio_base + CRTCX); - writeb(0x20, mga_mmio_base + CRTCD ); /* clear 0, enable off */ + writeb(CRTCX, 0x11); + writeb(CRTCD, 0x20); /* clear 0, enable off */ - return; + return; } void mga_handle_irq(int irq, void *dev_id/*, struct pt_regs *pregs*/) { -// static int frame=0; -// static int counter=0; - long int cc; -// if ( ! mga_enabled_flag ) return; - -// printf("vcount = %d\n",readl(mga_mmio_base + VCOUNT)); + // static int frame=0; + // static int counter=0; + long int cc; + // if ( ! mga_enabled_flag ) return; - //printf("mga_interrupt #%d\n", irq); + // printf("vcount = %d\n",readl(VCOUNT)); - if ( irq != -1 ) { + //printf("mga_interrupt #%d\n", irq); - cc = readl(mga_mmio_base + STATUS); - if ( ! (cc & 0x10) ) return; /* vsyncpen */ -// debug_irqcnt++; - } + if ( irq != -1 ) { -// if ( debug_irqignore ) { -// debug_irqignore = 0; - - -/* - if ( mga_conf_deinterlace ) { - if ( mga_first_field ) { - // printf("mga_interrupt first field\n"); - if ( syncfb_interrupt() ) - mga_first_field = 0; - } else { - // printf("mga_interrupt second field\n"); - mga_select_buffer( mga_current_field | 2 ); - mga_first_field = 1; - } - } else { - syncfb_interrupt(); - } -*/ + cc = readl(STATUS); + if ( ! (cc & 0x10) ) return; /* vsyncpen */ + // debug_irqcnt++; + } -// frame=(frame+1)&1; - regs.besctl = (regs.besctl & ~0x07000000) + (mga_next_frame << 25); - writel( regs.besctl, mga_mmio_base + BESCTL ); + // if ( debug_irqignore ) { + // debug_irqignore = 0; + + /* + if ( mga_conf_deinterlace ) { + if ( mga_first_field ) { + // printf("mga_interrupt first field\n"); + if ( syncfb_interrupt() ) + mga_first_field = 0; + } else { + // printf("mga_interrupt second field\n"); + mga_select_buffer( mga_current_field | 2 ); + mga_first_field = 1; + } + } else { + syncfb_interrupt(); + } + */ + + // frame=(frame+1)&1; + regs.besctl = (regs.besctl & ~0x07000000) + (mga_next_frame << 25); + writel(BESCTL, regs.besctl); #ifdef CRTC2 -// sem pridat vyber obrazku !!!! - crtc2_frame_sel(mga_next_frame); + crtc2_frame_sel(mga_next_frame); #endif - + #if 0 - ++counter; - if(!(counter&63)){ - printf("mga irq counter = %d\n",counter); - } + ++counter; + if(!(counter&63)){ + printf("mga irq counter = %d\n",counter); + } #endif -// } else { -// debug_irqignore = 1; -// } - - if ( irq != -1 ) { - writeb( 0x11, mga_mmio_base + CRTCX); - writeb( 0, mga_mmio_base + CRTCD ); - writeb( 0x10, mga_mmio_base + CRTCD ); - } - -// writel( regs.besglobctl, mga_mmio_base + BESGLOBCTL); + // } else { + // debug_irqignore = 1; + // } + if ( irq != -1 ) { + writeb(CRTCX, 0x11); + writeb(CRTCD, 0); + writeb(CRTCD, 0x10); + } - return; + //writel(BESGLOBCTL, regs.besglobctl); } #endif /* MGA_ALLOW_IRQ */ -int vixConfigPlayback(vidix_playback_t *config) +int VIDIX_NAME(vixConfigPlayback)(vidix_playback_t *config) { - int i; - int x, y, sw, sh, dw, dh; - int besleft, bestop, ifactor, ofsleft, ofstop, baseadrofs, weight, weights; + unsigned int i; + int x, y, sw, sh, dw, dh; + int besleft, bestop, ifactor, ofsleft, ofstop, baseadrofs, weight, weights; #ifdef CRTC2 #define right_margin 0 #define left_margin 18 @@ -696,31 +716,31 @@ int vixConfigPlayback(vidix_playback_t *config) #define vsync_len 4 #define upper_margin 39 - unsigned int hdispend = (config->src.w + 31) & ~31; - unsigned int hsyncstart = hdispend + (right_margin & ~7); - unsigned int hsyncend = hsyncstart + (hsync_len & ~7); - unsigned int htotal = hsyncend + (left_margin & ~7); - unsigned int vdispend = config->src.h; - unsigned int vsyncstart = vdispend + lower_margin; - unsigned int vsyncend = vsyncstart + vsync_len; - unsigned int vtotal = vsyncend + upper_margin; -#endif + unsigned int hdispend = (config->src.w + 31) & ~31; + unsigned int hsyncstart = hdispend + (right_margin & ~7); + unsigned int hsyncend = hsyncstart + (hsync_len & ~7); + unsigned int htotal = hsyncend + (left_margin & ~7); + unsigned int vdispend = config->src.h; + unsigned int vsyncstart = vdispend + lower_margin; + unsigned int vsyncend = vsyncstart + vsync_len; + unsigned int vtotal = vsyncend + upper_margin; +#endif if ((config->num_frames < 1) || (config->num_frames > MGA_DEFAULT_FRAMES)) { - printf("[mga] illegal num_frames: %d, setting to %d\n", - config->num_frames, MGA_DEFAULT_FRAMES); + printf(MGA_MSG" illegal num_frames: %d, setting to %d\n", + config->num_frames, MGA_DEFAULT_FRAMES); config->num_frames = MGA_DEFAULT_FRAMES; } for(;config->num_frames>0;config->num_frames--) { /*FIXME: this driver can use more frames but we need to apply - some tricks to avoid RGB-memory hits*/ + some tricks to avoid RGB-memory hits*/ mga_src_base = ((mga_ram_size/2)*0x100000-config->num_frames*config->frame_size); mga_src_base &= (~0xFFFF); /* 64k boundary */ if(mga_src_base>=0) break; } - if (mga_verbose > 1) printf("[mga] YUV buffer base: %p\n", mga_src_base); + if (mga_verbose > 1) printf(MGA_MSG" YUV buffer base: 0x%x\n", mga_src_base); config->dga_addr = mga_mem_base + mga_src_base; @@ -730,45 +750,45 @@ int vixConfigPlayback(vidix_playback_t *config) sh = config->src.h; dw = config->dest.w; dh = config->dest.h; - + config->dest.pitch.y=32; config->dest.pitch.u=config->dest.pitch.v=16; - if (mga_verbose) printf("[mga] Setting up a %dx%d-%dx%d video window (src %dx%d) format %X\n", - dw, dh, x, y, sw, sh, config->fourcc); + if (mga_verbose) printf(MGA_MSG" Setting up a %dx%d-%dx%d video window (src %dx%d) format %X\n", + dw, dh, x, y, sw, sh, config->fourcc); if ((sw < 4) || (sh < 4) || (dw < 4) || (dh < 4)) { - printf("[mga] Invalid src/dest dimensions\n"); - return(EINVAL); + printf(MGA_MSG" Invalid src/dest dimensions\n"); + return(EINVAL); } //FIXME check that window is valid and inside desktop -// printf("[mga] vcount = %d\n", readl(mga_mmio_base + VCOUNT)); + // printf(MGA_MSG" vcount = %d\n", readl(VCOUNT)); - sw+=sw&1; + sw += sw & 1; switch(config->fourcc) { - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_YV12: - sh+=sh&1; - config->frame_size = ((sw + 31) & ~31) * sh + (((sw + 31) & ~31) * sh) / 2; - break; - case IMGFMT_YUY2: - case IMGFMT_UYVY: - config->frame_size = ((sw + 31) & ~31) * sh * 2; - break; - default: - printf("[mga] Unsupported pixel format: %x\n", config->fourcc); - return(ENOTSUP); + case IMGFMT_I420: + case IMGFMT_IYUV: + case IMGFMT_YV12: + sh+=sh&1; + config->frame_size = ((sw + 31) & ~31) * sh + (((sw + 31) & ~31) * sh) / 2; + break; + case IMGFMT_YUY2: + case IMGFMT_UYVY: + config->frame_size = ((sw + 31) & ~31) * sh * 2; + break; + default: + printf(MGA_MSG" Unsupported pixel format: %x\n", config->fourcc); + return(ENOTSUP); } config->offsets[0] = 0; -// config->offsets[1] = config->frame_size; -// config->offsets[2] = 2*config->frame_size; -// config->offsets[3] = 3*config->frame_size; + // config->offsets[1] = config->frame_size; + // config->offsets[2] = 2*config->frame_size; + // config->offsets[3] = 3*config->frame_size; for (i = 1; i < config->num_frames+1; i++) config->offsets[i] = i*config->frame_size; @@ -785,346 +805,345 @@ int vixConfigPlayback(vidix_playback_t *config) /* for G200 set Interleaved UV planes */ if (!is_g400) config->flags = VID_PLAY_INTERLEAVED_UV | INTERLEAVING_UV; - - //Setup the BES registers for a three plane 4:2:0 video source + + //Setup the BES registers for a three plane 4:2:0 video source regs.besglobctl = 0; switch(config->fourcc) { - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - regs.besctl = 1 // BES enabled - + (0<<6) // even start polarity - + (1<<10) // x filtering enabled - + (1<<11) // y filtering enabled - + (1<<16) // chroma upsampling - + (1<<17) // 4:2:0 mode - + (1<<18); // dither enabled + case IMGFMT_YV12: + case IMGFMT_I420: + case IMGFMT_IYUV: + regs.besctl = 1 // BES enabled + + (0<<6) // even start polarity + + (1<<10) // x filtering enabled + + (1<<11) // y filtering enabled + + (1<<16) // chroma upsampling + + (1<<17) // 4:2:0 mode + + (1<<18); // dither enabled #if 0 if(is_g400) { - //zoom disabled, zoom filter disabled, 420 3 plane format, proc amp - //disabled, rgb mode disabled - regs.besglobctl = (1<<5); + //zoom disabled, zoom filter disabled, 420 3 plane format, proc amp + //disabled, rgb mode disabled + regs.besglobctl = (1<<5); } else { - //zoom disabled, zoom filter disabled, Cb samples in 0246, Cr - //in 1357, BES register update on besvcnt - regs.besglobctl = 0; + //zoom disabled, zoom filter disabled, Cb samples in 0246, Cr + //in 1357, BES register update on besvcnt + regs.besglobctl = 0; } #endif - break; + break; - case IMGFMT_YUY2: - regs.besctl = 1 // BES enabled - + (0<<6) // even start polarity - + (1<<10) // x filtering enabled - + (1<<11) // y filtering enabled - + (1<<16) // chroma upsampling - + (0<<17) // 4:2:2 mode - + (1<<18); // dither enabled + case IMGFMT_YUY2: + regs.besctl = 1 // BES enabled + + (0<<6) // even start polarity + + (1<<10) // x filtering enabled + + (1<<11) // y filtering enabled + + (1<<16) // chroma upsampling + + (0<<17) // 4:2:2 mode + + (1<<18); // dither enabled regs.besglobctl = 0; // YUY2 format selected - break; + break; - case IMGFMT_UYVY: + case IMGFMT_UYVY: regs.besctl = 1 // BES enabled - + (0<<6) // even start polarity - + (1<<10) // x filtering enabled - + (1<<11) // y filtering enabled - + (1<<16) // chroma upsampling - + (0<<17) // 4:2:2 mode - + (1<<18); // dither enabled + + (0<<6) // even start polarity + + (1<<10) // x filtering enabled + + (1<<11) // y filtering enabled + + (1<<16) // chroma upsampling + + (0<<17) // 4:2:2 mode + + (1<<18); // dither enabled regs.besglobctl = 1<<6; // UYVY format selected - break; + break; } - //Disable contrast and brightness control - regs.besglobctl |= (1<<5) + (1<<7); - regs.beslumactl = (0x7f << 16) + (0x80<<0); - regs.beslumactl = 0x80<<0; - - //Setup destination window boundaries - besleft = x > 0 ? x : 0; - bestop = y > 0 ? y : 0; - regs.beshcoord = (besleft<<16) + (x + dw-1); - regs.besvcoord = (bestop<<16) + (y + dh-1); - - //Setup source dimensions - regs.beshsrclst = (sw - 1) << 16; - regs.bespitch = (sw + 31) & ~31 ; - - //Setup horizontal scaling - ifactor = ((sw-1)<<14)/(dw-1); - ofsleft = besleft - x; - - regs.beshiscal = ifactor<<2; - regs.beshsrcst = (ofsleft*ifactor)<<2; - regs.beshsrcend = regs.beshsrcst + (((dw - ofsleft - 1) * ifactor) << 2); - - //Setup vertical scaling - ifactor = ((sh-1)<<14)/(dh-1); - ofstop = bestop - y; - - regs.besviscal = ifactor<<2; - - baseadrofs = ((ofstop*regs.besviscal)>>16)*regs.bespitch; - //frame_size = ((sw + 31) & ~31) * sh + (((sw + 31) & ~31) * sh) / 2; - regs.besa1org = (uint32_t) mga_src_base + baseadrofs; - regs.besa2org = (uint32_t) mga_src_base + baseadrofs + 1*config->frame_size; - regs.besb1org = (uint32_t) mga_src_base + baseadrofs + 2*config->frame_size; - regs.besb2org = (uint32_t) mga_src_base + baseadrofs + 3*config->frame_size; - -if(config->fourcc==IMGFMT_YV12 - ||config->fourcc==IMGFMT_IYUV - ||config->fourcc==IMGFMT_I420 - ){ - // planar YUV frames: - if (is_g400) - baseadrofs = (((ofstop*regs.besviscal)/4)>>16)*regs.bespitch; - else - baseadrofs = (((ofstop*regs.besviscal)/2)>>16)*regs.bespitch; - - if(config->fourcc==IMGFMT_YV12){ - regs.besa1corg = (uint32_t) mga_src_base + baseadrofs + regs.bespitch * sh ; - regs.besa2corg = (uint32_t) mga_src_base + baseadrofs + 1*config->frame_size + regs.bespitch * sh; - regs.besb1corg = (uint32_t) mga_src_base + baseadrofs + 2*config->frame_size + regs.bespitch * sh; - regs.besb2corg = (uint32_t) mga_src_base + baseadrofs + 3*config->frame_size + regs.bespitch * sh; - regs.besa1c3org = regs.besa1corg + ((regs.bespitch * sh) / 4); - regs.besa2c3org = regs.besa2corg + ((regs.bespitch * sh) / 4); - regs.besb1c3org = regs.besb1corg + ((regs.bespitch * sh) / 4); - regs.besb2c3org = regs.besb2corg + ((regs.bespitch * sh) / 4); - } else { - regs.besa1c3org = (uint32_t) mga_src_base + baseadrofs + regs.bespitch * sh ; - regs.besa2c3org = (uint32_t) mga_src_base + baseadrofs + 1*config->frame_size + regs.bespitch * sh; - regs.besb1c3org = (uint32_t) mga_src_base + baseadrofs + 2*config->frame_size + regs.bespitch * sh; - regs.besb2c3org = (uint32_t) mga_src_base + baseadrofs + 3*config->frame_size + regs.bespitch * sh; - regs.besa1corg = regs.besa1c3org + ((regs.bespitch * sh) / 4); - regs.besa2corg = regs.besa2c3org + ((regs.bespitch * sh) / 4); - regs.besb1corg = regs.besb1c3org + ((regs.bespitch * sh) / 4); - regs.besb2corg = regs.besb2c3org + ((regs.bespitch * sh) / 4); + //Disable contrast and brightness control + regs.besglobctl |= (1<<5) + (1<<7); + // we want to preserver these across restarts + //regs.beslumactl = (0x0 << 16) + 0x80; + + //Setup destination window boundaries + besleft = x > 0 ? x : 0; + bestop = y > 0 ? y : 0; + regs.beshcoord = (besleft<<16) + (x + dw-1); + regs.besvcoord = (bestop<<16) + (y + dh-1); + + //Setup source dimensions + regs.beshsrclst = (sw - 1) << 16; + regs.bespitch = (sw + 31) & ~31 ; + + //Setup horizontal scaling + ifactor = ((sw-1)<<14)/(dw-1); + ofsleft = besleft - x; + + regs.beshiscal = ifactor<<2; + regs.beshsrcst = (ofsleft*ifactor)<<2; + regs.beshsrcend = regs.beshsrcst + (((dw - ofsleft - 1) * ifactor) << 2); + + //Setup vertical scaling + ifactor = ((sh-1)<<14)/(dh-1); + ofstop = bestop - y; + + regs.besviscal = ifactor<<2; + + baseadrofs = ((ofstop*regs.besviscal)>>16)*regs.bespitch; + //frame_size = ((sw + 31) & ~31) * sh + (((sw + 31) & ~31) * sh) / 2; + regs.besa1org = (uint32_t) mga_src_base + baseadrofs; + regs.besa2org = (uint32_t) mga_src_base + baseadrofs + 1*config->frame_size; + regs.besb1org = (uint32_t) mga_src_base + baseadrofs + 2*config->frame_size; + regs.besb2org = (uint32_t) mga_src_base + baseadrofs + 3*config->frame_size; + + if (config->fourcc == IMGFMT_YV12 + || config->fourcc == IMGFMT_IYUV + || config->fourcc == IMGFMT_I420) + { + // planar YUV frames: + if (is_g400) + baseadrofs = (((ofstop*regs.besviscal)/4)>>16)*regs.bespitch; + else + baseadrofs = (((ofstop*regs.besviscal)/2)>>16)*regs.bespitch; + + if (config->fourcc == IMGFMT_YV12){ + regs.besa1corg = (uint32_t) mga_src_base + baseadrofs + regs.bespitch * sh ; + regs.besa2corg = (uint32_t) mga_src_base + baseadrofs + 1*config->frame_size + regs.bespitch * sh; + regs.besb1corg = (uint32_t) mga_src_base + baseadrofs + 2*config->frame_size + regs.bespitch * sh; + regs.besb2corg = (uint32_t) mga_src_base + baseadrofs + 3*config->frame_size + regs.bespitch * sh; + regs.besa1c3org = regs.besa1corg + ((regs.bespitch * sh) / 4); + regs.besa2c3org = regs.besa2corg + ((regs.bespitch * sh) / 4); + regs.besb1c3org = regs.besb1corg + ((regs.bespitch * sh) / 4); + regs.besb2c3org = regs.besb2corg + ((regs.bespitch * sh) / 4); + } else { + regs.besa1c3org = (uint32_t) mga_src_base + baseadrofs + regs.bespitch * sh ; + regs.besa2c3org = (uint32_t) mga_src_base + baseadrofs + 1*config->frame_size + regs.bespitch * sh; + regs.besb1c3org = (uint32_t) mga_src_base + baseadrofs + 2*config->frame_size + regs.bespitch * sh; + regs.besb2c3org = (uint32_t) mga_src_base + baseadrofs + 3*config->frame_size + regs.bespitch * sh; + regs.besa1corg = regs.besa1c3org + ((regs.bespitch * sh) / 4); + regs.besa2corg = regs.besa2c3org + ((regs.bespitch * sh) / 4); + regs.besb1corg = regs.besb1c3org + ((regs.bespitch * sh) / 4); + regs.besb2corg = regs.besb2c3org + ((regs.bespitch * sh) / 4); + } } -} - weight = ofstop * (regs.besviscal >> 2); weights = weight < 0 ? 1 : 0; regs.besv2wght = regs.besv1wght = (weights << 16) + ((weight & 0x3FFF) << 2); regs.besv2srclst = regs.besv1srclst = sh - 1 - (((ofstop * regs.besviscal) >> 16) & 0x03FF); #ifdef CRTC2 - // pridat hlavni registry - tj. casovani ... + // pridat hlavni registry - tj. casovani ... -switch(config->fourcc){ - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: + switch(config->fourcc){ + case IMGFMT_YV12: + case IMGFMT_I420: + case IMGFMT_IYUV: cregs.c2ctl = 1 // CRTC2 enabled - + (1<<1) // external clock - + (0<<2) // external clock - + (1<<3) // pixel clock enable - not needed ??? - + (0<<4) // high prioryty req - + (1<<5) // high prioryty req - + (0<<6) // high prioryty req - + (1<<8) // high prioryty req max - + (0<<9) // high prioryty req max - + (0<<10) // high prioryty req max - + (0<<20) // CRTC1 to DAC - + (1<<21) // 420 mode - + (1<<22) // 420 mode - + (1<<23) // 420 mode - + (0<<24) // single chroma line for 420 mode - need to be corrected - + (0<<25) /*/ interlace mode - need to be corrected*/ - + (0<<26) // field legth polariry - + (0<<27) // field identification polariry - + (1<<28) // VIDRST detection mode - + (0<<29) // VIDRST detection mode - + (1<<30) // Horizontal counter preload - + (1<<31) // Vertical counter preload - ; + + (1<<1) // external clock + + (0<<2) // external clock + + (1<<3) // pixel clock enable - not needed ??? + + (0<<4) // high priority req + + (1<<5) // high priority req + + (0<<6) // high priority req + + (1<<8) // high priority req max + + (0<<9) // high priority req max + + (0<<10) // high priority req max + + (0<<20) // CRTC1 to DAC + + (1<<21) // 420 mode + + (1<<22) // 420 mode + + (1<<23) // 420 mode + + (0<<24) // single chroma line for 420 mode - need to be corrected + + (0<<25) /*/ interlace mode - need to be corrected*/ + + (0<<26) // field legth polariry + + (0<<27) // field identification polariry + + (1<<28) // VIDRST detection mode + + (0<<29) // VIDRST detection mode + + (1<<30) // Horizontal counter preload + + (1<<31) // Vertical counter preload + ; cregs.c2datactl = 1 // disable dither - propably not needed, we are already in YUV mode - + (1<<1) // Y filter enable - + (1<<2) // CbCr filter enable - + (0<<3) // subpicture enable (disabled) - + (0<<4) // NTSC enable (disabled - PAL) - + (0<<5) // C2 static subpicture enable (disabled) - + (0<<6) // C2 subpicture offset division (disabled) - + (0<<7) // 422 subformat selection ! -/* + (0<<8) // 15 bpp high alpha - + (0<<9) // 15 bpp high alpha - + (0<<10) // 15 bpp high alpha - + (0<<11) // 15 bpp high alpha - + (0<<12) // 15 bpp high alpha - + (0<<13) // 15 bpp high alpha - + (0<<14) // 15 bpp high alpha - + (0<<15) // 15 bpp high alpha - + (0<<16) // 15 bpp low alpha - + (0<<17) // 15 bpp low alpha - + (0<<18) // 15 bpp low alpha - + (0<<19) // 15 bpp low alpha - + (0<<20) // 15 bpp low alpha - + (0<<21) // 15 bpp low alpha - + (0<<22) // 15 bpp low alpha - + (0<<23) // 15 bpp low alpha - + (0<<24) // static subpicture key - + (0<<25) // static subpicture key - + (0<<26) // static subpicture key - + (0<<27) // static subpicture key - + (0<<28) // static subpicture key -*/ ; - break; - - case IMGFMT_YUY2: + + (1<<1) // Y filter enable + + (1<<2) // CbCr filter enable + + (0<<3) // subpicture enable (disabled) + + (0<<4) // NTSC enable (disabled - PAL) + + (0<<5) // C2 static subpicture enable (disabled) + + (0<<6) // C2 subpicture offset division (disabled) + + (0<<7) // 422 subformat selection ! + /* + (0<<8) // 15 bpp high alpha + + (0<<9) // 15 bpp high alpha + + (0<<10) // 15 bpp high alpha + + (0<<11) // 15 bpp high alpha + + (0<<12) // 15 bpp high alpha + + (0<<13) // 15 bpp high alpha + + (0<<14) // 15 bpp high alpha + + (0<<15) // 15 bpp high alpha + + (0<<16) // 15 bpp low alpha + + (0<<17) // 15 bpp low alpha + + (0<<18) // 15 bpp low alpha + + (0<<19) // 15 bpp low alpha + + (0<<20) // 15 bpp low alpha + + (0<<21) // 15 bpp low alpha + + (0<<22) // 15 bpp low alpha + + (0<<23) // 15 bpp low alpha + + (0<<24) // static subpicture key + + (0<<25) // static subpicture key + + (0<<26) // static subpicture key + + (0<<27) // static subpicture key + + (0<<28) // static subpicture key + */ ; + break; + + case IMGFMT_YUY2: cregs.c2ctl = 1 // CRTC2 enabled - + (1<<1) // external clock - + (0<<2) // external clock - + (1<<3) // pixel clock enable - not needed ??? - + (0<<4) // high prioryty req - acc to spec - + (1<<5) // high prioryty req - + (0<<6) // high prioryty req - // 7 reserved - + (1<<8) // high prioryty req max - + (0<<9) // high prioryty req max - + (0<<10) // high prioryty req max - // 11-19 reserved - + (0<<20) // CRTC1 to DAC - + (1<<21) // 422 mode - + (0<<22) // 422 mode - + (1<<23) // 422 mode - + (0<<24) // single chroma line for 420 mode - need to be corrected - + (0<<25) /*/ interlace mode - need to be corrected*/ - + (0<<26) // field legth polariry - + (0<<27) // field identification polariry - + (1<<28) // VIDRST detection mode - + (0<<29) // VIDRST detection mode - + (1<<30) // Horizontal counter preload - + (1<<31) // Vertical counter preload - ; + + (1<<1) // external clock + + (0<<2) // external clock + + (1<<3) // pixel clock enable - not needed ??? + + (0<<4) // high priority req - acc to spec + + (1<<5) // high priority req + + (0<<6) // high priority req + // 7 reserved + + (1<<8) // high priority req max + + (0<<9) // high priority req max + + (0<<10) // high priority req max + // 11-19 reserved + + (0<<20) // CRTC1 to DAC + + (1<<21) // 422 mode + + (0<<22) // 422 mode + + (1<<23) // 422 mode + + (0<<24) // single chroma line for 420 mode - need to be corrected + + (0<<25) /*/ interlace mode - need to be corrected*/ + + (0<<26) // field legth polariry + + (0<<27) // field identification polariry + + (1<<28) // VIDRST detection mode + + (0<<29) // VIDRST detection mode + + (1<<30) // Horizontal counter preload + + (1<<31) // Vertical counter preload + ; cregs.c2datactl = 1 // disable dither - propably not needed, we are already in YUV mode - + (1<<1) // Y filter enable - + (1<<2) // CbCr filter enable - + (0<<3) // subpicture enable (disabled) - + (0<<4) // NTSC enable (disabled - PAL) - + (0<<5) // C2 static subpicture enable (disabled) - + (0<<6) // C2 subpicture offset division (disabled) - + (0<<7) // 422 subformat selection ! -/* + (0<<8) // 15 bpp high alpha - + (0<<9) // 15 bpp high alpha - + (0<<10) // 15 bpp high alpha - + (0<<11) // 15 bpp high alpha - + (0<<12) // 15 bpp high alpha - + (0<<13) // 15 bpp high alpha - + (0<<14) // 15 bpp high alpha - + (0<<15) // 15 bpp high alpha - + (0<<16) // 15 bpp low alpha - + (0<<17) // 15 bpp low alpha - + (0<<18) // 15 bpp low alpha - + (0<<19) // 15 bpp low alpha - + (0<<20) // 15 bpp low alpha - + (0<<21) // 15 bpp low alpha - + (0<<22) // 15 bpp low alpha - + (0<<23) // 15 bpp low alpha - + (0<<24) // static subpicture key - + (0<<25) // static subpicture key - + (0<<26) // static subpicture key - + (0<<27) // static subpicture key - + (0<<28) // static subpicture key -*/ ; - break; - - case IMGFMT_UYVY: + + (1<<1) // Y filter enable + + (1<<2) // CbCr filter enable + + (0<<3) // subpicture enable (disabled) + + (0<<4) // NTSC enable (disabled - PAL) + + (0<<5) // C2 static subpicture enable (disabled) + + (0<<6) // C2 subpicture offset division (disabled) + + (0<<7) // 422 subformat selection ! + /* + (0<<8) // 15 bpp high alpha + + (0<<9) // 15 bpp high alpha + + (0<<10) // 15 bpp high alpha + + (0<<11) // 15 bpp high alpha + + (0<<12) // 15 bpp high alpha + + (0<<13) // 15 bpp high alpha + + (0<<14) // 15 bpp high alpha + + (0<<15) // 15 bpp high alpha + + (0<<16) // 15 bpp low alpha + + (0<<17) // 15 bpp low alpha + + (0<<18) // 15 bpp low alpha + + (0<<19) // 15 bpp low alpha + + (0<<20) // 15 bpp low alpha + + (0<<21) // 15 bpp low alpha + + (0<<22) // 15 bpp low alpha + + (0<<23) // 15 bpp low alpha + + (0<<24) // static subpicture key + + (0<<25) // static subpicture key + + (0<<26) // static subpicture key + + (0<<27) // static subpicture key + + (0<<28) // static subpicture key + */ ; + break; + + case IMGFMT_UYVY: cregs.c2ctl = 1 // CRTC2 enabled - + (1<<1) // external clock - + (0<<2) // external clock - + (1<<3) // pixel clock enable - not needed ??? - + (0<<4) // high prioryty req - + (1<<5) // high prioryty req - + (0<<6) // high prioryty req - + (1<<8) // high prioryty req max - + (0<<9) // high prioryty req max - + (0<<10) // high prioryty req max - + (0<<20) // CRTC1 to DAC - + (1<<21) // 422 mode - + (0<<22) // 422 mode - + (1<<23) // 422 mode - + (1<<24) // single chroma line for 420 mode - need to be corrected - + (1<<25) /*/ interlace mode - need to be corrected*/ - + (0<<26) // field legth polariry - + (0<<27) // field identification polariry - + (1<<28) // VIDRST detection mode - + (0<<29) // VIDRST detection mode - + (1<<30) // Horizontal counter preload - + (1<<31) // Vertical counter preload - ; + + (1<<1) // external clock + + (0<<2) // external clock + + (1<<3) // pixel clock enable - not needed ??? + + (0<<4) // high priority req + + (1<<5) // high priority req + + (0<<6) // high priority req + + (1<<8) // high priority req max + + (0<<9) // high priority req max + + (0<<10) // high priority req max + + (0<<20) // CRTC1 to DAC + + (1<<21) // 422 mode + + (0<<22) // 422 mode + + (1<<23) // 422 mode + + (1<<24) // single chroma line for 420 mode - need to be corrected + + (1<<25) /*/ interlace mode - need to be corrected*/ + + (0<<26) // field legth polariry + + (0<<27) // field identification polariry + + (1<<28) // VIDRST detection mode + + (0<<29) // VIDRST detection mode + + (1<<30) // Horizontal counter preload + + (1<<31) // Vertical counter preload + ; cregs.c2datactl = 0 // enable dither - propably not needed, we are already in YUV mode - + (1<<1) // Y filter enable - + (1<<2) // CbCr filter enable - + (0<<3) // subpicture enable (disabled) - + (0<<4) // NTSC enable (disabled - PAL) - + (0<<5) // C2 static subpicture enable (disabled) - + (0<<6) // C2 subpicture offset division (disabled) - + (1<<7) // 422 subformat selection ! -/* + (0<<8) // 15 bpp high alpha - + (0<<9) // 15 bpp high alpha - + (0<<10) // 15 bpp high alpha - + (0<<11) // 15 bpp high alpha - + (0<<12) // 15 bpp high alpha - + (0<<13) // 15 bpp high alpha - + (0<<14) // 15 bpp high alpha - + (0<<15) // 15 bpp high alpha - + (0<<16) // 15 bpp low alpha - + (0<<17) // 15 bpp low alpha - + (0<<18) // 15 bpp low alpha - + (0<<19) // 15 bpp low alpha - + (0<<20) // 15 bpp low alpha - + (0<<21) // 15 bpp low alpha - + (0<<22) // 15 bpp low alpha - + (0<<23) // 15 bpp low alpha - + (0<<24) // static subpicture key - + (0<<25) // static subpicture key - + (0<<26) // static subpicture key - + (0<<27) // static subpicture key - + (0<<28) // static subpicture key -*/ ; - break; + + (1<<1) // Y filter enable + + (1<<2) // CbCr filter enable + + (0<<3) // subpicture enable (disabled) + + (0<<4) // NTSC enable (disabled - PAL) + + (0<<5) // C2 static subpicture enable (disabled) + + (0<<6) // C2 subpicture offset division (disabled) + + (1<<7) // 422 subformat selection ! + /* + (0<<8) // 15 bpp high alpha + + (0<<9) // 15 bpp high alpha + + (0<<10) // 15 bpp high alpha + + (0<<11) // 15 bpp high alpha + + (0<<12) // 15 bpp high alpha + + (0<<13) // 15 bpp high alpha + + (0<<14) // 15 bpp high alpha + + (0<<15) // 15 bpp high alpha + + (0<<16) // 15 bpp low alpha + + (0<<17) // 15 bpp low alpha + + (0<<18) // 15 bpp low alpha + + (0<<19) // 15 bpp low alpha + + (0<<20) // 15 bpp low alpha + + (0<<21) // 15 bpp low alpha + + (0<<22) // 15 bpp low alpha + + (0<<23) // 15 bpp low alpha + + (0<<24) // static subpicture key + + (0<<25) // static subpicture key + + (0<<26) // static subpicture key + + (0<<27) // static subpicture key + + (0<<28) // static subpicture key + */ ; + break; } - cregs.c2hparam=((hdispend - 8) << 16) | (htotal - 8); - cregs.c2hsync=((hsyncend - 8) << 16) | (hsyncstart - 8); - - cregs.c2misc=0 // CRTCV2 656 togg f0 - +(0<<1) // CRTCV2 656 togg f0 - +(0<<2) // CRTCV2 656 togg f0 - +(0<<4) // CRTCV2 656 togg f1 - +(0<<5) // CRTCV2 656 togg f1 - +(0<<6) // CRTCV2 656 togg f1 - +(0<<8) // Hsync active high - +(0<<9) // Vsync active high - // 16-27 c2vlinecomp - nevim co tam dat - ; - cregs.c2offset=(regs.bespitch << 1); + cregs.c2hparam=((hdispend - 8) << 16) | (htotal - 8); + cregs.c2hsync=((hsyncend - 8) << 16) | (hsyncstart - 8); + + cregs.c2misc=0 // CRTCV2 656 togg f0 + +(0<<1) // CRTCV2 656 togg f0 + +(0<<2) // CRTCV2 656 togg f0 + +(0<<4) // CRTCV2 656 togg f1 + +(0<<5) // CRTCV2 656 togg f1 + +(0<<6) // CRTCV2 656 togg f1 + +(0<<8) // Hsync active high + +(0<<9) // Vsync active high + // 16-27 c2vlinecomp - nevim co tam dat + ; + cregs.c2offset=(regs.bespitch << 1); + + cregs.c2pl2startadd0=regs.besa1corg; + //cregs.c2pl2startadd1=regs.besa2corg; + cregs.c2pl3startadd0=regs.besa1c3org; + //cregs.c2pl3startadd1=regs.besa2c3org; + + cregs.c2preload=(vsyncstart << 16) | (hsyncstart); // from + + cregs.c2spicstartadd0=0; // not used + //cregs.c2spicstartadd1=0; // not used - cregs.c2pl2startadd0=regs.besa1corg; -// cregs.c2pl2startadd1=regs.besa2corg; - cregs.c2pl3startadd0=regs.besa1c3org; -// cregs.c2pl3startadd1=regs.besa2c3org; - - cregs.c2preload=(vsyncstart << 16) | (hsyncstart); // from - - cregs.c2spicstartadd0=0; // not used -// cregs.c2spicstartadd1=0; // not used - cregs.c2startadd0=regs.besa1org; -// cregs.c2startadd1=regs.besa2org; - + //cregs.c2startadd1=regs.besa2org; + cregs.c2subpiclut=0; //not used - + cregs.c2vparam=((vdispend - 1) << 16) | (vtotal - 1); cregs.c2vsync=((vsyncend - 1) << 16) | (vsyncstart - 1); #endif /* CRTC2 */ @@ -1133,15 +1152,15 @@ switch(config->fourcc){ return(0); } -int vixPlaybackOn(void) +int VIDIX_NAME(vixPlaybackOn)(void) { - if (mga_verbose) printf("[mga] playback on\n"); + if (mga_verbose) printf(MGA_MSG" playback on\n"); vid_src_ready = 1; if(vid_overlay_on) { regs.besctl |= 1; - mga_vid_write_regs(0); + mga_vid_write_regs(0); } #ifdef MGA_ALLOW_IRQ if (mga_irq != -1) @@ -1152,11 +1171,11 @@ int vixPlaybackOn(void) return(0); } -int vixPlaybackOff(void) +int VIDIX_NAME(vixPlaybackOff)(void) { - if (mga_verbose) printf("[mga] playback off\n"); + if (mga_verbose) printf(MGA_MSG" playback off\n"); - vid_src_ready = 0; + vid_src_ready = 0; #ifdef MGA_ALLOW_IRQ if (mga_irq != -1) disable_irq(); @@ -1168,152 +1187,155 @@ int vixPlaybackOff(void) return(0); } -int vixProbe(int verbose,int force) +int VIDIX_NAME(vixProbe)(int verbose,int force) { - pciinfo_t lst[MAX_PCI_DEVICES]; - unsigned int i, num_pci; - int err; + pciinfo_t lst[MAX_PCI_DEVICES]; + unsigned int i, num_pci; + int err; - if (verbose) printf("[mga] probe\n"); + if (verbose) printf(MGA_MSG" probe\n"); - mga_verbose = verbose; + mga_verbose = verbose; - is_g400 = -1; + is_g400 = -1; - err = pci_scan(&lst, &num_pci); - if (err) - { - printf("[mga] Error occured during pci scan: %s\n", strerror(err)); - return(err); - } + err = pci_scan(lst, &num_pci); + if (err) + { + printf(MGA_MSG" Error occured during pci scan: %s\n", strerror(err)); + return(err); + } + + if (mga_verbose) + printf(MGA_MSG" found %d pci devices\n", num_pci); - if (mga_verbose) - printf("[mga] found %d pci devices\n", num_pci); - - for (i = 0; i < num_pci; i++) + for (i = 0; i < num_pci; i++) + { + if (mga_verbose > 1) + printf(MGA_MSG" pci[%d] vendor: %d device: %d\n", + i, lst[i].vendor, lst[i].device); + if (lst[i].vendor == VENDOR_MATROX) { - if (mga_verbose > 1) - printf("[mga] pci[%d] vendor: %d device: %d\n", - i, lst[i].vendor, lst[i].device); - if (lst[i].vendor == VENDOR_MATROX) + switch(lst[i].device) { - switch(lst[i].device) - { - case DEVICE_MATROX_MGA_G550_AGP: - printf("[mga] Found MGA G550\n"); - is_g400 = 1; - goto card_found; - case DEVICE_MATROX_MGA_G400_AGP: - printf("[mga] Found MGA G400/G450\n"); - is_g400 = 1; - goto card_found; - case DEVICE_MATROX_MGA_G200_AGP: - printf("[mga] Found MGA G200 AGP\n"); - is_g400 = 0; - goto card_found; - case DEVICE_MATROX_MGA_G200: - printf("[mga] Found MGA G200 PCI\n"); - is_g400 = 0; - goto card_found; - } + case DEVICE_MATROX_MGA_G550_AGP: + printf(MGA_MSG" Found MGA G550\n"); + is_g400 = 1; + goto card_found; + case DEVICE_MATROX_MGA_G400_AGP: + printf(MGA_MSG" Found MGA G400/G450\n"); + is_g400 = 1; + goto card_found; + case DEVICE_MATROX_MGA_G200_AGP: + printf(MGA_MSG" Found MGA G200 AGP\n"); + is_g400 = 0; + goto card_found; + case DEVICE_MATROX_MGA_G200: + printf(MGA_MSG" Found MGA G200 PCI\n"); + is_g400 = 0; + goto card_found; } } + } - if (is_g400 == -1) - { - printf("[mga] No supported cards found\n"); - return(ENXIO); - } + if (is_g400 == -1) + { + printf(MGA_MSG" No supported cards found\n"); + return(ENXIO); + } card_found: - probed = 1; - memcpy(&pci_info, &lst[i], sizeof(pciinfo_t)); + probed = 1; + memcpy(&pci_info, &lst[i], sizeof(pciinfo_t)); - mga_cap.device_id = pci_info.device; /* set device id in capabilites */ + mga_cap.device_id = pci_info.device; /* set device id in capabilites */ - return(0); + return(0); } -int vixInit(void) +int VIDIX_NAME(vixInit)(const char *args) { unsigned int card_option = 0; int err; - - if (mga_verbose) printf("[mga] init\n"); + + /* reset Brightness & Constrast here */ + regs.beslumactl = (0x0 << 16) + 0x80; + + if (mga_verbose) printf(MGA_MSG" init\n"); mga_vid_in_use = 0; printf("Matrox MGA G200/G400/G450 YUV Video interface v2.01 (c) Aaron Holtzman & A'rpi\n"); -#ifdef CRCT2 +#ifdef CRTC2 printf("Driver compiled with TV-out (second-head) support\n"); #endif if (!probed) { - printf("[mga] driver was not probed but is being initializing\n"); + printf(MGA_MSG" driver was not probed but is being initializing\n"); return(EINTR); } #ifdef MGA_PCICONFIG_MEMDETECT pci_config_read(pci_info.bus, pci_info.card, pci_info.func, - 0x40, 4, &card_option); - if (mga_verbose > 1) printf("[mga] OPTION word: 0x%08X mem: 0x%02X %s\n", card_option, - (card_option>>10)&0x17, ((card_option>>14)&1)?"SGRAM":"SDRAM"); + 0x40, 4, &card_option); + if (mga_verbose > 1) printf(MGA_MSG" OPTION word: 0x%08X mem: 0x%02X %s\n", card_option, + (card_option>>10)&0x17, ((card_option>>14)&1)?"SGRAM":"SDRAM"); #endif if (mga_ram_size) { - printf("[mga] RAMSIZE forced to %d MB\n", mga_ram_size); + printf(MGA_MSG" RAMSIZE forced to %d MB\n", mga_ram_size); } else { #ifdef MGA_MEMORY_SIZE - mga_ram_size = MGA_MEMORY_SIZE; - printf("[mga] hard-coded RAMSIZE is %d MB\n", (unsigned int) mga_ram_size); + mga_ram_size = MGA_MEMORY_SIZE; + printf(MGA_MSG" hard-coded RAMSIZE is %d MB\n", (unsigned int) mga_ram_size); #else - if (is_g400) + if (is_g400) { switch((card_option>>10)&0x17) { - // SDRAM: - case 0x00: - case 0x04: mga_ram_size = 16; break; - case 0x03: mga_ram_size = 32; break; - // SGRAM: - case 0x10: - case 0x14: mga_ram_size = 32; break; - case 0x11: - case 0x12: mga_ram_size = 16; break; - default: - mga_ram_size = 16; - printf("[mga] Couldn't detect RAMSIZE, assuming 16MB!\n"); + // SDRAM: + case 0x00: + case 0x04: mga_ram_size = 16; break; + case 0x03: mga_ram_size = 32; break; + // SGRAM: + case 0x10: + case 0x14: mga_ram_size = 32; break; + case 0x11: + case 0x12: mga_ram_size = 16; break; + default: + mga_ram_size = 16; + printf(MGA_MSG" Couldn't detect RAMSIZE, assuming 16MB!\n"); } } else { switch((card_option>>10)&0x17) { -// case 0x10: -// case 0x13: mga_ram_size = 8; break; - default: mga_ram_size = 8; + // case 0x10: + // case 0x13: mga_ram_size = 8; break; + default: mga_ram_size = 8; } - } + } #if 0 -// printf("List resources -----------\n"); - for(temp=0;temp<DEVICE_COUNT_RESOURCE;temp++){ - struct resource *res=&pci_dev->resource[temp]; - if(res->flags){ - int size=(1+res->end-res->start)>>20; - printf("res %d: start: 0x%X end: 0x%X (%d MB) flags=0x%X\n",temp,res->start,res->end,size,res->flags); - if(res->flags&(IORESOURCE_MEM|IORESOURCE_PREFETCH)){ - if(size>mga_ram_size && size<=64) mga_ram_size=size; - } - } + // printf("List resources -----------\n"); + for(temp=0;temp<DEVICE_COUNT_RESOURCE;temp++){ + struct resource *res=&pci_dev->resource[temp]; + if(res->flags){ + int size=(1+res->end-res->start)>>20; + printf("res %d: start: 0x%X end: 0x%X (%d MB) flags=0x%X\n",temp,res->start,res->end,size,res->flags); + if(res->flags&(IORESOURCE_MEM|IORESOURCE_PREFETCH)){ + if(size>mga_ram_size && size<=64) mga_ram_size=size; + } } + } #endif - printf("[mga] detected RAMSIZE is %d MB\n", (unsigned int) mga_ram_size); + printf(MGA_MSG" detected RAMSIZE is %d MB\n", (unsigned int) mga_ram_size); #endif } @@ -1321,29 +1343,29 @@ int vixInit(void) { if ((mga_ram_size < 4) || (mga_ram_size > 64)) { - printf("[mga] invalid RAMSIZE: %d MB\n", mga_ram_size); + printf(MGA_MSG" invalid RAMSIZE: %d MB\n", mga_ram_size); return(EINVAL); } } - if (mga_verbose > 1) printf("[mga] hardware addresses: mmio: %p, framebuffer: %p\n", - pci_info.base1, pci_info.base0); + if (mga_verbose > 1) printf(MGA_MSG" hardware addresses: mmio: 0x%x, framebuffer: 0x%x\n", + pci_info.base1, pci_info.base0); mga_mmio_base = map_phys_mem(pci_info.base1,0x4000); mga_mem_base = map_phys_mem(pci_info.base0,mga_ram_size*1024*1024); - if (mga_verbose > 1) printf("[mga] MMIO at %p, IRQ: %d, framebuffer: %p\n", - mga_mmio_base, mga_irq, mga_mem_base); + if (mga_verbose > 1) printf(MGA_MSG" MMIO at %p, IRQ: %d, framebuffer: %p\n", + mga_mmio_base, mga_irq, mga_mem_base); err = mtrr_set_type(pci_info.base0,mga_ram_size*1024*1024,MTRR_TYPE_WRCOMB); - if(!err) printf("[mga] Set write-combining type of video memory\n"); + if(!err) printf(MGA_MSG" Set write-combining type of video memory\n"); #ifdef MGA_ALLOW_IRQ if (mga_irq != -1) { - int tmp = request_irq(mga_irq, mga_handle_irq, SA_INTERRUPT | SA_SHIRQ, "Syncfb Time Base", &mga_irq); - if (tmp) + int tmp = request_irq(mga_irq, mga_handle_irq, SA_INTERRUPT | SA_SHIRQ, "Syncfb Time Base", &mga_irq); + if (tmp) { - printf("syncfb (mga): cannot register irq %d (Err: %d)\n", mga_irq, tmp); - mga_irq=-1; + printf("syncfb (mga): cannot register irq %d (Err: %d)\n", mga_irq, tmp); + mga_irq=-1; } else { @@ -1356,133 +1378,141 @@ int vixInit(void) mga_irq=-1; } #else - printf("syncfb (mga): IRQ disabled in mga_vid.c\n"); - mga_irq=-1; + printf("syncfb (mga): IRQ disabled in mga_vid.c\n"); + mga_irq=-1; +#endif +#ifdef CRTC2 + memset(&cregs_save, 0, sizeof(cregs_save)); #endif - return(0); } -void vixDestroy(void) +void VIDIX_NAME(vixDestroy)(void) { - if (mga_verbose) printf("[mga] destroy\n"); + if (mga_verbose) printf(MGA_MSG" destroy\n"); /* FIXME turn off BES */ - vid_src_ready = 0; + vid_src_ready = 0; regs.besctl &= ~1; regs.besglobctl &= ~(1<<6); // UYVY format selected -// mga_config.colkey_on=0; //!!! + // mga_config.colkey_on=0; //!!! mga_vid_write_regs(1); mga_vid_in_use = 0; #ifdef MGA_ALLOW_IRQ if (mga_irq != -1) - free_irq(mga_irq, &mga_irq); + free_irq(mga_irq, &mga_irq); #endif if (mga_mmio_base) - unmap_phys_mem(mga_mmio_base, 0x4000); + unmap_phys_mem(mga_mmio_base, 0x4000); if (mga_mem_base) - unmap_phys_mem(mga_mem_base, mga_ram_size); + unmap_phys_mem(mga_mem_base, mga_ram_size); return; } -int vixQueryFourcc(vidix_fourcc_t *to) +int VIDIX_NAME(vixQueryFourcc)(vidix_fourcc_t *to) { int supports=0; - if (mga_verbose) printf("[mga] query fourcc (%x)\n", to->fourcc); + if (mga_verbose) printf(MGA_MSG" query fourcc (%x)\n", to->fourcc); switch(to->fourcc) { - case IMGFMT_YV12: - case IMGFMT_IYUV: - case IMGFMT_I420: - supports = is_g400 ? 1 : 0; - case IMGFMT_NV12: - supports = is_g400 ? 0 : 1; - case IMGFMT_YUY2: - case IMGFMT_UYVY: - supports = 1; - break; - default: - supports = 0; + case IMGFMT_YV12: + case IMGFMT_IYUV: + case IMGFMT_I420: + supports = is_g400 ? 1 : 0; + case IMGFMT_NV12: + supports = is_g400 ? 0 : 1; + case IMGFMT_YUY2: + case IMGFMT_UYVY: + supports = 1; + break; + default: + supports = 0; } - + if(!supports) { to->depth = to->flags = 0; return(ENOTSUP); } to->depth = VID_DEPTH_12BPP | - VID_DEPTH_15BPP | VID_DEPTH_16BPP | - VID_DEPTH_24BPP | VID_DEPTH_32BPP; + VID_DEPTH_15BPP | VID_DEPTH_16BPP | + VID_DEPTH_24BPP | VID_DEPTH_32BPP; to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY; return(0); } -unsigned int vixGetVersion(void) +unsigned int VIDIX_NAME(vixGetVersion)(void) { return(VIDIX_VERSION); } -int vixGetCapability(vidix_capability_t *to) +int VIDIX_NAME(vixGetCapability)(vidix_capability_t *to) { memcpy(to, &mga_cap, sizeof(vidix_capability_t)); return(0); } -int vixGetGrKeys(vidix_grkey_t *grkey) +int VIDIX_NAME(vixGetGrKeys)(vidix_grkey_t *grkey) { memcpy(grkey, &mga_grkey, sizeof(vidix_grkey_t)); return(0); } -int vixSetGrKeys(const vidix_grkey_t *grkey) +int VIDIX_NAME(vixSetGrKeys)(const vidix_grkey_t *grkey) { memcpy(&mga_grkey, grkey, sizeof(vidix_grkey_t)); return(0); } -int vixPlaybackSetEq( const vidix_video_eq_t * eq) +int VIDIX_NAME(vixPlaybackSetEq)( const vidix_video_eq_t * eq) { - uint32_t luma = 0; - float factor = 256.0 / 2000; + uint32_t luma; + float factor = 255.0 / 2000; /* contrast and brightness control isn't supported on G200 - alex */ if (!is_g400) { - if (mga_verbose) printf("[mga] equalizer isn't supported with G200\n"); + if (mga_verbose) printf(MGA_MSG" equalizer isn't supported with G200\n"); return(ENOTSUP); } - + + luma = regs.beslumactl; + if (eq->cap & VEQ_CAP_BRIGHTNESS) - luma += ((int)(eq->brightness * factor) << 16); + { + luma &= 0xffff; + luma |= (((int)(eq->brightness * factor) & 0xff) << 16); + } if (eq->cap & VEQ_CAP_CONTRAST) - luma += ((int)(eq->contrast * factor) & 0xFFFF); + { + luma &= 0xffff << 16; + luma |= ((int)((eq->contrast + 1000) * factor) & 0xff); + } - regs.beslumactl = luma+0x80; + regs.beslumactl = luma; - writel(regs.beslumactl,mga_mmio_base + BESLUMACTL); + writel(BESLUMACTL, regs.beslumactl); return(0); } -int vixPlaybackGetEq( vidix_video_eq_t * eq) +int VIDIX_NAME(vixPlaybackGetEq)( vidix_video_eq_t * eq) { - uint32_t luma; - float factor = 2000.0 / 256; + float factor = 2000.0 / 255; /* contrast and brightness control isn't supported on G200 - alex */ if (!is_g400) { - if (mga_verbose) printf("[mga] equalizer isn't supported with G200\n"); + if (mga_verbose) printf(MGA_MSG" equalizer isn't supported with G200\n"); return(ENOTSUP); } - regs.beslumactl = readl(mga_mmio_base + BESLUMACTL); - luma = regs.beslumactl-0x80; - - eq->brightness = (luma >> 16) * factor; - eq->contrast = (luma & 0xFFFF) * factor; + // BESLUMACTL is WO only registr! + // this will not work: regs.beslumactl = readl(BESLUMACTL); + eq->brightness = ((signed char)((regs.beslumactl >> 16) & 0xff)) * factor; + eq->contrast = (regs.beslumactl & 0xFF) * factor - 1000; eq->cap = VEQ_CAP_BRIGHTNESS | VEQ_CAP_CONTRAST; return(0); diff --git a/src/video_out/vidix/drivers/nvidia_vid.c b/src/video_out/vidix/drivers/nvidia_vid.c index 4f40fdd33..617a1f359 100644 --- a/src/video_out/vidix/drivers/nvidia_vid.c +++ b/src/video_out/vidix/drivers/nvidia_vid.c @@ -7,12 +7,14 @@ #include "vidix.h" #include "fourcc.h" -#include "libdha.h" -#include "pci_ids.h" -#include "pci_names.h" +#include "libdha/libdha.h" +#include "libdha/pci_ids.h" +#include "libdha/pci_names.h" #include "nvidia.h" +#define VIDIX_STATIC nvidia_ + static void *ctrl_base = 0; static void *fb_base = 0; static int32_t overlay_offset = 0; @@ -56,9 +58,9 @@ static const struct nv_card_id_s nv_card_id; static const struct nv_card_id_s nv_card_ids[]= { - { DEVICE_NVIDIA_RIVA_TNT2_NV5, "nVidia TNT2 (NV5) ", 5, CARD_FLAGS_NOTSUPPORTED}, - { DEVICE_NVIDIA_VANTA_NV6, "nVidia Vanta (NV6.1)", 6, CARD_FLAGS_NOTSUPPORTED}, - { DEVICE_NVIDIA_VANTA_NV62, "nVidia Vanta (NV6.2)", 6, CARD_FLAGS_NOTSUPPORTED} + { DEVICE_NVIDIA_NV5_RIVA_TNT2, "nVidia TNT2 (NV5) ", 5, CARD_FLAGS_NOTSUPPORTED}, + { DEVICE_NVIDIA_NV6_VANTA, "nVidia Vanta (NV6.1)", 6, CARD_FLAGS_NOTSUPPORTED}, + { DEVICE_NVIDIA_RIVA_TNT2_MODEL, "nVidia Vanta (NV6.2)", 6, CARD_FLAGS_NOTSUPPORTED} }; static int find_chip(unsigned int chip_id) @@ -93,12 +95,12 @@ static vidix_capability_t nvidia_cap = { 0, 0, 0, 0 } }; -unsigned int vixGetVersion(void) +unsigned int VIDIX_NAME(vixGetVersion)(void) { return(VIDIX_VERSION); } -int vixProbe(int verbose,int force) +int VIDIX_NAME(vixProbe)(int verbose,int force) { pciinfo_t lst[MAX_PCI_DEVICES]; unsigned int i, num_pci; @@ -158,7 +160,7 @@ int vixProbe(int verbose,int force) return(err); } -int vixInit(void) +int VIDIX_NAME(vixInit)(const char *args) { int card_option; @@ -255,18 +257,18 @@ int vixInit(void) return 0; } -void vixDestroy(void) +void VIDIX_NAME(vixDestroy)(void) { printf(NVIDIA_MSG"destory\n"); } -int vixGetCapability(vidix_capability_t *to) +int VIDIX_NAME(vixGetCapability)(vidix_capability_t *to) { memcpy(to, &nvidia_cap, sizeof(vidix_capability_t)); return(0); } -int vixQueryFourcc(vidix_fourcc_t *to) +int VIDIX_NAME(vixQueryFourcc)(vidix_fourcc_t *to) { printf(NVIDIA_MSG"query fourcc (%x)\n", to->fourcc); to->flags = 0; @@ -274,7 +276,7 @@ int vixQueryFourcc(vidix_fourcc_t *to) return 0; } -int vixConfigPlayback(vidix_playback_t *info) +int VIDIX_NAME(vixConfigPlayback)(vidix_playback_t *info) { int fb_pixel_size = 32/8; int fb_line_len = 1280*4; @@ -315,13 +317,13 @@ int vixConfigPlayback(vidix_playback_t *info) return 0; } -int vixPlaybackOn(void) +int VIDIX_NAME(vixPlaybackOn)(void) { printf(NVIDIA_MSG"playback on\n"); return 0; } -int vixPlaybackOff(void) +int VIDIX_NAME(vixPlaybackOff)(void) { printf(NVIDIA_MSG"playback off\n"); return 0; diff --git a/src/video_out/vidix/drivers/pm3_regs.h b/src/video_out/vidix/drivers/pm3_regs.h index 98f9b718a..44cc92dca 100644 --- a/src/video_out/vidix/drivers/pm3_regs.h +++ b/src/video_out/vidix/drivers/pm3_regs.h @@ -1,7 +1,7 @@ /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_regs.h,v 1.9 2001/11/20 00:09:15 alanh Exp $ */ /* - * glint register file + * glint register file * * Copyright by Sven Luther * Authors: Sven Luther, <luther@dpt-info.u-strasbg.fr> @@ -9,11 +9,17 @@ * * this work is sponsored by Appian Graphics. * - */ + */ #ifndef _PM3_REG_H_ #define _PM3_REG_H_ +#define PM3FIFOSize 120 + +#define PM3Tag(r) ((r>>3)&0x7ff) + +#define PM3OutputFIFO 0x2000 + /********************************************** * GLINT Permedia3 Control Status registers * ***********************************************/ @@ -90,7 +96,35 @@ #define PM3Aperture2YStart 0x0338 #define PM3Aperture2UStart 0x0340 #define PM3Aperture2VStart 0x0348 - + +#define PM3ByDMAReadCommandBase 0x0378 +#define PM3ByDMAReadCommandCount 0x0380 +#define PM3ByDMAReadMode 0x0350 + #define PM3ByDMAReadMode_ByteSwap_NONE (0<<0) + #define PM3ByDMAReadMode_ByteSwap_BYTE (1<<0) + #define PM3ByDMAReadMode_ByteSwap_HWORD (2<<0) + #define PM3ByDMAReadMode_ByteSwap_FULL (3<<0) + #define PM3ByDMAReadMode_PatchEnable (1<<2) + #define PM3ByDMAReadMode_Format_RAW (0<<3) + #define PM3ByDMAReadMode_Format_YUYV (1<<3) + #define PM3ByDMAReadMode_Format_UYVY (2<<3) + #define PM3ByDMAReadMode_PixelSize(s) (((s>>4)&3)<<5) + #define PM3ByDMAReadMode_EffectiveStride(s) ((s&3)<<7) + #define PM3ByDMAReadMode_PatchOffsetX(x) ((x&0x3f)<<9) + #define PM3ByDMAReadMode_PatchOffsetY(y) ((y&0x3f)<<16) + #define PM3ByDMAReadMode_Buffer_FB (0<<21) + #define PM3ByDMAReadMode_Buffer_LB (1<<21) + #define PM3ByDMAReadMode_Active (1<<22) + #define PM3ByDMAReadMode_MemType_PCI (0<<23) + #define PM3ByDMAReadMode_MemType_AGP (1<<23) + #define PM3ByDMAReadMode_Burst(b) ((b&7)<<24) + #define PM3ByDMAReadMode_Align (1<<27) +#define PM3ByDMAReadStride 0x0358 +#define PM3ByDMAReadUStart 0x0368 +#define PM3ByDMAReadVStart 0x0370 +#define PM3ByDMAReadYStart 0x0360 + + /********************************************** * GLINT Permedia3 Memory Control (0x1000) * ***********************************************/ @@ -520,8 +554,12 @@ #define PM3AntialiasMode 0x8808 #define PM3AntialiasModeAnd 0xac00 #define PM3AntialiasModeOr 0xac08 +#define PM3AreaStippleMode 0x81a0 /* ... */ #define PM3BackgroundColor 0xb0c8 +#define PM3BasePageOfWorkingSet 0xb4c8 +/* ... */ +#define PM3ChromaTestMode 0x8f18 /* ... */ #define PM3ColorDDAMode 0x87e0 #define PM3ColorDDAModeAnd 0xabe0 @@ -547,11 +585,41 @@ #define PM3DeltaMode 0x9300 #define PM3DeltaModeAnd 0xaad0 #define PM3DeltaModeOr 0xaad8 + +#define PM3DepthMode 0x89a0 /* ... */ #define PM3DitherMode 0x8818 #define PM3DitherModeAnd 0xacd0 #define PM3DitherModeOr 0xacd8 /* ... */ +#define PM3DMARectangleRead 0xa9a8 + #define PM3DMARectangleRead_Width(w) (w&0xfff) + #define PM3DMARectangleRead_Height(h) ((h&0xfff)<<12) + #define PM3DMARectangleRead_PixelSize(s) ((s&0x3)<<24) + #define PM3DMARectangleRead_Pack (1<<26) + #define PM3DMARectangleRead_ByteSwap(b) ((b&0x3)<<27) + #define PM3DMARectangleRead_Alignment (1<<30) +#define PM3DMARectangleReadAddress 0xa9b0 +#define PM3DMARectangleReadLinePitch 0xa9b8 +#define PM3DMARectangleReadTarget 0xa9c0 +/* ... */ +#define PM3DownloadAddress 0xb0d0 +#define PM3DownloadData 0xb0d8 +/* ... */ +#define PM3dBdx 0x87b8 +#define PM3dBdyDom 0x87c0 +#define PM3dGdx 0x87a0 +#define PM3dGdyDom 0x87a8 +#define PM3dQdx 0x83c0 +#define PM3dQdyDom 0x83c8 +#define PM3dRdx 0x8788 +#define PM3dRdyDom 0x8790 +#define PM3dSdx 0x8390 +#define PM3dSdy 0x83d8 +#define PM3dSdyDom 0x8398 +#define PM3dTdx 0x83a8 +#define PM3dTdy 0x83e0 +#define PM3dTdyDom 0x83b0 #define PM3dXDom 0x8008 #define PM3dXSub 0x8018 #define PM3dY 0x8028 @@ -587,47 +655,47 @@ #define PM3FBDestReadEnablesAnd 0xad20 #define PM3FBDestReadEnablesOr 0xad28 #define PM3FBDestReadEnables_E(e) ((e)&0xff) - #define PM3FBDestReadEnables_E0 1<<0 - #define PM3FBDestReadEnables_E1 1<<1 - #define PM3FBDestReadEnables_E2 1<<2 - #define PM3FBDestReadEnables_E3 1<<3 - #define PM3FBDestReadEnables_E4 1<<4 - #define PM3FBDestReadEnables_E5 1<<5 - #define PM3FBDestReadEnables_E6 1<<6 - #define PM3FBDestReadEnables_E7 1<<7 + #define PM3FBDestReadEnables_E0 (1<<0) + #define PM3FBDestReadEnables_E1 (1<<1) + #define PM3FBDestReadEnables_E2 (1<<2) + #define PM3FBDestReadEnables_E3 (1<<3) + #define PM3FBDestReadEnables_E4 (1<<4) + #define PM3FBDestReadEnables_E5 (1<<5) + #define PM3FBDestReadEnables_E6 (1<<6) + #define PM3FBDestReadEnables_E7 (1<<7) #define PM3FBDestReadEnables_R(r) (((r)&0xff)<<8) - #define PM3FBDestReadEnables_R0 1<<8 - #define PM3FBDestReadEnables_R1 1<<9 - #define PM3FBDestReadEnables_R2 1<<10 - #define PM3FBDestReadEnables_R3 1<<11 - #define PM3FBDestReadEnables_R4 1<<12 - #define PM3FBDestReadEnables_R5 1<<13 - #define PM3FBDestReadEnables_R6 1<<14 - #define PM3FBDestReadEnables_R7 1<<15 + #define PM3FBDestReadEnables_R0 (1<<8) + #define PM3FBDestReadEnables_R1 (1<<9) + #define PM3FBDestReadEnables_R2 (1<<10) + #define PM3FBDestReadEnables_R3 (1<<11) + #define PM3FBDestReadEnables_R4 (1<<12) + #define PM3FBDestReadEnables_R5 (1<<13) + #define PM3FBDestReadEnables_R6 (1<<14) + #define PM3FBDestReadEnables_R7 (1<<15) #define PM3FBDestReadEnables_ReferenceAlpha(a) (((a)&0xff)<<24) #define PM3FBDestReadMode 0xaee0 #define PM3FBDestReadModeAnd 0xac90 #define PM3FBDestReadModeOr 0xac98 - #define PM3FBDestReadMode_ReadDisable 0<<0 - #define PM3FBDestReadMode_ReadEnable 1<<0 + #define PM3FBDestReadMode_ReadDisable (0<<0) + #define PM3FBDestReadMode_ReadEnable (1<<0) #define PM3FBDestReadMode_StripePitch(sp) (((sp)&0x7)<<2) #define PM3FBDestReadMode_StripeHeight(sh) (((sh)&0x7)<<7) - #define PM3FBDestReadMode_Enable0 1<<8 - #define PM3FBDestReadMode_Enable1 1<<9 - #define PM3FBDestReadMode_Enable2 1<<10 - #define PM3FBDestReadMode_Enable3 1<<11 + #define PM3FBDestReadMode_Enable0 (1<<8) + #define PM3FBDestReadMode_Enable1 (1<<9) + #define PM3FBDestReadMode_Enable2 (1<<10) + #define PM3FBDestReadMode_Enable3 (1<<11) #define PM3FBDestReadMode_Layout0(l) (((l)&0x3)<<12) #define PM3FBDestReadMode_Layout1(l) (((l)&0x3)<<14) #define PM3FBDestReadMode_Layout2(l) (((l)&0x3)<<16) #define PM3FBDestReadMode_Layout3(l) (((l)&0x3)<<18) - #define PM3FBDestReadMode_Origin0 1<<20 - #define PM3FBDestReadMode_Origin1 1<<21 - #define PM3FBDestReadMode_Origin2 1<<22 - #define PM3FBDestReadMode_Origin3 1<<23 - #define PM3FBDestReadMode_Blocking 1<<24 - #define PM3FBDestReadMode_UseReadEnabled 1<<26 - #define PM3FBDestReadMode_AlphaFiltering 1<<27 + #define PM3FBDestReadMode_Origin0 (1<<20) + #define PM3FBDestReadMode_Origin1 (1<<21) + #define PM3FBDestReadMode_Origin2 (1<<22) + #define PM3FBDestReadMode_Origin3 (1<<23) + #define PM3FBDestReadMode_Blocking (1<<24) + #define PM3FBDestReadMode_UseReadEnabled (1<<26) + #define PM3FBDestReadMode_AlphaFiltering (1<<27) #define PM3FBHardwareWriteMask 0x8ac0 #define PM3FBSoftwareWriteMask 0x8820 @@ -647,14 +715,14 @@ #define PM3FBSourceReadMode_StripePitch(sp) (((sp)&0x7)<<2) #define PM3FBSourceReadMode_StripeHeight(sh) (((sh)&0x7)<<7) #define PM3FBSourceReadMode_Layout(l) (((l)&0x3)<<8) - #define PM3FBSourceReadMode_Origin 1<<10 - #define PM3FBSourceReadMode_Blocking 1<<11 - #define PM3FBSourceReadMode_UserTexelCoord 1<<13 - #define PM3FBSourceReadMode_WrapXEnable 1<<14 - #define PM3FBSourceReadMode_WrapYEnable 1<<15 + #define PM3FBSourceReadMode_Origin (1<<10) + #define PM3FBSourceReadMode_Blocking (1<<11) + #define PM3FBSourceReadMode_UseTexelCoord (1<<13) + #define PM3FBSourceReadMode_WrapXEnable (1<<14) + #define PM3FBSourceReadMode_WrapYEnable (1<<15) #define PM3FBSourceReadMode_WrapX(w) (((w)&0xf)<<16) #define PM3FBSourceReadMode_WrapY(w) (((w)&0xf)<<20) - #define PM3FBSourceReadMode_ExternalSourceData 1<<24 + #define PM3FBSourceReadMode_ExternalSourceData (1<<24) #define PM3FBWriteBufferAddr0 0xb000 #define PM3FBWriteBufferAddr1 0xb008 #define PM3FBWriteBufferAddr2 0xb010 @@ -694,12 +762,19 @@ #define PM3FBWriteMode_Origin1 1<<25 #define PM3FBWriteMode_Origin2 1<<26 #define PM3FBWriteMode_Origin3 1<<27 + +#define PM3FogMode 0x8690 #define PM3ForegroundColor 0xb0c0 /* ... */ #define PM3GIDMode 0xb538 #define PM3GIDModeAnd 0xb5b0 #define PM3GIDModeOr 0xb5b8 /* ... */ +#define PM3HeadPhysicalPageAllocation0 0xb480 +#define PM3HeadPhysicalPageAllocation1 0xb488 +#define PM3HeadPhysicalPageAllocation2 0xb490 +#define PM3HeadPhysicalPageAllocation3 0xb498 +/* ... */ #define PM3LBDestReadBufferAddr 0xb510 #define PM3LBDestReadBufferOffset 0xb518 #define PM3LBDestReadEnables 0xb508 @@ -708,14 +783,14 @@ #define PM3LBDestReadMode 0xb500 #define PM3LBDestReadModeAnd 0xb580 #define PM3LBDestReadModeOr 0xb588 - #define PM3LBDestReadMode_Disable 0<<0 - #define PM3LBDestReadMode_Enable 1<<0 + #define PM3LBDestReadMode_Disable (0<<0) + #define PM3LBDestReadMode_Enable (1<<0) #define PM3LBDestReadMode_StripePitch(p) (((p)&0x7)<<2) #define PM3LBDestReadMode_StripeHeight(h) (((h)&0x7)<<5) - #define PM3LBDestReadMode_Layout 1<<8 - #define PM3LBDestReadMode_Origin 1<<9 - #define PM3LBDestReadMode_UserReadEnables 1<<10 - #define PM3LBDestReadMode_Packed16 1<<11 + #define PM3LBDestReadMode_Layout (1<<8) + #define PM3LBDestReadMode_Origin (1<<9) + #define PM3LBDestReadMode_UserReadEnables (1<<10) + #define PM3LBDestReadMode_Packed16 (1<<11) #define PM3LBDestReadMode_Width(w) (((w)&0xfff)<<12) #define PM3LBReadFormat 0x8888 #define PM3LBReadFormat_DepthWidth(w) (((w)&0x3)<<0) @@ -730,12 +805,12 @@ #define PM3LBSourceReadMode 0xb520 #define PM3LBSourceReadModeAnd 0xb5a0 #define PM3LBSourceReadModeOr 0xb5a8 - #define PM3LBSourceReadMode_Enable 1<<0 + #define PM3LBSourceReadMode_Enable (1<<0) #define PM3LBSourceReadMode_StripePitch(p) (((p)&0x7)<<2) #define PM3LBSourceReadMode_StripeHeight(h) (((h)&0x7)<<5) - #define PM3LBSourceReadMode_Layout 1<<8 - #define PM3LBSourceReadMode_Origin 1<<9 - #define PM3LBSourceReadMode_Packed16 1<<10 + #define PM3LBSourceReadMode_Layout (1<<8) + #define PM3LBSourceReadMode_Origin (1<<9) + #define PM3LBSourceReadMode_Packed16 (1<<10) #define PM3LBSourceReadMode_Width(w) (((w)&0xfff)<<11) #define PM3LBStencil 0x88a8 #define PM3LBWriteBufferAddr 0xb540 @@ -749,13 +824,13 @@ #define PM3LBWriteMode 0x88c0 #define PM3LBWriteModeAnd 0xac80 #define PM3LBWriteModeOr 0xac88 - #define PM3LBWriteMode_WriteDisable 0<<0 - #define PM3LBWriteMode_WriteEnable 1<<0 + #define PM3LBWriteMode_WriteDisable (0<<0) + #define PM3LBWriteMode_WriteEnable (1<<0) #define PM3LBWriteMode_StripePitch(p) (((p)&0x7)<<3) #define PM3LBWriteMode_StripeHeight(h) (((h)&0x7)<<6) - #define PM3LBWriteMode_Layout 1<<9 - #define PM3LBWriteMode_Origin 1<<10 - #define PM3LBWriteMode_Packed16 1<<11 + #define PM3LBWriteMode_Layout (1<<9) + #define PM3LBWriteMode_Origin (1<<10) + #define PM3LBWriteMode_Packed16 (1<<11) #define PM3LBWriteMode_Width(w) (((w)&0xfff)<<12) /* ... */ #define PM3LineStippleMode 0x81a8 @@ -777,6 +852,8 @@ #define PM3LogicalOpMode_UseConstantSource_Disable (0<<11) #define PM3LogicalOpMode_UseConstantSource_Enable (1<<11) +#define PM3LogicalTexturePageAddr 0xb4d0 +#define PM3LogicalTexturePageTableLength 0xb4d8 /* ... */ #define PM3LUT 0x8e80 /* ... */ @@ -789,6 +866,8 @@ #define PM3LUTModeOr 0xad78 #define PM3LUTTransfer 0x84d8 /* ... */ +#define PM3PhysicalPageAllocationTableAddr 0xb4c0 +/* ... */ #define PM3PixelSize 0x80c0 #define PM3PixelSize_GLOBAL_32BIT (0<<0) #define PM3PixelSize_GLOBAL_16BIT (1<<0) @@ -820,6 +899,8 @@ #define PM3PixelSize_GLOBAL (0<<31) #define PM3PixelSize_INDIVIDUAL (1<<31) /* ... */ +#define PM3QStart 0x83b8 + #define PM3Render 0x8038 #define PM3Render_AreaStipple_Disable (0<<0) #define PM3Render_AreaStipple_Enable (1<<0) @@ -858,7 +939,6 @@ #define PM3RasterizerModeAnd 0xaba0 #define PM3RasterizerModeOr 0xabb8 #define PM3RectangleHeight 0x94e0 -#define PM3Render 0x8038 #define PM3RepeatLine 0x9328 #define PM3ResetPickResult 0x8c20 #define PM3RLEMask 0x8c48 @@ -881,11 +961,33 @@ #define PM3StartY 0x8020 /* ... */ #define PM3SpanColorMask 0x8168 + +#define PM3StencilMode 0x8988 +/* ... */ +#define PM3TailPhysicalPageAllocation0 0xb4a0 +#define PM3TailPhysicalPageAllocation1 0xb4a8 +#define PM3TailPhysicalPageAllocation2 0xb4b0 +#define PM3TailPhysicalPageAllocation3 0xb4b8 /* ... */ #define PM3TextureApplicationMode 0x8680 #define PM3TextureApplicationModeAnd 0xac50 #define PM3TextureApplicationModeOr 0xac58 -#define PM3TextureBaseAddr 0x8500 +#define PM3TextureBaseAddr0 0x8500 +#define PM3TextureBaseAddr1 0x8508 +#define PM3TextureBaseAddr2 0x8510 +#define PM3TextureBaseAddr3 0x8518 +#define PM3TextureBaseAddr4 0x8520 +#define PM3TextureBaseAddr5 0x8528 +#define PM3TextureBaseAddr6 0x8530 +#define PM3TextureBaseAddr7 0x8538 +#define PM3TextureBaseAddr8 0x8540 +#define PM3TextureBaseAddr9 0x8548 +#define PM3TextureBaseAddr10 0x8550 +#define PM3TextureBaseAddr11 0x8558 +#define PM3TextureBaseAddr12 0x8560 +#define PM3TextureBaseAddr13 0x8568 +#define PM3TextureBaseAddr14 0x8570 +#define PM3TextureBaseAddr15 0x8578 #define PM3TextureCacheControl 0x8490 #define PM3TextureChromaLower0 0x84f0 #define PM3TextureChromaLower1 0x8608 @@ -943,22 +1045,36 @@ #define PM3TextureReadMode1 0xb408 #define PM3TextureReadMode1And 0xad40 #define PM3TextureReadMode1Or 0xad48 + +#define PM3TouchLogicalPage 0xb370 + #define PM3TouchLogicalPage_Page(p) (p&0xffff) + #define PM3TouchLogicalPage_Count(c) ((c&0x3fff)<<16) + #define PM3TouchLogicalPage_Mode(m) ((m&0x3)<<30) + +#define PM3TStart 0x83a0 + +#define PM3UpdateLogicalTextureInfo 0xb368 + #define PM3UpdateLogicalTextureInfo_Length(l) ((l)&0x1ff) + #define PM3UpdateLogicalTextureInfo_MemoryPool(m) (((m)&0x3)<<9) + #define PM3UpdateLogicalTextureInfo_VirtualHostPage (1<<11) + #define PM3UpdateLogicalTextureInfo_HostPage(p) (((p)&0xfffff)<<12) + /* ... */ #define PM3WaitForCompletion 0x80b8 #define PM3Window 0x8980 - #define PM3Window_ForceLBUpdate 1<<3 - #define PM3Window_LBUpdateSource 1<<4 + #define PM3Window_ForceLBUpdate (1<<3) + #define PM3Window_LBUpdateSource (1<<4) #define PM3Window_FrameCount(c) (((c)&0xff)<<9) - #define PM3Window_StencilFCP 1<<17 - #define PM3Window_DepthFCP 1<<18 - #define PM3Window_OverrideWriteFiltering 1<<19 + #define PM3Window_StencilFCP (1<<17) + #define PM3Window_DepthFCP (1<<18) + #define PM3Window_OverrideWriteFiltering (1<<19) #define PM3WindowAnd 0xab80 #define PM3WindowOr 0xab88 #define PM3WindowOrigin 0x81c8 #define PM3XBias 0x9480 #define PM3YBias 0x9488 #define PM3YLimits 0x80a8 -#define PM3UVMode 0x8f00 +#define PM3YUVMode 0x8f00 #define PM3ZFogBias 0x86b8 #define PM3ZStart 0xadd8 #define PM3ZStartL 0x89b8 @@ -969,21 +1085,21 @@ * GLINT Permedia3 2D setup Unit * ***********************************************/ #define PM3Config2D 0xb618 - #define PM3Config2D_OpaqueSpan 1<<0 - #define PM3Config2D_MultiRXBlit 1<<1 - #define PM3Config2D_UserScissorEnable 1<<2 - #define PM3Config2D_FBDestReadEnable 1<<3 - #define PM3Config2D_AlphaBlendEnable 1<<4 - #define PM3Config2D_DitherEnable 1<<5 - #define PM3Config2D_ForegroundROPEnable 1<<6 + #define PM3Config2D_OpaqueSpan (1<<0) + #define PM3Config2D_MultiRXBlit (1<<1) + #define PM3Config2D_UserScissorEnable (1<<2) + #define PM3Config2D_FBDestReadEnable (1<<3) + #define PM3Config2D_AlphaBlendEnable (1<<4) + #define PM3Config2D_DitherEnable (1<<5) + #define PM3Config2D_ForegroundROPEnable (1<<6) #define PM3Config2D_ForegroundROP(rop) (((rop)&0xf)<<7) - #define PM3Config2D_BackgroundROPEnable 1<<11 + #define PM3Config2D_BackgroundROPEnable (1<<11) #define PM3Config2D_BackgroundROP(rop) (((rop)&0xf)<<12) - #define PM3Config2D_UseConstantSource 1<<16 - #define PM3Config2D_FBWriteEnable 1<<17 - #define PM3Config2D_Blocking 1<<18 - #define PM3Config2D_ExternalSourceData 1<<19 - #define PM3Config2D_LUTModeEnable 1<<20 + #define PM3Config2D_UseConstantSource (1<<16) + #define PM3Config2D_FBWriteEnable (1<<17) + #define PM3Config2D_Blocking (1<<18) + #define PM3Config2D_ExternalSourceData (1<<19) + #define PM3Config2D_LUTModeEnable (1<<20) #define PM3DownloadGlyphwidth 0xb658 #define PM3DownloadGlyphwidth_GlyphWidth(gw) ((gw)&0xffff) #define PM3DownloadTarget 0xb650 @@ -1000,17 +1116,17 @@ #define PM3RectanglePosition_YOffset(y) (((y)&0xffff)<<16) #define PM3Render2D 0xb640 #define PM3Render2D_Width(w) ((w)&0x0fff) - #define PM3Render2D_Operation_Normal 0<<12 - #define PM3Render2D_Operation_SyncOnHostData 1<<12 - #define PM3Render2D_Operation_SyncOnBitMask 2<<12 - #define PM3Render2D_Operation_PatchOrderRendering 3<<12 - #define PM3Render2D_FBSourceReadEnable 1<<14 - #define PM3Render2D_SpanOperation 1<<15 + #define PM3Render2D_Operation_Normal (0<<12) + #define PM3Render2D_Operation_SyncOnHostData (1<<12) + #define PM3Render2D_Operation_SyncOnBitMask (2<<12) + #define PM3Render2D_Operation_PatchOrderRendering (3<<12) + #define PM3Render2D_FBSourceReadEnable (1<<14) + #define PM3Render2D_SpanOperation (1<<15) #define PM3Render2D_Height(h) (((h)&0x0fff)<<16) - #define PM3Render2D_XPositive 1<<28 - #define PM3Render2D_YPositive 1<<29 - #define PM3Render2D_AreaStippleEnable 1<<30 - #define PM3Render2D_TextureEnable 1<<31 + #define PM3Render2D_XPositive (1<<28) + #define PM3Render2D_YPositive (1<<29) + #define PM3Render2D_AreaStippleEnable (1<<30) + #define PM3Render2D_TextureEnable (1<<31) #define PM3Render2DGlyph 0xb648 #define PM3Render2DGlyph_Width(w) ((w)&0x7f) #define PM3Render2DGlyph_Height(h) (((h)&0x7f)<<7) @@ -1059,34 +1175,50 @@ #define PM3FillRectanglePosition_XOffset(x) ((x)&0xffff) #define PM3FillRectanglePosition_YOffset(y) (((y)&0xffff)<<16) -#if 1 - /********************************************** * GLINT Permedia3 Macros * ***********************************************/ +#ifdef __alpha__ +#define mem_barrier() asm volatile ("mb" : : : "memory") +#define write_mem_barrier() asm volatile ("wmb" : : : "memory") +#else +#define mem_barrier() +#define write_mem_barrier() +#endif + extern void *pm3_reg_base; -#define WRITE_REG(offset,val) \ - *(volatile unsigned long *)(((unsigned char *)(pm3_reg_base)) + offset) = (val) - -#define READ_REG(offset) \ - *(volatile unsigned long *)(((unsigned char *)(pm3_reg_base)) + offset) +#define WRITE_REG(offset,val) \ + do { \ + write_mem_barrier(); \ + *(volatile uint32_t *) \ + (((unsigned char *)(pm3_reg_base)) + offset) = (val); \ + } while(0) -#define UPDATE_SET_REG(offset,val) \ - { \ - unsigned long temp; \ - temp = READ_REG(offset); \ - WRITE_REG(offset,temp|(val)); \ - } +static inline uint32_t +READ_REG(uint32_t offset) +{ + mem_barrier(); + return *(volatile uint32_t *)(((unsigned char *)(pm3_reg_base)) + offset); +} + +#define UPDATE_SET_REG(offset,val) \ + { \ + unsigned long temp; \ + temp = READ_REG(offset); \ + WRITE_REG(offset,temp|(val)); \ + } -#define UPDATE_CLEAR_REG(offset,val) \ - { \ - unsigned long temp; \ - temp = READ_REG(offset); \ - WRITE_REG(offset,temp&(~(val))); \ +#define UPDATE_CLEAR_REG(offset,val) \ + { \ + unsigned long temp; \ + temp = READ_REG(offset); \ + WRITE_REG(offset,temp&(~(val))); \ } +#define WAIT_FIFO(n) while(READ_REG(PM3InFIFOSpace) < (n)) + #define RAMDAC_DELAY(x) do { \ int delay = x; \ unsigned char tmp; \ @@ -1112,10 +1244,10 @@ do{ \ SLOW_WRITE_REG(PM3RD_IndexedData, data); \ } -#define RAMDAC_GET_REG(index, temp) \ -{ \ - RAMDAC_SET_INDEX(index); \ - temp = READ_REG(PM3RD_IndexedData); \ +#define RAMDAC_GET_REG(index, temp) \ +{ \ + RAMDAC_SET_INDEX(index); \ + temp = READ_REG(PM3RD_IndexedData); \ } -#endif + #endif /* _PM3_REG_H_ */ diff --git a/src/video_out/vidix/drivers/pm3_vid.c b/src/video_out/vidix/drivers/pm3_vid.c index c5b97782c..20b35a14a 100644 --- a/src/video_out/vidix/drivers/pm3_vid.c +++ b/src/video_out/vidix/drivers/pm3_vid.c @@ -24,16 +24,20 @@ #include <string.h> #include <inttypes.h> #include <unistd.h> +#include <sys/mman.h> #include "vidix.h" #include "fourcc.h" #include "libdha.h" #include "pci_ids.h" #include "pci_names.h" -#include "config.h" #include "pm3_regs.h" +#define PM3_MSG "pm3_vid:" + +#define VIDIX_STATIC pm3_ + /* MBytes of video memory to use */ #define PM3_VIDMEM 24 @@ -45,12 +49,16 @@ #define TRACE_EXIT() #endif -pciinfo_t pci_info; +static pciinfo_t pci_info; -void *pm3_reg_base; -void *pm3_mem; +static void *pm3_reg_base; +static void *pm3_mem; -int pm3_vidmem = PM3_VIDMEM; +static int pm3_vidmem = PM3_VIDMEM; +static int pm3_blank = 0; +static int pm3_dma = 0; + +static u_int page_size; static vidix_capability_t pm3_cap = { @@ -63,14 +71,14 @@ static vidix_capability_t pm3_cap = 4, 4, -1, - FLAG_UPSCALER|FLAG_DOWNSCALER, + FLAG_UPSCALER | FLAG_DOWNSCALER, VENDOR_3DLABS, -1, { 0, 0, 0, 0 } }; -unsigned int vixGetVersion(void) +unsigned int VIDIX_NAME(vixGetVersion)(void) { return(VIDIX_VERSION); } @@ -90,7 +98,7 @@ static int find_chip(unsigned chip_id) return -1; } -int vixProbe(int verbose, int force) +int VIDIX_NAME(vixProbe)(int verbose, int force) { pciinfo_t lst[MAX_PCI_DEVICES]; unsigned i,num_pci; @@ -99,7 +107,7 @@ int vixProbe(int verbose, int force) err = pci_scan(lst,&num_pci); if(err) { - printf("[pm3] Error occured during pci scan: %s\n",strerror(err)); + printf(PM3_MSG" Error occured during pci scan: %s\n",strerror(err)); return err; } else @@ -116,7 +124,8 @@ int vixProbe(int verbose, int force) continue; dname = pci_device_name(VENDOR_3DLABS, lst[i].device); dname = dname ? dname : "Unknown chip"; - printf("[pm3] Found chip: %s\n", dname); + printf(PM3_MSG" Found chip: %s with IRQ %i\n", + dname, lst[i].irq); pm3_cap.device_id = lst[i].device; err = 0; memcpy(&pci_info, &lst[i], sizeof(pciinfo_t)); @@ -124,34 +133,62 @@ int vixProbe(int verbose, int force) } } } - if(err && verbose) printf("[pm3] Can't find chip\n"); + if(err && verbose) printf(PM3_MSG" Can't find chip\n"); return err; } #define PRINT_REG(reg) \ { \ long _foo = READ_REG(reg); \ - printf("[pm3] " #reg " (%x) = %#lx (%li)\n", reg, _foo, _foo); \ + printf(PM3_MSG" " #reg " (%x) = %#lx (%li)\n", reg, _foo, _foo); \ } -int vixInit(void) +int VIDIX_NAME(vixInit)(const char *args) { - char *vm; + char *ac = strdup(args), *s, *opt; + + opt = strtok_r(ac, ",", &s); + while(opt){ + char *a = strchr(opt, '='); + + if(a) + *a++ = 0; + if(!strcmp(opt, "mem")){ + if(a) + pm3_vidmem = strtol(a, NULL, 0); + } else if(!strcmp(opt, "blank")){ + pm3_blank = a? strtol(a, NULL, 0): 1; + } + + opt = strtok_r(NULL, ",", &s); + } + + free(ac); + pm3_reg_base = map_phys_mem(pci_info.base0, 0x20000); pm3_mem = map_phys_mem(pci_info.base1, 0x2000000); - if((vm = getenv("PM3_VIDMEM"))){ - pm3_vidmem = strtol(vm, NULL, 0); + + if(bm_open() == 0){ + printf(PM3_MSG" Using DMA.\n"); + pm3_cap.flags |= FLAG_DMA; + page_size = sysconf(_SC_PAGESIZE); + hwirq_install(pci_info.bus, pci_info.card, pci_info.func, + 0, PM3IntFlags, -1); + pm3_dma = 1; } + return 0; } -void vixDestroy(void) +void VIDIX_NAME(vixDestroy)(void) { unmap_phys_mem(pm3_reg_base, 0x20000); unmap_phys_mem(pm3_mem, 0x2000000); + hwirq_uninstall(pci_info.bus, pci_info.card, pci_info.func); + bm_close(); } -int vixGetCapability(vidix_capability_t *to) +int VIDIX_NAME(vixGetCapability)(vidix_capability_t *to) { memcpy(to, &pm3_cap, sizeof(vidix_capability_t)); return 0; @@ -168,7 +205,7 @@ static int is_supported_fourcc(uint32_t fourcc) } } -int vixQueryFourcc(vidix_fourcc_t *to) +int VIDIX_NAME(vixQueryFourcc)(vidix_fourcc_t *to) { if(is_supported_fourcc(to->fourcc)) { @@ -184,6 +221,12 @@ int vixQueryFourcc(vidix_fourcc_t *to) return ENOSYS; } +static int frames[VID_PLAY_MAXFRAMES], vid_base; +static long overlay_mode, overlay_control, video_control, int_enable; +static int src_w, drw_w; +static int src_h, drw_h; +static int drw_x, drw_y; + #define FORMAT_RGB8888 PM3VideoOverlayMode_COLORFORMAT_RGB8888 #define FORMAT_RGB4444 PM3VideoOverlayMode_COLORFORMAT_RGB4444 #define FORMAT_RGB5551 PM3VideoOverlayMode_COLORFORMAT_RGB5551 @@ -202,9 +245,8 @@ int vixQueryFourcc(vidix_fourcc_t *to) /* Notice, have to check that we dont overflow the deltas here ... */ static void -compute_scale_factor( - short* src_w, short* dst_w, - unsigned int* shrink_delta, unsigned int* zoom_delta) +compute_scale_factor(int* src_w, int* dst_w, + u_int* shrink_delta, u_int* zoom_delta) { /* NOTE: If we don't return reasonable values here then the video * unit can potential shut off and won't display an image until re-enabled. @@ -228,21 +270,13 @@ compute_scale_factor( } } -static int frames[VID_PLAY_MAXFRAMES]; - -static long overlay_mode, overlay_control; - -int vixConfigPlayback(vidix_playback_t *info) +static void +pm3_setup_overlay(vidix_playback_t *info) { int shrink, zoom; - short src_w, drw_w; - short src_h, drw_h; - long base0; - int pitch; - int format; - unsigned int i; - - TRACE_ENTER(); + int format = 0; + int filter = 0; + int sw = src_w; switch(info->fourcc){ case IMGFMT_YUY2: @@ -251,97 +285,46 @@ int vixConfigPlayback(vidix_playback_t *info) case IMGFMT_UYVY: format = FORMAT_VUY422; break; - default: - return -1; } - src_w = info->src.w; - src_h = info->src.h; + compute_scale_factor(&sw, &drw_w, &shrink, &zoom); - drw_w = info->dest.w; - drw_h = info->dest.h; - - pitch = src_w; - - info->num_frames = pm3_vidmem*1024*1024 / (pitch * src_h * 2); - if(info->num_frames > VID_PLAY_MAXFRAMES) - info->num_frames = VID_PLAY_MAXFRAMES; - - /* Use end of video memory. Assume the card has 32 MB */ - base0 = (32-pm3_vidmem)*1024*1024; - info->dga_addr = pm3_mem + base0; - - if(info->fourcc == IMGFMT_YV12){ - info->dest.pitch.y = 2; - info->dest.pitch.u = 2; - info->dest.pitch.y = 2; - info->offset.y = 0; - info->offset.v = src_w * src_h; - info->offset.u = src_w * src_h * 3/2; - } else { - info->dest.pitch.y = 2; - info->dest.pitch.u = 0; - info->dest.pitch.v = 0; - info->offset.y = 0; - info->offset.v = 0; - info->offset.u = 0; - } - info->frame_size = pitch * src_h * 2; - - for(i = 0; i < info->num_frames; i++){ - info->offsets[i] = info->frame_size * i; - frames[i] = (base0 + info->offsets[i]) >> 1; - } - - compute_scale_factor(&src_w, &drw_w, &shrink, &zoom); - -#if 0 - aperture_mode = READ_REG(PM3ByAperture1Mode); - if(info->fourcc == IMGFMT_YV12){ -/* WRITE_REG(PM3Aperture0, base0 >> 1); */ - WRITE_REG(PM3ByAperture1Mode, - PM3ByApertureMode_FORMAT_YUYV | - PM3ByApertureMode_PIXELSIZE_32BIT); - WRITE_REG(PM3Aperture1Stride, pitch); - WRITE_REG(PM3Aperture1YStart, base0 / 16); - WRITE_REG(PM3Aperture1VStart, (base0 + info->offset.v) / 16); - WRITE_REG(PM3Aperture1UStart, (base0 + info->offset.u) / 16); - } -#endif - - WRITE_REG(PM3VideoOverlayBase0, base0 >> 1); - WRITE_REG(PM3VideoOverlayStride, PM3VideoOverlayStride_STRIDE(pitch)); - WRITE_REG(PM3VideoOverlayWidth, PM3VideoOverlayWidth_WIDTH(src_w)); + WRITE_REG(PM3VideoOverlayBase0, vid_base >> 1); + WRITE_REG(PM3VideoOverlayStride, PM3VideoOverlayStride_STRIDE(src_w)); + WRITE_REG(PM3VideoOverlayWidth, PM3VideoOverlayWidth_WIDTH(sw)); WRITE_REG(PM3VideoOverlayHeight, PM3VideoOverlayHeight_HEIGHT(src_h)); WRITE_REG(PM3VideoOverlayOrigin, 0); /* Scale the source to the destinationsize */ - if (src_h == drw_h) { - WRITE_REG(PM3VideoOverlayYDelta, PM3VideoOverlayYDelta_NONE); - } else { - WRITE_REG(PM3VideoOverlayYDelta, - PM3VideoOverlayYDelta_DELTA(src_h, drw_h)); - } if (src_w == drw_w) { WRITE_REG(PM3VideoOverlayShrinkXDelta, 1<<16); WRITE_REG(PM3VideoOverlayZoomXDelta, 1<<16); } else { WRITE_REG(PM3VideoOverlayShrinkXDelta, shrink); WRITE_REG(PM3VideoOverlayZoomXDelta, zoom); + filter = PM3VideoOverlayMode_FILTER_PARTIAL; } + if (src_h == drw_h) { + WRITE_REG(PM3VideoOverlayYDelta, PM3VideoOverlayYDelta_NONE); + } else { + WRITE_REG(PM3VideoOverlayYDelta, + PM3VideoOverlayYDelta_DELTA(src_h, drw_h)); + filter = PM3VideoOverlayMode_FILTER_FULL; + } + WRITE_REG(PM3VideoOverlayIndex, 0); /* Now set the ramdac video overlay region and mode */ - RAMDAC_SET_REG(PM3RD_VideoOverlayXStartLow, (info->dest.x & 0xff)); - RAMDAC_SET_REG(PM3RD_VideoOverlayXStartHigh, (info->dest.x & 0xf00)>>8); - RAMDAC_SET_REG(PM3RD_VideoOverlayXEndLow, (info->dest.x+drw_w) & 0xff); + RAMDAC_SET_REG(PM3RD_VideoOverlayXStartLow, (drw_x & 0xff)); + RAMDAC_SET_REG(PM3RD_VideoOverlayXStartHigh, (drw_x & 0xf00)>>8); + RAMDAC_SET_REG(PM3RD_VideoOverlayXEndLow, (drw_x+drw_w) & 0xff); RAMDAC_SET_REG(PM3RD_VideoOverlayXEndHigh, - ((info->dest.x+drw_w) & 0xf00)>>8); - RAMDAC_SET_REG(PM3RD_VideoOverlayYStartLow, (info->dest.y & 0xff)); - RAMDAC_SET_REG(PM3RD_VideoOverlayYStartHigh, (info->dest.y & 0xf00)>>8); - RAMDAC_SET_REG(PM3RD_VideoOverlayYEndLow, (info->dest.y+drw_h) & 0xff); + ((drw_x+drw_w) & 0xf00)>>8); + RAMDAC_SET_REG(PM3RD_VideoOverlayYStartLow, (drw_y & 0xff)); + RAMDAC_SET_REG(PM3RD_VideoOverlayYStartHigh, (drw_y & 0xf00)>>8); + RAMDAC_SET_REG(PM3RD_VideoOverlayYEndLow, (drw_y+drw_h) & 0xff); RAMDAC_SET_REG(PM3RD_VideoOverlayYEndHigh, - ((info->dest.y+drw_h) & 0xf00)>>8); + ((drw_y+drw_h) & 0xf00)>>8); RAMDAC_SET_REG(PM3RD_VideoOverlayKeyR, 0xff); RAMDAC_SET_REG(PM3RD_VideoOverlayKeyG, 0x00); @@ -350,20 +333,71 @@ int vixConfigPlayback(vidix_playback_t *info) overlay_mode = 1 << 5 | format | - PM3VideoOverlayMode_FILTER_FULL | + filter | PM3VideoOverlayMode_BUFFERSYNC_MANUAL | PM3VideoOverlayMode_FLIP_VIDEO; overlay_control = PM3RD_VideoOverlayControl_KEY_COLOR | - PM3RD_VideoOverlayControl_MODE_OVERLAYKEY | + PM3RD_VideoOverlayControl_MODE_ALWAYS | PM3RD_VideoOverlayControl_DIRECTCOLOR_ENABLED; +} + +int VIDIX_NAME(vixConfigPlayback)(vidix_playback_t *info) +{ + unsigned int i; + u_int frame_size; + u_int vidmem_size; + u_int max_frames; + + TRACE_ENTER(); + + src_w = info->src.w; + src_h = info->src.h; + drw_w = info->dest.w; + drw_h = info->dest.h; + drw_x = info->dest.x; + drw_y = info->dest.y; + + frame_size = src_w * src_h * 2; + vidmem_size = pm3_vidmem*1024*1024; + max_frames = vidmem_size / frame_size; + if(max_frames > VID_PLAY_MAXFRAMES) + max_frames = VID_PLAY_MAXFRAMES; + + src_h--; /* ugh */ + + if(info->num_frames > max_frames) + info->num_frames = max_frames; + vidmem_size = info->num_frames * frame_size; + + /* Use end of video memory. Assume the card has 32 MB */ + vid_base = 32*1024*1024 - vidmem_size; + info->dga_addr = pm3_mem + vid_base; + + info->dest.pitch.y = 2; + info->dest.pitch.u = 0; + info->dest.pitch.v = 0; + info->offset.y = 0; + info->offset.v = 0; + info->offset.u = 0; + info->frame_size = frame_size; + + for(i = 0; i < info->num_frames; i++){ + info->offsets[i] = frame_size * i; + frames[i] = (vid_base + info->offsets[i]) >> 1; + } + + pm3_setup_overlay(info); + + video_control = READ_REG(PM3VideoControl); + int_enable = READ_REG(PM3IntEnable); TRACE_EXIT(); return 0; } -int vixPlaybackOn(void) +int VIDIX_NAME(vixPlaybackOn)(void) { TRACE_ENTER(); @@ -374,11 +408,15 @@ int vixPlaybackOn(void) WRITE_REG(PM3VideoOverlayUpdate, PM3VideoOverlayUpdate_ENABLE); + if(pm3_blank) + WRITE_REG(PM3VideoControl, + video_control | PM3VideoControl_DISPLAY_ENABLE); + TRACE_EXIT(); return 0; } -int vixPlaybackOff(void) +int VIDIX_NAME(vixPlaybackOff)(void) { RAMDAC_SET_REG(PM3RD_VideoOverlayControl, PM3RD_VideoOverlayControl_DISABLE); @@ -389,12 +427,115 @@ int vixPlaybackOff(void) RAMDAC_SET_REG(PM3RD_VideoOverlayKeyG, 0x01); RAMDAC_SET_REG(PM3RD_VideoOverlayKeyB, 0xfe); + if(video_control) + WRITE_REG(PM3VideoControl, video_control); + + if(pm3_dma) + WRITE_REG(PM3IntEnable, 0); + return 0; } -int vixPlaybackFrameSelect(unsigned int frame) +int VIDIX_NAME(vixPlaybackFrameSelect)(unsigned int frame) { WRITE_REG(PM3VideoOverlayBase0, frames[frame]); -/* WRITE_REG(PM3Aperture0, frames[frame]); */ + + return 0; +} + +struct pm3_bydma_cmd { + uint32_t bus_addr; + uint32_t fb_addr; + uint32_t mask; + uint32_t count; +}; + +struct pm3_bydma_frame { + struct pm3_bydma_cmd *cmds; + u_long bus_addr; + uint32_t count; +}; + +static struct pm3_bydma_frame * +pm3_setup_bydma(vidix_dma_t *dma) +{ + u_int size = dma->size; + u_int pages = (size + page_size-1) / page_size; + struct pm3_bydma_frame *bdf; + long baddr[pages]; + u_int i; + uint32_t dest; + + if(bm_virt_to_bus(dma->src, dma->size, baddr)) + return NULL; + + bdf = malloc(sizeof(*bdf)); + bdf->cmds = valloc(pages * sizeof(struct pm3_bydma_cmd)); + + dest = vid_base + dma->dest_offset; + for(i = 0; i < pages; i++, dest += page_size, size -= page_size){ + bdf->cmds[i].bus_addr = baddr[i]; + bdf->cmds[i].fb_addr = dest; + bdf->cmds[i].mask = ~0; + bdf->cmds[i].count = ((size > page_size)? page_size: size) / 16; + } + + bdf->count = pages; + + if(bm_virt_to_bus(bdf->cmds, page_size, &bdf->bus_addr) != 0){ + free(bdf->cmds); + free(bdf); + return NULL; + } + + return bdf; +} + +extern int +VIDIX_NAME(vixPlaybackCopyFrame)(vidix_dma_t *dma) +{ + u_int frame = dma->idx; + struct pm3_bydma_frame *bdf; + + if(dma->internal[frame]){ + bdf = dma->internal[frame]; + } else { + if(!(bdf = pm3_setup_bydma(dma))){ + return -1; + } else if(dma->flags & BM_DMA_FIXED_BUFFS){ + if(mlock(bdf->cmds, page_size) == 0){ + dma->internal[frame] = bdf; + } else { + printf(PM3_MSG" Can't lock page @ %p\n", bdf->cmds); + } + } + } + + if(dma->flags & BM_DMA_SYNC){ + WRITE_REG(PM3IntEnable, (1 << 7)); + while(READ_REG(PM3ByDMAReadMode) & PM3ByDMAReadMode_Active){ + hwirq_wait(pci_info.irq); + } + WRITE_REG(PM3IntEnable, 0); + } + + WAIT_FIFO(3); + WRITE_REG(PM3ByDMAReadCommandBase, bdf->bus_addr); + WRITE_REG(PM3ByDMAReadCommandCount, bdf->count); + WRITE_REG(PM3ByDMAReadMode, + PM3ByDMAReadMode_ByteSwap_NONE | + PM3ByDMAReadMode_Format_RAW | + PM3ByDMAReadMode_PixelSize(16) | + PM3ByDMAReadMode_Active | + PM3ByDMAReadMode_Burst(7) | + PM3ByDMAReadMode_Align); + return 0; } + +extern int +VIDIX_NAME(vixQueryDMAStatus)(void) +{ + uint32_t bdm = READ_REG(PM3ByDMAReadMode); + return (bdm & PM3ByDMAReadMode_Active)? 1: 0; +} diff --git a/src/video_out/vidix/drivers/radeon.h b/src/video_out/vidix/drivers/radeon.h index 82ab7a895..090fbf8df 100644 --- a/src/video_out/vidix/drivers/radeon.h +++ b/src/video_out/vidix/drivers/radeon.h @@ -597,9 +597,7 @@ # define SCALER_UNKNOWN_FLAG3 0x02000000L /* ??? */ # define SCALER_UNKNOWN_FLAG4 0x04000000L /* ??? */ # define SCALER_DIS_LIMIT 0x08000000L -#ifdef RAGE128 # define SCALER_PRG_LOAD_START 0x10000000L -#endif # define SCALER_INT_EMU 0x20000000L # define SCALER_ENABLE 0x40000000L # define SCALER_SOFT_RESET 0x80000000L @@ -758,6 +756,10 @@ # define CMP_MIX_OR 0x00000000L # define CMP_MIX_AND 0x00000100L #define OV0_TEST 0x04F8 +# define OV0_SCALER_Y2R_DISABLE 0x00000001L +# define OV0_SUBPIC_ONLY 0x00000008L +# define OV0_EXTENSE 0x00000010L +# define OV0_SWAP_UV 0x00000020L #define OV0_COL_CONV 0x04FC # define OV0_CB_TO_B 0x0000007FL # define OV0_CB_TO_G 0x0000FF00L diff --git a/src/video_out/vidix/drivers/radeon_vid.c b/src/video_out/vidix/drivers/radeon_vid.c index 8d8805264..7864083a8 100644 --- a/src/video_out/vidix/drivers/radeon_vid.c +++ b/src/video_out/vidix/drivers/radeon_vid.c @@ -12,6 +12,7 @@ #include <math.h> #include <inttypes.h> #include <sys/mman.h> +#include "bswap.h" #include "pci_ids.h" #include "pci_names.h" #include "vidix.h" @@ -20,16 +21,24 @@ #include "radeon.h" #ifdef RAGE128 -#define RADEON_MSG "Rage128_vid:" +#define RADEON_MSG "rage128_vid:" #define X_ADJUST 0 #else -#define RADEON_MSG "Radeon_vid:" -#define X_ADJUST 8 +#define RADEON_MSG "radeon_vid:" +#define X_ADJUST (is_shift_required ? 8 : 0) #ifndef RADEON #define RADEON #endif #endif +#define RADEON_ASSERT(msg) printf(RADEON_MSG"################# FATAL:"msg); + +#ifdef RAGE128 +#define VIDIX_STATIC rage128_ +#else +#define VIDIX_STATIC radeo_ +#endif + //#undef RADEON_ENABLE_BM /* unfinished stuff. May corrupt your filesystem ever */ #define RADEON_ENABLE_BM 1 @@ -50,12 +59,19 @@ typedef struct #define VERBOSE_LEVEL 0 static int __verbose = 0; - +#ifndef RAGE128 +static int is_shift_required=0; +#endif 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; @@ -85,6 +101,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 */ @@ -112,7 +129,7 @@ typedef struct video_registers_s static bes_registers_t besr; #ifndef RAGE128 -static int IsR200=0; +static int RadeonFamily=100; #endif #define DECLARE_VREG(name) { #name, name, 0 } static video_registers_t vregs[] = @@ -256,9 +273,12 @@ static uint32_t radeon_ram_size = 0; #define INREG8(addr) GETREG(uint8_t,(uint32_t)(radeon_mmio_base),addr) #define OUTREG8(addr,val) SETREG(uint8_t,(uint32_t)(radeon_mmio_base),addr,val) -#define INREG(addr) GETREG(uint32_t,(uint32_t)(radeon_mmio_base),addr) -#define OUTREG(addr,val) SETREG(uint32_t,(uint32_t)(radeon_mmio_base),addr,val) -#define OUTREGP(addr,val,mask) \ +static inline uint32_t INREG (uint32_t addr) { + uint32_t tmp = GETREG(uint32_t,(uint32_t)(radeon_mmio_base),addr); + return le2me_32(tmp); +} +#define OUTREG(addr,val) SETREG(uint32_t,(uint32_t)(radeon_mmio_base),addr,le2me_32(val)) +#define OUTREGP(addr,val,mask) \ do { \ unsigned int _tmp = INREG(addr); \ _tmp &= (mask); \ @@ -266,6 +286,7 @@ static uint32_t radeon_ram_size = 0; OUTREG(addr, _tmp); \ } while (0) + static __inline__ uint32_t INPLL(uint32_t addr) { OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000001f); @@ -274,7 +295,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); \ @@ -362,7 +383,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); @@ -374,7 +395,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); } @@ -386,7 +407,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,7 +485,7 @@ static void radeon_engine_restore( void ) (pitch64 << 22)); radeon_fifo_wait(1); -#if defined(__BIG_ENDIAN) +#if defined(WORDS_BIGENDIAN) OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN); #else @@ -578,19 +599,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 +656,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; @@ -744,7 +765,7 @@ GAMMA_SETTINGS r100_def_gamma[6] = static void make_default_gamma_correction( void ) { size_t i; - if(!IsR200){ + if(RadeonFamily == 100){ OUTREG(OV0_LIN_TRANS_A, 0x12A00000); OUTREG(OV0_LIN_TRANS_B, 0x199018FE); OUTREG(OV0_LIN_TRANS_C, 0x12A0F9B0); @@ -754,24 +775,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 +800,9 @@ static void make_default_gamma_correction( void ) static void radeon_vid_make_default(void) { #ifdef RAGE128 - OUTREG(OV0_COLOUR_CNTL,0x00101000UL); /* Default brihgtness 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 @@ -795,7 +817,7 @@ static void radeon_vid_make_default(void) } -unsigned vixGetVersion( void ) { return VIDIX_VERSION; } +unsigned VIDIX_NAME(vixGetVersion)( void ) { return VIDIX_VERSION; } static unsigned short ati_card_ids[] = { @@ -845,11 +867,11 @@ static unsigned short ati_card_ids[] = DEVICE_ATI_RAGE_128_SE_4X, DEVICE_ATI_RAGE_128_SF_4X, DEVICE_ATI_RAGE_128_SG_4X, - DEVICE_ATI_RAGE_128_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_4X2, + DEVICE_ATI_RAGE_128_4X, DEVICE_ATI_RAGE_128_PRO, DEVICE_ATI_RAGE_128_PRO2, DEVICE_ATI_RAGE_128_PRO3, @@ -858,18 +880,40 @@ static unsigned short ati_card_ids[] = DEVICE_ATI_RAGE_MOBILITY_M32 #else /* Radeons (indeed: Rage 256 Pro ;) */ - DEVICE_ATI_RADEON_8500_DV, + DEVICE_ATI_RADEON_R100_QD, + DEVICE_ATI_RADEON_R100_QE, + DEVICE_ATI_RADEON_R100_QF, + DEVICE_ATI_RADEON_R100_QG, + DEVICE_ATI_RADEON_VE_QY, + DEVICE_ATI_RADEON_VE_QZ, + DEVICE_ATI_RADEON_MOBILITY_M7, + DEVICE_ATI_RADEON_MOBILITY_M72, DEVICE_ATI_RADEON_MOBILITY_M6, DEVICE_ATI_RADEON_MOBILITY_M62, - DEVICE_ATI_RADEON_MOBILITY_M63, - DEVICE_ATI_RADEON_QD, - DEVICE_ATI_RADEON_QE, - DEVICE_ATI_RADEON_QF, - DEVICE_ATI_RADEON_QG, - DEVICE_ATI_RADEON_QL, - DEVICE_ATI_RADEON_QW, - DEVICE_ATI_RADEON_VE_QY, - DEVICE_ATI_RADEON_VE_QZ + DEVICE_ATI_RADEON_R200_BB, + 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_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_R250_ID, + DEVICE_ATI_RADEON_R250_IE, + DEVICE_ATI_RADEON_R250_IF, + DEVICE_ATI_RADEON_R250_IG, + DEVICE_ATI_RADEON_R250_LD, + DEVICE_ATI_RADEON_R250_LE, + DEVICE_ATI_RADEON_R250_LF, + DEVICE_ATI_RADEON_R250_LG, + DEVICE_ATI_RADEON_R300_ND, + DEVICE_ATI_RADEON_R300_NE, + DEVICE_ATI_RADEON_R300_NF, + DEVICE_ATI_RADEON_R300_NG #endif }; @@ -883,7 +927,7 @@ static int find_chip(unsigned chip_id) return -1; } -pciinfo_t pci_info; +static pciinfo_t pci_info; static int probed=0; vidix_capability_t def_cap = @@ -908,7 +952,7 @@ vidix_capability_t def_cap = }; -int vixProbe( int verbose,int force ) +int VIDIX_NAME(vixProbe)( int verbose,int force ) { pciinfo_t lst[MAX_PCI_DEVICES]; unsigned i,num_pci; @@ -927,18 +971,78 @@ int vixProbe( 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); -#ifndef RAGE128 +#ifndef RAGE128 if(idx != -1) - if(ati_card_ids[idx] == DEVICE_ATI_RADEON_QL || - ati_card_ids[idx] == DEVICE_ATI_RADEON_8500_DV || - ati_card_ids[idx] == DEVICE_ATI_RADEON_QW) IsR200 = 1; + { + 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_VE_QY: + case DEVICE_ATI_RADEON_VE_QZ: + case DEVICE_ATI_RADEON_MOBILITY_M6: + case DEVICE_ATI_RADEON_MOBILITY_M62: + 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_MOBILITY_M72: + RadeonFamily = 150; + break; + + /* Radeon 8500 */ + case DEVICE_ATI_RADEON_R200_BB: + 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_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_R250_ID: + case DEVICE_ATI_RADEON_R250_IE: + case DEVICE_ATI_RADEON_R250_IF: + case DEVICE_ATI_RADEON_R250_IG: + case DEVICE_ATI_RADEON_R250_LD: + case DEVICE_ATI_RADEON_R250_LE: + case DEVICE_ATI_RADEON_R250_LF: + case DEVICE_ATI_RADEON_R250_LG: + RadeonFamily = 250; + break; + + /* Radeon 9700 */ + case DEVICE_ATI_RADEON_R300_ND: + case DEVICE_ATI_RADEON_R300_NE: + case DEVICE_ATI_RADEON_R300_NF: + case DEVICE_ATI_RADEON_R300_NG: + RadeonFamily = 300; + break; + default: + break; + } + } #endif if(force > PROBE_NORMAL) { @@ -993,7 +1097,7 @@ static char * GET_MON_NAME(int type) case MT_LCD: pret = "LCD"; break; case MT_CTV: pret = "CTV"; break; case MT_STV: pret = "STV"; break; - default: pret = "Unknown"; + default: pret = "Unknown"; } return pret; } @@ -1040,7 +1144,38 @@ static void radeon_get_moninfo (rinfo_t *rinfo) } } #endif -int vixInit( void ) + +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; +}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); +} + +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); +} + +int VIDIX_NAME(vixInit)( const char *args ) { int err; if(!probed) @@ -1061,19 +1196,18 @@ int vixInit( void ) #ifndef RAGE128 { memset(&rinfo,0,sizeof(rinfo_t)); - switch(def_cap.device_id) + if(RadeonFamily > 100) rinfo.hasCRTC2 = 1; + + switch(RadeonFamily) { - case DEVICE_ATI_RADEON_VE_QY: - case DEVICE_ATI_RADEON_VE_QZ: - case DEVICE_ATI_RADEON_MOBILITY_M6: - case DEVICE_ATI_RADEON_MOBILITY_M62: - case DEVICE_ATI_RADEON_MOBILITY_M63: - case DEVICE_ATI_RADEON_QL: - case DEVICE_ATI_RADEON_8500_DV: - case DEVICE_ATI_RADEON_QW: - rinfo.hasCRTC2 = 1; - break; - default: break; + case 100: + case 120: + case 150: + case 250: + is_shift_required=1; + break; + default: + break; } radeon_get_moninfo(&rinfo); if(rinfo.hasCRTC2) { @@ -1095,17 +1229,19 @@ int vixInit( void ) else if(__verbose) printf(RADEON_MSG" Can't initialize busmastering: %s\n",strerror(errno)); #endif + save_regs(); return 0; } -void vixDestroy( void ) +void VIDIX_NAME(vixDestroy)( void ) { + restore_regs(); unmap_phys_mem(radeon_mem_base,radeon_ram_size); unmap_phys_mem(radeon_mmio_base,0xFFFF); bm_close(); } -int vixGetCapability(vidix_capability_t *to) +int VIDIX_NAME(vixGetCapability)(vidix_capability_t *to) { memcpy(to,&def_cap,sizeof(vidix_capability_t)); return 0; @@ -1116,29 +1252,45 @@ int vixGetCapability(vidix_capability_t *to) YUY2, UYVY, DDES, OGLT, OGL2, OGLS, OGLB, OGNT, OGNZ, OGNS, IF09, YVU9, IMC4, M2IA, IYUV, VBID, DXT1, DXT2, DXT3, DXT4, DXT5 */ -uint32_t supported_fourcc[] = -{ - IMGFMT_Y800, 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; + +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 srcw) { unsigned i; - for(i=0;i<sizeof(supported_fourcc)/sizeof(uint32_t);i++) + for(i=0;i<sizeof(supported_fourcc)/sizeof(fourcc_desc_t);i++) { - if(fourcc==supported_fourcc[i]) return 1; + if(fourcc==supported_fourcc[i].fourcc && + srcw <=supported_fourcc[i].max_srcw) return 1; } return 0; } -int vixQueryFourcc(vidix_fourcc_t *to) +int VIDIX_NAME(vixQueryFourcc)(vidix_fourcc_t *to) { - if(is_supported_fourcc(to->fourcc)) + if(is_supported_fourcc(to->fourcc,to->srcw)) { to->depth = VID_DEPTH_1BPP | VID_DEPTH_2BPP | VID_DEPTH_4BPP | VID_DEPTH_8BPP | @@ -1152,6 +1304,7 @@ int vixQueryFourcc(vidix_fourcc_t *to) return ENOSYS; } +static double H_scale_ratio; static void radeon_vid_dump_regs( void ) { size_t i; @@ -1161,6 +1314,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"H_scale_ratio=%8.2f\n",H_scale_ratio); printf(RADEON_MSG"*** Begin of OV0 registers dump ***\n"); for(i=0;i<sizeof(vregs)/sizeof(video_registers_t);i++) printf(RADEON_MSG"%s = %08X\n",vregs[i].sname,INREG(vregs[i].name)); @@ -1174,7 +1328,11 @@ static void radeon_vid_stop_video( void ) OUTREG(OV0_EXCLUSIVE_HORZ, 0); OUTREG(OV0_AUTO_FLIP_CNTL, 0); /* maybe */ OUTREG(OV0_FILTER_CNTL, FILTER_HARDCODED_COEF); +#ifdef RAGE128 OUTREG(OV0_KEY_CNTL, GRAPHIC_KEY_FN_NE); +#else + OUTREG(OV0_KEY_CNTL, GRAPHIC_KEY_FN_EQ); +#endif OUTREG(OV0_TEST, 0); } @@ -1235,41 +1393,18 @@ static void radeon_vid_display_video( void ) OUTREG(OV0_P23_V_ACCUM_INIT, besr.p23_v_accum_init); bes_flags = SCALER_ENABLE | - SCALER_SMART_SWITCH | + SCALER_SMART_SWITCH | SCALER_Y2R_TEMP | SCALER_PIX_EXPAND; if(besr.double_buff) bes_flags |= SCALER_DOUBLE_BUFFER; if(besr.deinterlace_on) bes_flags |= SCALER_ADAPTIVE_DEINT; + if(besr.horz_pick_nearest) bes_flags |= SCALER_HORZ_PICK_NEAREST; + if(besr.vert_pick_nearest) bes_flags |= SCALER_VERT_PICK_NEAREST; #ifdef RAGE128 bes_flags |= SCALER_BURST_PER_PLANE; #endif - switch(besr.fourcc) - { - case IMGFMT_RGB15: - case IMGFMT_BGR15: bes_flags |= SCALER_SOURCE_15BPP | 0x10000000; break; - case IMGFMT_RGB16: - case IMGFMT_BGR16: bes_flags |= SCALER_SOURCE_16BPP | 0x10000000; break; -/* - case IMGFMT_RGB24: - case IMGFMT_BGR24: bes_flags |= SCALER_SOURCE_24BPP; break; -*/ - case IMGFMT_RGB32: - case IMGFMT_BGR32: bes_flags |= SCALER_SOURCE_32BPP | 0x10000000; break; - /* 4:1:0*/ - case IMGFMT_IF09: - case IMGFMT_YVU9: bes_flags |= SCALER_SOURCE_YUV9; break; - /* 4:0:0*/ - case IMGFMT_Y800: - /* 4:2:0 */ - case IMGFMT_IYUV: - case IMGFMT_I420: - case IMGFMT_YV12: bes_flags |= SCALER_SOURCE_YUV12; break; - /* 4:2:2 */ - case IMGFMT_YVYU: - case IMGFMT_UYVY: bes_flags |= SCALER_SOURCE_YVYU422; break; - case IMGFMT_YUY2: - default: bes_flags |= SCALER_SOURCE_VYUY422; break; - } + bes_flags |= (besr.surf_id << 8) & SCALER_SURFAC_FORMAT; + if(besr.load_prg_start) bes_flags |= SCALER_PRG_LOAD_START; OUTREG(OV0_SCALE_CNTL, bes_flags); #ifndef RAGE128 if(rinfo.hasCRTC2 && @@ -1278,6 +1413,14 @@ static void radeon_vid_display_video( void ) /* TODO: suppress scaler output to CRTC here and enable TVO only */ } #endif + radeon_fifo_wait(6); + OUTREG(OV0_FILTER_CNTL,besr.filter_cntl); + OUTREG(OV0_FOUR_TAP_COEF_0,besr.four_tap_coeff[0]); + OUTREG(OV0_FOUR_TAP_COEF_1,besr.four_tap_coeff[1]); + OUTREG(OV0_FOUR_TAP_COEF_2,besr.four_tap_coeff[2]); + OUTREG(OV0_FOUR_TAP_COEF_3,besr.four_tap_coeff[3]); + OUTREG(OV0_FOUR_TAP_COEF_4,besr.four_tap_coeff[4]); + if(besr.swap_uv) OUTREG(OV0_TEST,INREG(OV0_TEST)|OV0_SWAP_UV); OUTREG(OV0_REG_LOAD_CNTL, 0); if(__verbose > VERBOSE_LEVEL) printf(RADEON_MSG"we wanted: scaler=%08X\n",bes_flags); if(__verbose > VERBOSE_LEVEL) radeon_vid_dump_regs(); @@ -1358,34 +1501,966 @@ 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)) * (1<<0xc) + 0.5)<=0x2000)) + { /*>=0.3125 and >.333333~ */ + *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*2)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 2; + *P1StepSize = 1; + *P23StepSize = 2; + } + /* We step the Y, U, and V by two. */ + else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=2+.5+.5) / 16.0) && + ((uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5)<=0x3000) && + ((uint16_t)((1/(H_scale_ratio*4*2)) * (1<<0xc) + 0.5)<=0x2000)) + { + *P1GroupSize = 4; + *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*2)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 2; + *P1StepSize = 2; + *P23StepSize = 2; + } + /* We step the Y by two and the U and V by four. */ + else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=2+.25+.25) / 16.0) && + ((uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5)<=0x3000) && + ((uint16_t)((1/(H_scale_ratio*4*4)) * (1<<0xc) + 0.5)<=0x2000)) + { + *P1GroupSize = 4; + *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*4)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 3; + *P1StepSize = 2; + *P23StepSize = 4; + } + /* We step the Y, U, and V by four. */ + else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=1+.25+.25) / 16.0) && + ((uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5)<=0x3000) && + ((uint16_t)((1/(H_scale_ratio*4*4)) * (1<<0xc) + 0.5)<=0x2000)) + { + *P1GroupSize = 4; + *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*4)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 3; + *P1StepSize = 4; + *P23StepSize = 4; + } + /* We would like to step the Y by four and the U and V by eight, but we can't mix step by 3 and step by 4 for packed modes */ + + /* We step the Y, U, and V by eight. */ + else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=.5+.125+.125) / 16.0) && + ((uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5)<=0x3000) && + ((uint16_t)((1/(H_scale_ratio*4*8)) * (1<<0xc) + 0.5)<=0x2000)) + { + *P1GroupSize = 4; + *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*4*8)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 4; + *P1StepSize = 8; + *P23StepSize = 8; + } + /* We step the Y by eight and the U and V by sixteen. */ + else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=.5+.0625+.0625) / 16.0) && + ((uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5)<=0x3000) && + ((uint16_t)((1/(H_scale_ratio*4*16)) * (1<<0xc) + 0.5)<=0x2000)) + { + *P1GroupSize = 4; + *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*4*16)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 5; + *P1StepSize = 8; + *P23StepSize = 16; + } + /* We step the Y, U, and V by sixteen. */ + else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=.25+.0625+.0625) / 16.0) && + ((uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5)<=0x3000) && + ((uint16_t)((1/(H_scale_ratio*4*16)) * (1<<0xc) + 0.5)<=0x2000)) + { + *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*4*16)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 5; + *P1StepSize = 16; + *P23StepSize = 16; + } + else + { + H_scale_ratio=(ClocksNeededFor16Pixels=.25+.0625+.0625) / 16; + *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*4*16)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 5; + *P1StepSize = 16; + *P23StepSize = 16; + } + break; + case 10: + case 11: + case 12: + case 13: + case 14: /* YUV12, VYUY422, YUYV422, YOverPkCRCB12, YWovenWithPkCRCB12 */ + /* We scale the Y, U, and V with the four tap filters */ + /* four tap on both (unless Y is too wide) */ + if ((H_scale_ratio>=(ClocksNeededFor16Pixels=8+4+4) / 16.0) && + !DisallowFourTapVertFiltering && !DisallowFourTapUVVertFiltering) + { /*0.75 */ + *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*2)) * (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+4+4) / 16.0) && + 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*2)) * (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+2+2) / 16.0) && + !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*2)) * (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+2+2) / 16.0) + { /*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*2)) * (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+1+1) / 16.0) + { /*0.312 */ + *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*2*2)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 2; + *P1StepSize = 1; + *P23StepSize = 2; + } + /* We step the Y, U, and V by two. */ + else if (H_scale_ratio>=(ClocksNeededFor16Pixels=2+1+1) / 16.0) + { + *P1GroupSize = 4; + *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*2)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 2; + *P1StepSize = 2; + *P23StepSize = 2; + } + /* We step the Y by two and the U and V by four. */ + else if (H_scale_ratio>=(ClocksNeededFor16Pixels=2+.5+.5) / 16.0) + { + *P1GroupSize = 4; + *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*4)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 3; + *P1StepSize = 2; + *P23StepSize = 4; + } + /* We step the Y, U, and V by four. */ + else if (H_scale_ratio>=(ClocksNeededFor16Pixels=1+.5+.5) / 16.0) + { + *P1GroupSize = 4; + *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*2*4)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 3; + *P1StepSize = 4; + *P23StepSize = 4; + } + /* We step the Y by four and the U and V by eight. */ + else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=1+.25+.25) / 16.0) && + (fieldvalue_OV0_SURFACE_FORMAT==10)) + { + *P1GroupSize = 4; + /* Can't mix step by 3 and step by 4 for packed modes */ + *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*2*8)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 4; + *P1StepSize = 4; + *P23StepSize = 8; + } + /* We step the Y, U, and V by eight. */ + else if (H_scale_ratio>=(ClocksNeededFor16Pixels=.5+.25+.25) / 16.0) + { + *P1GroupSize = 4; + *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*2*8)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 4; + *P1StepSize = 8; + *P23StepSize = 8; + } + /* We step the Y by eight and the U and V by sixteen. */ + else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=.5+.125+.125) / 16.0) && (fieldvalue_OV0_SURFACE_FORMAT==10)) + { + *P1GroupSize = 4; + /* Step by 5 not supported for packed modes */ + *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*2*16)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 5; + *P1StepSize = 8; + *P23StepSize = 16; + } + /* We step the Y, U, and V by sixteen. */ + else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=.25+.125+.125) / 16.0) && + (fieldvalue_OV0_SURFACE_FORMAT==10)) + { + *P1GroupSize = 4; + /* Step by 5 not supported for packed modes */ + *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*2*16)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 5; + *P1StepSize = 16; + *P23StepSize = 16; + } + else + { + if (fieldvalue_OV0_SURFACE_FORMAT==10) + { + H_scale_ratio=(ClocksNeededFor16Pixels=.25+.125+.125) / 16; + *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*2*16)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 5; + *P1StepSize = 16; + *P23StepSize = 16; + } + else + { + H_scale_ratio=(ClocksNeededFor16Pixels=.5+.25+.25) / 16; + *P1GroupSize = 4; + *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*2*8)) * (1<<0xc) + 0.5); + *val_OV0_P23_H_STEP_BY = 4; + *P1StepSize = 8; + *P23StepSize = 8; + } + } + break; + default: break; + + } + besr.h_inc = (*(val_OV0_P1_H_INC)&0x3fff) | ((*(val_OV0_P23_H_INC)&0x3fff)<<16); + besr.step_by = (*(val_OV0_P1_H_STEP_BY)&0x7) | ((*(val_OV0_P23_H_STEP_BY)&0x7)<<8); +} + +/* ********************************************************* */ +/* ** Setup Black Bordering */ +/* ********************************************************* */ + +static void ComputeBorders( vidix_playback_t *config, int VertUVSubSample ) +{ + double tempBLANK_LINES_AT_TOP; + unsigned TopLine,BottomLine,SourceLinesUsed,TopUVLine,BottomUVLine,SourceUVLinesUsed; + uint32_t val_OV0_P1_ACTIVE_LINES_M1,val_OV0_P1_BLNK_LN_AT_TOP_M1; + uint32_t val_OV0_P23_ACTIVE_LINES_M1,val_OV0_P23_BLNK_LN_AT_TOP_M1; + + if (floor(config->src.y)<0) { + tempBLANK_LINES_AT_TOP = -floor(config->src.y); + TopLine = 0; + } + else { + tempBLANK_LINES_AT_TOP = 0; + TopLine = (int)floor(config->src.y); + } + /* Round rSrcBottom up and subtract one */ + if (ceil(config->src.y+config->src.h) > config->src.h) + { + BottomLine = config->src.h - 1; + } + else + { + BottomLine = (int)ceil(config->src.y+config->src.h) - 1; + } + + if (BottomLine >= TopLine) + { + SourceLinesUsed = BottomLine - TopLine + 1; + } + else + { + /*CYCACC_ASSERT(0, "SourceLinesUsed less than or equal to zero.") */ + SourceLinesUsed = 1; + } + + { + int SourceHeightInPixels; + SourceHeightInPixels = BottomLine - TopLine + 1; + } + + val_OV0_P1_ACTIVE_LINES_M1 = SourceLinesUsed - 1; + val_OV0_P1_BLNK_LN_AT_TOP_M1 = ((int)tempBLANK_LINES_AT_TOP-1) & 0xfff; + + TopUVLine = ((int)(config->src.y/VertUVSubSample) < 0) ? 0: (int)(config->src.y/VertUVSubSample); /* Round rSrcTop down */ + BottomUVLine = (ceil(((config->src.y+config->src.h)/VertUVSubSample)) > (config->src.h/VertUVSubSample)) + ? (config->src.h/VertUVSubSample)-1 : (int)ceil(((config->src.y+config->src.h)/VertUVSubSample))-1; + + if (BottomUVLine >= TopUVLine) + { + SourceUVLinesUsed = BottomUVLine - TopUVLine + 1; + } + else + { + /*CYCACC_ASSERT(0, "SourceUVLinesUsed less than or equal to zero.") */ + SourceUVLinesUsed = 1; + } + val_OV0_P23_ACTIVE_LINES_M1 = SourceUVLinesUsed - 1; + val_OV0_P23_BLNK_LN_AT_TOP_M1 = ((int)(tempBLANK_LINES_AT_TOP/VertUVSubSample)-1) & 0x7ff; + besr.p1_blank_lines_at_top = (val_OV0_P1_BLNK_LN_AT_TOP_M1 & 0xfff) | + ((val_OV0_P1_ACTIVE_LINES_M1 & 0xfff) << 16); + besr.p23_blank_lines_at_top = (val_OV0_P23_BLNK_LN_AT_TOP_M1 & 0x7ff) | + ((val_OV0_P23_ACTIVE_LINES_M1 & 0x7ff) << 16); +} + + +static void ComputeXStartEnd( + int is_400, + uint32_t LeftPixel,uint32_t LeftUVPixel, + uint32_t MemWordsInBytes,uint32_t BytesPerPixel, + uint32_t SourceWidthInPixels, uint32_t P1StepSize, + uint32_t BytesPerUVPixel,uint32_t SourceUVWidthInPixels, + uint32_t P23StepSize, uint32_t *p1_x_start, uint32_t *p2_x_start ) +{ + uint32_t val_OV0_P1_X_START,val_OV0_P2_X_START,val_OV0_P3_X_START; + uint32_t val_OV0_P1_X_END,val_OV0_P2_X_END,val_OV0_P3_X_END; + /* ToDo_Active: At the moment we are not using iOV0_VID_BUF?_START_PIX, but instead // are using iOV0_P?_X_START and iOV0_P?_X_END. We should use "start pix" and // "width" to derive the start and end. */ + + val_OV0_P1_X_START = (int)LeftPixel % (MemWordsInBytes/BytesPerPixel); + val_OV0_P1_X_END = (int)((val_OV0_P1_X_START + SourceWidthInPixels - 1) / P1StepSize) * P1StepSize; + + val_OV0_P2_X_START = val_OV0_P2_X_END = 0; + switch (besr.surf_id) + { + case 9: + case 10: + case 13: + case 14: /* ToDo_Active: The driver must insure that the initial value is */ + /* a multiple of a power of two when decimating */ + val_OV0_P2_X_START = (int)LeftUVPixel % + (MemWordsInBytes/BytesPerUVPixel); + val_OV0_P2_X_END = (int)((val_OV0_P2_X_START + + SourceUVWidthInPixels - 1) / P23StepSize) * P23StepSize; + break; + case 11: + case 12: val_OV0_P2_X_START = (int)LeftUVPixel % (MemWordsInBytes/(BytesPerPixel*2)); + val_OV0_P2_X_END = (int)((val_OV0_P2_X_START + SourceUVWidthInPixels - 1) / P23StepSize) * P23StepSize; + break; + case 3: + case 4: val_OV0_P2_X_START = val_OV0_P1_X_START; + /* This value is needed only to allow proper setting of */ + /* val_OV0_PRESHIFT_P23_TO */ + /* val_OV0_P2_X_END = 0; */ + break; + case 6: val_OV0_P2_X_START = (int)LeftPixel % (MemWordsInBytes/BytesPerPixel); + val_OV0_P2_X_END = (int)((val_OV0_P1_X_START + SourceWidthInPixels - 1) / P23StepSize) * P23StepSize; + break; + default: /* insert debug statement here. */ + RADEON_ASSERT("unknown fourcc\n"); + break; + } + val_OV0_P3_X_START = val_OV0_P2_X_START; + val_OV0_P3_X_END = val_OV0_P2_X_END; + + besr.p1_x_start_end = (val_OV0_P1_X_END&0x7ff) | ((val_OV0_P1_X_START&0x7ff)<<16); + besr.p2_x_start_end = (val_OV0_P2_X_END&0x7ff) | ((val_OV0_P2_X_START&0x7ff)<<16); + besr.p3_x_start_end = (val_OV0_P3_X_END&0x7ff) | ((val_OV0_P3_X_START&0x7ff)<<16); + if(is_400) + { + besr.p2_x_start_end = 0; + besr.p3_x_start_end = 0; + } + *p1_x_start = val_OV0_P1_X_START; + *p2_x_start = val_OV0_P2_X_START; +} + +static void ComputeAccumInit( + uint32_t val_OV0_P1_X_START,uint32_t val_OV0_P2_X_START, + uint32_t val_OV0_P1_H_INC,uint32_t val_OV0_P23_H_INC, + uint32_t val_OV0_P1_H_STEP_BY,uint32_t val_OV0_P23_H_STEP_BY, + uint32_t CRT_V_INC, + uint32_t P1GroupSize, uint32_t P23GroupSize, + uint32_t val_OV0_P1_MAX_LN_IN_PER_LN_OUT, + uint32_t val_OV0_P23_MAX_LN_IN_PER_LN_OUT) +{ + uint32_t val_OV0_P1_H_ACCUM_INIT,val_OV0_PRESHIFT_P1_TO; + uint32_t val_OV0_P23_H_ACCUM_INIT,val_OV0_PRESHIFT_P23_TO; + uint32_t val_OV0_P1_V_ACCUM_INIT,val_OV0_P23_V_ACCUM_INIT; + /* 2.5 puts the kernal 50% of the way between the source pixel that is off screen */ + /* and the first on-screen source pixel. "(float)valOV0_P?_H_INC / (1<<0xc)" is */ + /* the distance (in source pixel coordinates) to the center of the first */ + /* destination pixel. Need to add additional pixels depending on how many pixels */ + /* are fetched at a time and how many pixels in a set are masked. */ + /* P23 values are always fetched in groups of two or four. If the start */ + /* pixel does not fall on the boundary, then we need to shift preshift for */ + /* some additional pixels */ + + { + double ExtraHalfPixel; + double tempAdditionalShift; + double tempP1HStartPoint; + double tempP23HStartPoint; + double tempP1Init; + double tempP23Init; + + if (besr.horz_pick_nearest) ExtraHalfPixel = 0.5; + else ExtraHalfPixel = 0.0; + tempAdditionalShift = val_OV0_P1_X_START % P1GroupSize + ExtraHalfPixel; + tempP1HStartPoint = tempAdditionalShift + 2.5 + ((float)val_OV0_P1_H_INC / (1<<0xd)); + tempP1Init = (double)((int)(tempP1HStartPoint * (1<<0x5) + 0.5)) / (1<<0x5); + + /* P23 values are always fetched in pairs. If the start pixel is odd, then we */ + /* need to shift an additional pixel */ + /* Note that if the pitch is a multiple of two, and if we store fields using */ + /* the traditional planer format where the V plane and the U plane share the */ + /* same pitch, then OverlayRegFields->val_OV0_P2_X_START % P23Group */ + /* OverlayRegFields->val_OV0_P3_X_START % P23GroupSize. Either way */ + /* it is a requirement that the U and V start on the same polarity byte */ + /* (even or odd). */ + tempAdditionalShift = val_OV0_P2_X_START % P23GroupSize + ExtraHalfPixel; + tempP23HStartPoint = tempAdditionalShift + 2.5 + ((float)val_OV0_P23_H_INC / (1<<0xd)); + tempP23Init = (double)((int)(tempP23HStartPoint * (1<<0x5) + 0.5)) / (1 << 0x5); + val_OV0_P1_H_ACCUM_INIT = (int)((tempP1Init - (int)tempP1Init) * (1<<0x5)); + val_OV0_PRESHIFT_P1_TO = (int)tempP1Init; + val_OV0_P23_H_ACCUM_INIT = (int)((tempP23Init - (int)tempP23Init) * (1<<0x5)); + val_OV0_PRESHIFT_P23_TO = (int)tempP23Init; + } + + /* ************************************************************** */ + /* ** Calculate values for initializing the vertical accumulators */ + /* ************************************************************** */ + + { + double ExtraHalfLine; + double ExtraFullLine; + double tempP1VStartPoint; + double tempP23VStartPoint; + + if (besr.vert_pick_nearest) ExtraHalfLine = 0.5; + else ExtraHalfLine = 0.0; + + if (val_OV0_P1_H_STEP_BY==0)ExtraFullLine = 1.0; + else ExtraFullLine = 0.0; + + tempP1VStartPoint = 1.5 + ExtraFullLine + ExtraHalfLine + ((float)CRT_V_INC / (1<<0xd)); + if (tempP1VStartPoint>2.5 + 2*ExtraFullLine) + { + tempP1VStartPoint = 2.5 + 2*ExtraFullLine; + } + val_OV0_P1_V_ACCUM_INIT = (int)(tempP1VStartPoint * (1<<0x5) + 0.5); + + if (val_OV0_P23_H_STEP_BY==0)ExtraFullLine = 1.0; + else ExtraFullLine = 0.0; + + switch (besr.surf_id) + { + case 10: + case 13: + case 14: tempP23VStartPoint = 1.5 + ExtraFullLine + ExtraHalfLine + + ((float)CRT_V_INC / (1<<0xe)); + break; + case 9: tempP23VStartPoint = 1.5 + ExtraFullLine + ExtraHalfLine + + ((float)CRT_V_INC / (1<<0xf)); + break; + case 3: + case 4: + case 6: + case 11: + case 12: tempP23VStartPoint = 0; + break; + default: tempP23VStartPoint = 0xFFFF;/* insert debug statement here */ + break; + } + + if (tempP23VStartPoint>2.5 + 2*ExtraFullLine) + { + tempP23VStartPoint = 2.5 + 2*ExtraFullLine; + } + + val_OV0_P23_V_ACCUM_INIT = (int)(tempP23VStartPoint * (1<<0x5) + 0.5); + } + besr.p1_h_accum_init = ((val_OV0_P1_H_ACCUM_INIT&0x1f)<<15) |((val_OV0_PRESHIFT_P1_TO&0xf)<<28); + besr.p1_v_accum_init = (val_OV0_P1_MAX_LN_IN_PER_LN_OUT&0x3) |((val_OV0_P1_V_ACCUM_INIT&0x7ff)<<15); + besr.p23_h_accum_init= ((val_OV0_P23_H_ACCUM_INIT&0x1f)<<15) |((val_OV0_PRESHIFT_P23_TO&0xf)<<28); + besr.p23_v_accum_init= (val_OV0_P23_MAX_LN_IN_PER_LN_OUT&0x3)|((val_OV0_P23_V_ACCUM_INIT&0x3ff)<<15); +} + +typedef struct RangeAndCoefSet { + double Range; + signed char CoefSet[5][4]; +} RANGEANDCOEFSET; + +/* Filter Setup Routine */ +static void FilterSetup ( uint32_t val_OV0_P1_H_INC ) +{ + static RANGEANDCOEFSET ArrayOfSets[] = { + {0.25, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.26, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.27, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.28, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.29, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.30, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.31, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.32, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.33, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.34, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.35, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.36, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.37, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.38, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.39, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.40, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.41, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.42, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.43, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.44, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.45, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.46, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.47, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.48, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.49, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.50, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, + {0.51, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 2, 14, 14, 2}, }}, + {0.52, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 16, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }}, + {0.53, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 16, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }}, + {0.54, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 4, 17, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }}, + {0.55, {{ 7, 18, 7, 0}, { 6, 17, 9, 0}, { 4, 17, 11, 0}, { 3, 15, 13, 1}, { 1, 15, 15, 1}, }}, + {0.56, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, + {0.57, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, + {0.58, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, + {0.59, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, + {0.60, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, + {0.61, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, + {0.62, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, + {0.63, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, + {0.64, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, + {0.65, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }}, + {0.66, {{ 7, 18, 8, -1}, { 6, 18, 10, -2}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }}, + {0.67, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 18, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }}, + {0.68, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }}, + {0.69, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }}, + {0.70, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }}, + {0.71, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }}, + {0.72, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, + {0.73, {{ 7, 20, 7, -2}, { 4, 21, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, + {0.74, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, + {0.75, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 1, 21, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, + {0.76, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 1, 21, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, + {0.77, {{ 6, 22, 6, -2}, { 3, 22, 9, -2}, { 1, 22, 12, -3}, { 0, 19, 15, -2}, {-2, 18, 18, -2}, }}, + {0.78, {{ 6, 21, 6, -1}, { 3, 22, 9, -2}, { 1, 22, 12, -3}, { 0, 19, 15, -2}, {-2, 18, 18, -2}, }}, + {0.79, {{ 5, 23, 5, -1}, { 3, 22, 9, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }}, + {0.80, {{ 5, 23, 5, -1}, { 3, 23, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }}, + {0.81, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }}, + {0.82, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-3, 19, 19, -3}, }}, + {0.83, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, + {0.84, {{ 4, 25, 4, -1}, { 1, 25, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, + {0.85, {{ 4, 25, 4, -1}, { 1, 25, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, + {0.86, {{ 4, 24, 4, 0}, { 1, 25, 7, -1}, {-1, 24, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, + {0.87, {{ 4, 24, 4, 0}, { 1, 25, 7, -1}, {-1, 24, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, + {0.88, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-1, 24, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, + {0.89, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-1, 24, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, + {0.90, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, + {0.91, {{ 3, 26, 3, 0}, { 0, 27, 6, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, + {0.92, {{ 2, 28, 2, 0}, { 0, 27, 6, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, + {0.93, {{ 2, 28, 2, 0}, { 0, 26, 6, 0}, {-2, 25, 10, -1}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, + {0.94, {{ 2, 28, 2, 0}, { 0, 26, 6, 0}, {-2, 25, 10, -1}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, + {0.95, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }}, + {0.96, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }}, + {0.97, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }}, + {0.98, {{ 1, 30, 1, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }}, + {0.99, {{ 0, 32, 0, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-4, 24, 14, -2}, {-3, 19, 19, -3}, }}, + {1.00, {{ 0, 32, 0, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-4, 24, 14, -2}, {-3, 19, 19, -3}, }} + }; + + double DSR; + + unsigned ArrayElement; + + DSR = (double)(1<<0xc)/val_OV0_P1_H_INC; + if (DSR<.25) DSR=.25; + if (DSR>1) DSR=1; + + ArrayElement = (int)((DSR-0.25) * 100); + besr.four_tap_coeff[0] = (ArrayOfSets[ArrayElement].CoefSet[0][0] & 0xf) | + ((ArrayOfSets[ArrayElement].CoefSet[0][1] & 0x7f)<<8) | + ((ArrayOfSets[ArrayElement].CoefSet[0][2] & 0x7f)<<16) | + ((ArrayOfSets[ArrayElement].CoefSet[0][3] & 0xf)<<24); + besr.four_tap_coeff[1] = (ArrayOfSets[ArrayElement].CoefSet[1][0] & 0xf) | + ((ArrayOfSets[ArrayElement].CoefSet[1][1] & 0x7f)<<8) | + ((ArrayOfSets[ArrayElement].CoefSet[1][2] & 0x7f)<<16) | + ((ArrayOfSets[ArrayElement].CoefSet[1][3] & 0xf)<<24); + besr.four_tap_coeff[2] = (ArrayOfSets[ArrayElement].CoefSet[2][0] & 0xf) | + ((ArrayOfSets[ArrayElement].CoefSet[2][1] & 0x7f)<<8) | + ((ArrayOfSets[ArrayElement].CoefSet[2][2] & 0x7f)<<16) | + ((ArrayOfSets[ArrayElement].CoefSet[2][3] & 0xf)<<24); + besr.four_tap_coeff[3] = (ArrayOfSets[ArrayElement].CoefSet[3][0] & 0xf) | + ((ArrayOfSets[ArrayElement].CoefSet[3][1] & 0x7f)<<8) | + ((ArrayOfSets[ArrayElement].CoefSet[3][2] & 0x7f)<<16) | + ((ArrayOfSets[ArrayElement].CoefSet[3][3] & 0xf)<<24); + besr.four_tap_coeff[4] = (ArrayOfSets[ArrayElement].CoefSet[4][0] & 0xf) | + ((ArrayOfSets[ArrayElement].CoefSet[4][1] & 0x7f)<<8) | + ((ArrayOfSets[ArrayElement].CoefSet[4][2] & 0x7f)<<16) | + ((ArrayOfSets[ArrayElement].CoefSet[4][3] & 0xf)<<24); +/* + For more details, refer to Microsoft's draft of PC99. +*/ +} + +/* The minimal value of horizontal scale ratio when hard coded coefficients + are suitable for the best quality. */ +/* FIXME: Should it be 0.9 for Rage128 ??? */ +const double MinHScaleHard=0.75; + static int radeon_vid_init_video( vidix_playback_t *config ) { - uint32_t i,tmp,src_w,src_h,dest_w,dest_h,pitch,h_inc,step_by,left,leftUV,top; - int is_400,is_410,is_420,is_rgb32,is_rgb,best_pitch,mpitch; + double V_scale_ratio; + uint32_t i,src_w,src_h,dest_w,dest_h,pitch,left,leftUV,top,h_inc; + uint32_t val_OV0_P1_H_INC,val_OV0_P1_H_STEP_BY,val_OV0_P23_H_INC,val_OV0_P23_H_STEP_BY; + uint32_t val_OV0_P1_X_START,val_OV0_P2_X_START; + uint32_t val_OV0_P1_MAX_LN_IN_PER_LN_OUT,val_OV0_P23_MAX_LN_IN_PER_LN_OUT; + uint32_t CRT_V_INC; + uint32_t BytesPerOctWord,LogMemWordsInBytes,MemWordsInBytes,LogTileWidthInMemWords; + uint32_t TileWidthInMemWords,TileWidthInBytes,LogTileHeight,TileHeight; + uint32_t PageSizeInBytes,OV0LB_Rows; + uint32_t SourceWidthInMemWords,SourceUVWidthInMemWords; + uint32_t SourceWidthInPixels,SourceUVWidthInPixels; + uint32_t RightPixel,RightUVPixel,LeftPixel,LeftUVPixel; + int is_400,is_410,is_420,best_pitch,mpitch; + int horz_repl_factor,interlace_factor; + int BytesPerPixel,BytesPerUVPixel,HorzUVSubSample,VertUVSubSample; + int DisallowFourTapVertFiltering,DisallowFourTapUVVertFiltering; + radeon_vid_stop_video(); left = config->src.x << 16; top = config->src.y << 16; src_h = config->src.h; src_w = config->src.w; - is_400 = is_410 = is_420 = is_rgb32 = is_rgb = 0; + is_400 = is_410 = is_420 = 0; if(config->fourcc == IMGFMT_YV12 || config->fourcc == IMGFMT_I420 || config->fourcc == IMGFMT_IYUV) is_420 = 1; if(config->fourcc == IMGFMT_YVU9 || config->fourcc == IMGFMT_IF09) is_410 = 1; if(config->fourcc == IMGFMT_Y800) is_400 = 1; - if(config->fourcc == IMGFMT_RGB32 || - config->fourcc == IMGFMT_BGR32) is_rgb32 = 1; - if(config->fourcc == IMGFMT_RGB32 || - config->fourcc == IMGFMT_BGR32 || - config->fourcc == IMGFMT_RGB24 || - config->fourcc == IMGFMT_BGR24 || - config->fourcc == IMGFMT_RGB16 || - config->fourcc == IMGFMT_BGR16 || - config->fourcc == IMGFMT_RGB15 || - config->fourcc == IMGFMT_BGR15) is_rgb = 1; best_pitch = radeon_query_pitch(config->fourcc,&config->src.pitch); mpitch = best_pitch-1; + BytesPerOctWord = 16; + LogMemWordsInBytes = 4; + MemWordsInBytes = 1<<LogMemWordsInBytes; + LogTileWidthInMemWords = 2; + TileWidthInMemWords = 1<<LogTileWidthInMemWords; + TileWidthInBytes = 1<<(LogTileWidthInMemWords+LogMemWordsInBytes); + LogTileHeight = 4; + TileHeight = 1<<LogTileHeight; + PageSizeInBytes = 64*MemWordsInBytes; + OV0LB_Rows = 96; + h_inc = 1; switch(config->fourcc) { /* 4:0:0*/ @@ -1409,25 +2484,320 @@ static int radeon_vid_init_video( vidix_playback_t *config ) config->dest.pitch.v = best_pitch; break; /* 4:2:2 */ - default: /* RGB15, RGB16, YVYU, UYVY, YUY2 */ + + default: /* RGB15, RGB16, YVYU, UYVY, YUY2 */ pitch = ((src_w*2) + mpitch) & ~mpitch; config->dest.pitch.y = config->dest.pitch.u = config->dest.pitch.v = best_pitch; break; } + besr.load_prg_start=0; + besr.swap_uv=0; + switch(config->fourcc) + { + case IMGFMT_RGB15: + besr.swap_uv=1; + case IMGFMT_BGR15: besr.surf_id = SCALER_SOURCE_15BPP>>8; + besr.load_prg_start = 1; + break; + case IMGFMT_RGB16: + besr.swap_uv=1; + case IMGFMT_BGR16: besr.surf_id = SCALER_SOURCE_16BPP>>8; + besr.load_prg_start = 1; + break; + case IMGFMT_RGB32: + besr.swap_uv=1; + case IMGFMT_BGR32: besr.surf_id = SCALER_SOURCE_32BPP>>8; + besr.load_prg_start = 1; + break; + /* 4:1:0*/ + case IMGFMT_IF09: + case IMGFMT_YVU9: besr.surf_id = SCALER_SOURCE_YUV9>>8; + break; + /* 4:0:0*/ + case IMGFMT_Y800: + /* 4:2:0 */ + case IMGFMT_IYUV: + case IMGFMT_I420: + case IMGFMT_YV12: besr.surf_id = SCALER_SOURCE_YUV12>>8; + break; + /* 4:2:2 */ + case IMGFMT_YVYU: + case IMGFMT_UYVY: besr.surf_id = SCALER_SOURCE_YVYU422>>8; + break; + case IMGFMT_YUY2: + default: besr.surf_id = SCALER_SOURCE_VYUY422>>8; + break; + } + switch (besr.surf_id) + { + case 3: + case 4: + case 11: + case 12: BytesPerPixel = 2; + break; + case 6: BytesPerPixel = 4; + break; + case 9: + case 10: + case 13: + case 14: BytesPerPixel = 1; + break; + default: BytesPerPixel = 0;/*insert a debug statement here. */ + break; + } + switch (besr.surf_id) + { + case 3: + case 4: BytesPerUVPixel = 0; + break;/* In RGB modes, the BytesPerUVPixel is don't care */ + case 11: + case 12: BytesPerUVPixel = 2; + break; + case 6: BytesPerUVPixel = 0; + break; /* In RGB modes, the BytesPerUVPixel is don't care */ + case 9: + case 10: BytesPerUVPixel = 1; + break; + case 13: + case 14: BytesPerUVPixel = 2; + break; + default: BytesPerUVPixel = 0;/* insert a debug statement here. */ + break; + + } + switch (besr.surf_id) + { + case 3: + case 4: + case 6: HorzUVSubSample = 1; + break; + case 9: HorzUVSubSample = 4; + break; + case 10: + case 11: + case 12: + case 13: + case 14: HorzUVSubSample = 2; + break; + default: HorzUVSubSample = 0;/* insert debug statement here. */ + break; + } + switch (besr.surf_id) + { + case 3: + case 4: + case 6: + case 11: + case 12: VertUVSubSample = 1; + break; + case 9: VertUVSubSample = 4; + break; + case 10: + case 13: + case 14: VertUVSubSample = 2; + break; + default: VertUVSubSample = 0;/* insert debug statment here. */ + break; + } + DisallowFourTapVertFiltering = 0; /* Allow it by default */ + DisallowFourTapUVVertFiltering = 0; /* Allow it by default */ + LeftPixel = config->src.x; + RightPixel = config->src.w-1; + if(floor(config->src.x/HorzUVSubSample)<0) LeftUVPixel = 0; + else LeftUVPixel = (int)floor(config->src.x/HorzUVSubSample); + if(ceil((config->src.x+config->src.w)/HorzUVSubSample) > config->src.w/HorzUVSubSample) + RightUVPixel = config->src.w/HorzUVSubSample - 1; + else RightUVPixel = (int)ceil((config->src.x+config->src.w)/HorzUVSubSample) - 1; + /* Top, Bottom and Right Crops can be out of range. The driver will program the hardware + // to create a black border at the top and bottom. This is useful for DVD letterboxing. */ + SourceWidthInPixels = (int)(config->src.w + 1); + SourceUVWidthInPixels = (int)(RightUVPixel - LeftUVPixel + 1); + + SourceWidthInMemWords = (int)(ceil(RightPixel*BytesPerPixel / MemWordsInBytes) - + floor(LeftPixel*BytesPerPixel / MemWordsInBytes) + 1); + /* SourceUVWidthInMemWords means Source_U_or_V_or_UV_WidthInMemWords depending on whether the UV is packed together of not. */ + SourceUVWidthInMemWords = (int)(ceil(RightUVPixel*BytesPerUVPixel / + MemWordsInBytes) - floor(LeftUVPixel*BytesPerUVPixel / + MemWordsInBytes) + 1); + + switch (besr.surf_id) + { + case 9: + case 10: if ((ceil(SourceWidthInMemWords/2)-1) * 2 > OV0LB_Rows-1) + { + RADEON_ASSERT("ceil(SourceWidthInMemWords/2)-1) * 2 > OV0LB_Rows-1\n"); + } + else if ((SourceWidthInMemWords-1) * 2 > OV0LB_Rows-1) + { + DisallowFourTapVertFiltering = 1; + } + + if ((ceil(SourceUVWidthInMemWords/2)-1) * 4 + 1 > OV0LB_Rows-1) + { + /*CYCACC_ASSERT(0, "Image U plane width spans more octwords than supported by hardware.") */ + } + else if ((SourceUVWidthInMemWords-1) * 4 + 1 > OV0LB_Rows-1) + { + DisallowFourTapUVVertFiltering = 1; + } + + if ((ceil(SourceUVWidthInMemWords/2)-1) * 4 + 3 > OV0LB_Rows-1) + { + /*CYCACC_ASSERT(0, "Image V plane width spans more octwords than supported by hardware.") */ + } + else if ((SourceUVWidthInMemWords-1) * 4 + 3 > OV0LB_Rows-1) + { + DisallowFourTapUVVertFiltering = 1; + } + break; + case 13: + case 14: if ((ceil(SourceWidthInMemWords/2)-1) * 2 > OV0LB_Rows-1) + { + RADEON_ASSERT("ceil(SourceWidthInMemWords/2)-1) * 2 > OV0LB_Rows-1\n"); + } + else if ((SourceWidthInMemWords-1) * 2 > OV0LB_Rows-1) + { + DisallowFourTapVertFiltering = 1; + } + + if ((ceil(SourceUVWidthInMemWords/2)-1) * 2 + 1 > OV0LB_Rows-1) + { + /*CYCACC_ASSERT(0, "Image UV plane width spans more octwords than supported by hardware.") */ + } + else if ((SourceUVWidthInMemWords-1) * 2 + 1 > OV0LB_Rows-1) + { + DisallowFourTapUVVertFiltering = 1; + } + break; + case 3: + case 4: + case 6: + case 11: + case 12: if ((ceil(SourceWidthInMemWords/2)-1) > OV0LB_Rows-1) + { + RADEON_ASSERT("(ceil(SourceWidthInMemWords/2)-1) > OV0LB_Rows-1\n") + } + else if ((SourceWidthInMemWords-1) > OV0LB_Rows-1) + { + DisallowFourTapVertFiltering = 1; + } + break; + default: /* insert debug statement here. */ + break; + } dest_w = config->dest.w; dest_h = config->dest.h; if(radeon_is_dbl_scan()) dest_h *= 2; besr.dest_bpp = radeon_vid_get_dbpp(); besr.fourcc = config->fourcc; - besr.v_inc = (src_h << 20) / dest_h; - if(radeon_is_interlace()) besr.v_inc *= 2; - h_inc = (src_w << 12) / dest_w; - step_by = 1; - while(h_inc >= (2 << 12)) { - step_by++; - h_inc >>= 1; + if(radeon_is_interlace()) interlace_factor = 2; + else interlace_factor = 1; + /* TODO: must be checked in doublescan mode!!! */ + horz_repl_factor = 1 << (uint32_t)((INPLL(VCLK_ECP_CNTL) & 0x300) >> 8); + H_scale_ratio = (double)ceil(((double)dest_w+1)/horz_repl_factor)/src_w; + V_scale_ratio = (double)(dest_h+1)/src_h; + if(H_scale_ratio < 0.5 && V_scale_ratio < 0.5) + { + val_OV0_P1_MAX_LN_IN_PER_LN_OUT = 3; + val_OV0_P23_MAX_LN_IN_PER_LN_OUT = 2; + } + else + if(H_scale_ratio < 1 && V_scale_ratio < 1) + { + val_OV0_P1_MAX_LN_IN_PER_LN_OUT = 2; + val_OV0_P23_MAX_LN_IN_PER_LN_OUT = 1; + } + else + { + val_OV0_P1_MAX_LN_IN_PER_LN_OUT = 1; + val_OV0_P23_MAX_LN_IN_PER_LN_OUT = 1; + } + /* N.B.: Indeed it has 6.12 format but shifted on 8 to the left!!! */ + besr.v_inc = (uint16_t)((1./V_scale_ratio)*(1<<12)*interlace_factor+0.5); + CRT_V_INC = besr.v_inc/interlace_factor; + besr.v_inc <<= 8; + { + int ThereIsTwoTapVerticalFiltering,DoNotUseMostRecentlyFetchedLine; + int P1GroupSize; + int P23GroupSize; + int P1StepSize; + int P23StepSize; + + Calc_H_INC_STEP_BY( + besr.surf_id, + H_scale_ratio, + DisallowFourTapVertFiltering, + DisallowFourTapUVVertFiltering, + &val_OV0_P1_H_INC, + &val_OV0_P1_H_STEP_BY, + &val_OV0_P23_H_INC, + &val_OV0_P23_H_STEP_BY, + &P1GroupSize, + &P1StepSize, + &P23StepSize); + + if(H_scale_ratio > MinHScaleHard) + { + h_inc = (src_w << 12) / dest_w; + besr.step_by = 0x0101; + switch (besr.surf_id) + { + case 3: + case 4: + case 6: + besr.h_inc = (h_inc)|(h_inc<<16); + break; + case 9: + besr.h_inc = h_inc | ((h_inc >> 2) << 16); + break; + default: + besr.h_inc = h_inc | ((h_inc >> 1) << 16); + break; + } + } + + P23GroupSize = 2; /* Current vaue for all modes */ + + besr.horz_pick_nearest=0; + DoNotUseMostRecentlyFetchedLine=0; + ThereIsTwoTapVerticalFiltering = (val_OV0_P1_H_STEP_BY!=0) || (val_OV0_P23_H_STEP_BY!=0); + if (ThereIsTwoTapVerticalFiltering && DoNotUseMostRecentlyFetchedLine) + besr.vert_pick_nearest = 1; + else + besr.vert_pick_nearest = 0; + + ComputeXStartEnd(is_400,LeftPixel,LeftUVPixel,MemWordsInBytes,BytesPerPixel, + SourceWidthInPixels,P1StepSize,BytesPerUVPixel, + SourceUVWidthInPixels,P23StepSize,&val_OV0_P1_X_START,&val_OV0_P2_X_START); + + if(H_scale_ratio > MinHScaleHard) + { + unsigned tmp; + tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3); + besr.p1_h_accum_init = ((tmp << 4) & 0x000f8000) | + ((tmp << 12) & 0xf0000000); + + 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 = ((left >> 1) & 0x0001ffff) + 0x00028000 + (h_inc << 2); + besr.p23_h_accum_init = ((tmp << 4) & 0x000f8000) | + ((tmp << 12) & 0x70000000); + + tmp = ((top >> 1) & 0x0000ffff) + 0x00018000; + besr.p23_v_accum_init = (is_420||is_410) ? + ((tmp << 4) & OV0_P23_V_ACCUM_INIT_MASK) + |(OV0_P23_MAX_LN_IN_PER_LN_OUT & 1) : 0; + } + else + ComputeAccumInit( val_OV0_P1_X_START,val_OV0_P2_X_START, + val_OV0_P1_H_INC,val_OV0_P23_H_INC, + val_OV0_P1_H_STEP_BY,val_OV0_P23_H_STEP_BY, + CRT_V_INC,P1GroupSize,P23GroupSize, + val_OV0_P1_MAX_LN_IN_PER_LN_OUT, + val_OV0_P23_MAX_LN_IN_PER_LN_OUT); } /* keep everything in 16.16 */ @@ -1437,7 +2807,7 @@ static int radeon_vid_init_video( vidix_playback_t *config ) config->offsets[i] = config->offsets[i-1]+config->frame_size; if(is_420 || is_410 || is_400) { - uint32_t d1line,d2line,d3line; + uint32_t d1line,d2line,d3line; d1line = top*pitch; if(is_420) { @@ -1520,54 +2890,30 @@ static int radeon_vid_init_video( vidix_playback_t *config ) besr.vid_buf_base_adrs_v[i] = radeon_overlay_off + config->offsets[i] + config->offset.y; } } - - tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3); - besr.p1_h_accum_init = ((tmp << 4) & 0x000f8000) | - ((tmp << 12) & 0xf0000000); - - 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 = ((left >> 1) & 0x0001ffff) + 0x00028000 + (h_inc << 2); - besr.p23_h_accum_init = ((tmp << 4) & 0x000f8000) | - ((tmp << 12) & 0x70000000); - - tmp = ((top >> 1) & 0x0000ffff) + 0x00018000; - besr.p23_v_accum_init = (is_420||is_410) ? - ((tmp << 4) & OV0_P23_V_ACCUM_INIT_MASK) - |(OV0_P23_MAX_LN_IN_PER_LN_OUT & 1) : 0; leftUV = (left >> (is_410?18:17)) & 15; left = (left >> 16) & 15; - if(is_rgb) - besr.h_inc = (h_inc)|(h_inc<<16); - else - if(is_410) - besr.h_inc = h_inc | ((h_inc >> 2) << 16); - else - besr.h_inc = h_inc | ((h_inc >> 1) << 16); - besr.step_by = step_by | (step_by << 8); besr.y_x_start = (config->dest.x+X_ADJUST) | (config->dest.y << 16); besr.y_x_end = (config->dest.x + dest_w+X_ADJUST) | ((config->dest.y + dest_h) << 16); - besr.p1_blank_lines_at_top = P1_BLNK_LN_AT_TOP_M1_MASK|((src_h-1)<<16); - if(is_420 || is_410) - { - src_h = (src_h + 1) >> (is_410?2: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; + ComputeBorders(config,VertUVSubSample); besr.vid_buf_pitch0_value = pitch; besr.vid_buf_pitch1_value = is_410 ? pitch>>2 : is_420 ? pitch>>1 : pitch; - besr.p1_x_start_end = (src_w+left-1)|(left<<16); - if(is_400) - { - besr.p2_x_start_end = 0; - besr.p3_x_start_end = 0; - } + /* ********************************************************* */ + /* ** Calculate programmable coefficients as needed */ + /* ********************************************************* */ + + /* ToDo_Active: When in pick nearest mode, we need to program the filter tap zero */ + /* coefficients to 0, 32, 0, 0. Or use hard coded coefficients. */ + if(H_scale_ratio > MinHScaleHard) besr.filter_cntl |= FILTER_HARDCODED_COEF; else { - if(is_410||is_420) src_w>>=is_410?2:1; - besr.p2_x_start_end = (src_w+left-1)|(leftUV<<16); - besr.p3_x_start_end = besr.p2_x_start_end; + FilterSetup (val_OV0_P1_H_INC); + /* ToDo_Active: Must add the smarts into the driver to decide what type of filtering it */ + /* would like to do. For now, we let the test application decide. */ + besr.filter_cntl = FILTER_PROGRAMMABLE_COEF; + if(DisallowFourTapVertFiltering) + besr.filter_cntl |= FILTER_HARD_SCALE_VERT_Y; + if(DisallowFourTapUVVertFiltering) + besr.filter_cntl |= FILTER_HARD_SCALE_VERT_UV; } return 0; } @@ -1608,14 +2954,14 @@ static void radeon_compute_framesize(vidix_playback_t *info) info->frame_size = (info->frame_size+4095)&~4095; } -int vixConfigPlayback(vidix_playback_t *info) +int VIDIX_NAME(vixConfigPlayback)(vidix_playback_t *info) { unsigned rgb_size,nfr; uint32_t radeon_video_size; - if(!is_supported_fourcc(info->fourcc)) return ENOSYS; + if(!is_supported_fourcc(info->fourcc,info->src.w)) return ENOSYS; if(info->num_frames>VID_PLAY_MAXFRAMES) info->num_frames=VID_PLAY_MAXFRAMES; if(info->num_frames==1) besr.double_buff=0; - else besr.double_buff=1; + else besr.double_buff=1; radeon_compute_framesize(info); rgb_size = radeon_get_xres()*radeon_get_yres()*((radeon_vid_get_dbpp()+7)/8); @@ -1628,7 +2974,7 @@ int vixConfigPlayback(vidix_playback_t *info) Note: probably it's ont good idea to locate them in video memory but as initial release it's OK */ radeon_video_size -= radeon_ram_size * sizeof(bm_list_descriptor) / 4096; - radeon_dma_desc_base = pci_info.base0 + radeon_video_size; + radeon_dma_desc_base = (void *) pci_info.base0 + radeon_video_size; } #endif for(;nfr>0; nfr--) @@ -1655,7 +3001,7 @@ int vixConfigPlayback(vidix_playback_t *info) return 0; } -int vixPlaybackOn( void ) +int VIDIX_NAME(vixPlaybackOn)( void ) { #ifdef RAGE128 unsigned dw,dh; @@ -1670,13 +3016,13 @@ int vixPlaybackOn( void ) return 0; } -int vixPlaybackOff( void ) +int VIDIX_NAME(vixPlaybackOff)( void ) { radeon_vid_stop_video(); return 0; } -int vixPlaybackFrameSelect(unsigned frame) +int VIDIX_NAME(vixPlaybackFrameSelect)(unsigned frame) { uint32_t off[6]; int prev_frame= (frame-1+besr.vid_nbufs) % besr.vid_nbufs; @@ -1718,7 +3064,7 @@ vidix_video_eq_t equal = , 0, 0, 0, 0, 0, 0, 0, 0 }; -int vixPlaybackGetEq( vidix_video_eq_t * eq) +int VIDIX_NAME(vixPlaybackGetEq)( vidix_video_eq_t * eq) { memcpy(eq,&equal,sizeof(vidix_video_eq_t)); return 0; @@ -1727,13 +3073,13 @@ int vixPlaybackGetEq( vidix_video_eq_t * eq) #ifndef RAGE128 #define RTFSaturation(a) (1.0 + ((a)*1.0)/1000.0) #define RTFBrightness(a) (((a)*1.0)/2000.0) -#define RTFIntensity(a) (((a)*1.0)/2000.0) -#define RTFContrast(a) (1.0 + ((a)*1.0)/1000.0) +#define RTFIntensity(a) (((a)*1.0)/2000.0) +#define RTFContrast(a) (1.0 + ((a)*1.0)/1000.0) #define RTFHue(a) (((a)*3.1416)/1000.0) #define RTFCheckParam(a) {if((a)<-1000) (a)=-1000; if((a)>1000) (a)=1000;} #endif -int vixPlaybackSetEq( const vidix_video_eq_t * eq) +int VIDIX_NAME(vixPlaybackSetEq)( const vidix_video_eq_t * eq) { #ifdef RAGE128 int br,sat; @@ -1743,7 +3089,7 @@ int vixPlaybackSetEq( const vidix_video_eq_t * eq) if(eq->cap & VEQ_CAP_BRIGHTNESS) equal.brightness = eq->brightness; if(eq->cap & VEQ_CAP_CONTRAST) equal.contrast = eq->contrast; if(eq->cap & VEQ_CAP_SATURATION) equal.saturation = eq->saturation; - if(eq->cap & VEQ_CAP_HUE) equal.hue = eq->hue; + if(eq->cap & VEQ_CAP_HUE) equal.hue = eq->hue; if(eq->cap & VEQ_CAP_RGB_INTENSITY) { equal.red_intensity = eq->red_intensity; @@ -1778,7 +3124,7 @@ int vixPlaybackSetEq( const vidix_video_eq_t * eq) return 0; } -int vixPlaybackSetDeint( const vidix_deinterlace_t * info) +int VIDIX_NAME(vixPlaybackSetDeint)( const vidix_deinterlace_t * info) { unsigned sflg; switch(info->flags) @@ -1816,7 +3162,7 @@ int vixPlaybackSetDeint( const vidix_deinterlace_t * info) return 0; } -int vixPlaybackGetDeint( vidix_deinterlace_t * info) +int VIDIX_NAME(vixPlaybackGetDeint)( vidix_deinterlace_t * info) { if(!besr.deinterlace_on) info->flags = CFG_NON_INTERLACED; else @@ -1841,12 +3187,29 @@ static void set_gr_key( void ) switch(dbpp) { case 15: +#ifndef RAGE128 + if(RadeonFamily > 100) + besr.graphics_key_clr= + ((radeon_grkey.ckey.blue &0xF8)) + | ((radeon_grkey.ckey.green&0xF8)<<8) + | ((radeon_grkey.ckey.red &0xF8)<<16); + else +#endif besr.graphics_key_clr= ((radeon_grkey.ckey.blue &0xF8)>>3) | ((radeon_grkey.ckey.green&0xF8)<<2) | ((radeon_grkey.ckey.red &0xF8)<<7); break; case 16: +#ifndef RAGE128 + /* This test may be too general/specific */ + if(RadeonFamily > 100) + besr.graphics_key_clr= + ((radeon_grkey.ckey.blue &0xF8)) + | ((radeon_grkey.ckey.green&0xFC)<<8) + | ((radeon_grkey.ckey.red &0xF8)<<16); + else +#endif besr.graphics_key_clr= ((radeon_grkey.ckey.blue &0xF8)>>3) | ((radeon_grkey.ckey.green&0xFC)<<3) @@ -1874,7 +3237,7 @@ static void set_gr_key( void ) besr.ckey_cntl = VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_NE|CMP_MIX_AND; #else besr.graphics_key_msk=besr.graphics_key_clr; - besr.ckey_cntl = VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_EQ|CMP_MIX_AND; + besr.ckey_cntl = VIDEO_KEY_FN_TRUE|CMP_MIX_AND|GRAPHIC_KEY_FN_EQ; #endif } else @@ -1890,13 +3253,13 @@ static void set_gr_key( void ) OUTREG(OV0_KEY_CNTL,besr.ckey_cntl); } -int vixGetGrKeys(vidix_grkey_t *grkey) +int VIDIX_NAME(vixGetGrKeys)(vidix_grkey_t *grkey) { memcpy(grkey, &radeon_grkey, sizeof(vidix_grkey_t)); return(0); } -int vixSetGrKeys(const vidix_grkey_t *grkey) +int VIDIX_NAME(vixSetGrKeys)(const vidix_grkey_t *grkey) { memcpy(&radeon_grkey, grkey, sizeof(vidix_grkey_t)); set_gr_key(); @@ -1933,7 +3296,7 @@ printf("RADEON_DMA_TABLE[%i] %X %X %X %X\n",i,list[i].framebuf_offset,list[i].sy return 0; } -static int radeon_transfer_frame( void ) +static int radeon_transfer_frame( void ) { unsigned i; radeon_engine_idle(); @@ -1960,7 +3323,7 @@ static int radeon_transfer_frame( void ) } -int vixPlaybackCopyFrame( vidix_dma_t * dmai ) +int VIDIX_NAME(vixPlaybackCopyFrame)( vidix_dma_t * dmai ) { int retval; if(mlock(dmai->src,dmai->size) != 0) return errno; @@ -1970,7 +3333,7 @@ int vixPlaybackCopyFrame( vidix_dma_t * dmai ) return retval; } -int vixQueryDMAStatus( void ) +int VIDIX_NAME(vixQueryDMAStatus)( void ) { int bm_active; #if 1 //def RAGE128 |
