diff options
author | Jordan Crouse <jordan.crouse@amd.com> | 2007-03-07 18:14:34 -0700 |
---|---|---|
committer | Jordan Crouse <jordan.crouse@amd.com> | 2007-03-07 18:18:09 -0700 |
commit | b59bfdde9341ca9014e00795e344ac64b5b91b8c (patch) | |
tree | 1d85f4420e42e2f55500872e8cde05ebcdf5ef9e | |
parent | d2f53b7c576c91f07f55b62b0020be1d0ab358dc (diff) |
[MAJOR UPDATE] Geode LX driver
This is a major re-vamping of the Geode LX driver to support EXA, RandR,
and advanced xserver features. The GX and LX drivers now share the similar
streamlined infrastructure, and acceleration. The LX driver also adds
features the GX does not have, such as accelerated rotations and
far better composite support.
This provides the basis for the rotation and acceleration enhancements.
-rw-r--r-- | src/Makefile.am | 8 | ||||
-rw-r--r-- | src/amd.h | 391 | ||||
-rw-r--r-- | src/amd_blend.h | 62 | ||||
-rw-r--r-- | src/amd_common.c | 158 | ||||
-rw-r--r-- | src/amd_driver.c | 64 | ||||
-rw-r--r-- | src/amd_gx_accel.c | 155 | ||||
-rw-r--r-- | src/amd_gx_dcon.c | 4 | ||||
-rw-r--r-- | src/amd_gx_driver.c | 2166 | ||||
-rw-r--r-- | src/amd_gx_video.c | 47 | ||||
-rw-r--r-- | src/amd_lx_accel.c | 1563 | ||||
-rw-r--r-- | src/amd_lx_cursor.c | 205 | ||||
-rw-r--r-- | src/amd_lx_dga.c | 398 | ||||
-rw-r--r-- | src/amd_lx_driver.c | 3738 | ||||
-rw-r--r-- | src/amd_lx_exa.c | 1034 | ||||
-rw-r--r-- | src/amd_lx_randr.c | 331 | ||||
-rw-r--r-- | src/amd_lx_rotate.c | 246 | ||||
-rw-r--r-- | src/amd_lx_shadow.c | 453 | ||||
-rw-r--r-- | src/amd_lx_vga.c | 7 | ||||
-rw-r--r-- | src/amd_lx_video.c | 2079 | ||||
-rw-r--r-- | src/cim/cim_gp.c | 190 | ||||
-rw-r--r-- | src/cim/cim_rtns.h | 5 |
21 files changed, 5283 insertions, 8021 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index e22c601..02525e3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -40,10 +40,12 @@ amd_drv_ladir = @moduledir@/drivers amd_drv_la_SOURCES = \ amd.h \ + amd_blend.h \ amd_fourcc.h \ build_num.h \ cim_dev.h \ amd_driver.c \ + amd_common.c \ amd_gx_driver.c\ amd_gx_accel.c \ amd_gx_cursor.c \ @@ -55,12 +57,12 @@ amd_drv_la_SOURCES = \ durango.c \ panel.c \ amd_lx_driver.c \ - amd_lx_accel.c \ amd_lx_cursor.c \ - amd_lx_dga.c \ amd_lx_video.c \ - amd_lx_shadow.c \ amd_lx_regacc.c \ + amd_lx_rotate.c \ + amd_lx_randr.c \ + amd_lx_exa.c \ cimarron.c EXTRA_DIST = \ @@ -1,5 +1,5 @@ -/* - * Copyright (c) 2006 Advanced Micro Devices, Inc. + /* + * (c) 2006 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -230,61 +230,138 @@ typedef struct _VESARec } VESARec; -/* output enable types */ -#define LX_OT_CRT 0x0001 -#define LX_OT_FP 0x0002 -#define LX_OT_VOP 0x0004 -#define LX_OT_DRGB 0x0008 +#define OUTPUT_PANEL 0x01 +#define OUTPUT_CRT 0x02 +#define OUTPUT_TV 0x04 +#define OUTPUT_VOP 0x08 typedef struct _geodeRec { - /* Private struct for the server */ - unsigned long cpu_version; - unsigned long cpu_revision; - unsigned long vid_version; - INIT_BASE_ADDRESSES InitBaseAddress; - - EntityInfoPtr pEnt; - ScreenBlockHandlerProcPtr BlockHandler; /* needed for video */ - int DetectedChipSet; - int Chipset; -#ifdef HAVE_LX - int cimFd; - unsigned long CmdBfrOffset; - unsigned long CmdBfrSize; - unsigned int EnabledOutput; - unsigned long FBTop; -#endif - unsigned long FBLinearAddr; - unsigned char *FBBase; - unsigned long FBAvail; - unsigned long FBOffset; - unsigned long FBSize; - unsigned long maxWidth, maxHeight; - unsigned int cpu_reg_size; - unsigned int gp_reg_size; - unsigned int vid_reg_size; -#ifdef HAVE_LX - unsigned int vg_reg_size; - unsigned int vip_reg_size; -#endif - int Pitch; /* display FB pitch */ - int AccelPitch; /* accel pitch (may be ShadowPitch) */ - - /** new **/ - int displayPitch; /* The pitch ofthe visible area */ - int shadowPitch; /* The pitch of the shadow area */ - int displayOffset; /* The offset of the visible area */ - int displaySize; /* The size of the visibile area */ - - Bool HWCursor; - Bool NoAccel; - Bool CustomMode; - Bool useVGA; - unsigned long VideoKey; - + /* Common */ + + int Output; /* Bitmask indicating the valid output options */ + + Bool HWCursor; + Bool NoAccel; + Bool useVGA; + Bool VGAActive; /* Flag indicating if LX VGA is active */ + Bool Compression; + Bool useEXA; + + int rotation; + int displayWidth; + Bool starting; + Bool tryCompression; + Bool tryHWCursor; + unsigned int shadowSize; + unsigned int shadowOffset; + + DisplayModePtr curMode; + VG_COMPRESSION_DATA CBData; + + unsigned long CursorStartOffset; + unsigned int CursorSize; + xf86CursorInfoPtr CursorInfo; + int CursorXHot; + int CursorYHot; + + /* Geometry information */ + unsigned int maxWidth; /* Maximum possible width of the screen */ + unsigned int maxHeight; /* Maximum possible height of the screen */ + + int Pitch; /* display FB pitch */ + + int displayPitch; /* The pitch ofthe visible area */ + int displayOffset; /* The offset of the visible area */ + int displaySize; /* The size of the visibile area */ + + int PanelX; + int PanelY; + + /* Framebuffer memory */ + + unsigned long FBLinearAddr; + unsigned char *FBBase; + unsigned int FBAvail; + unsigned int FBOffset; + unsigned int FBSize; + + /* Video information */ + int video_x; + int video_y; + short video_w; + short video_h; + short video_srcw; + short video_srch; + short video_dstw; + short video_dsth; + int video_id; + int video_offset; + ScrnInfoPtr video_scrnptr; + BOOL OverlayON; + int videoKey; + + /* EXA structures */ + + ExaDriverPtr pExa; + unsigned int exaBfrOffset; + unsigned int exaBfrSz; + + /* XAA structures */ + unsigned char **AccelImageWriteBuffers; + int NoOfImgBuffers; + unsigned char **AccelColorExpandBuffers; + int NoOfColorExpandLines; + XAAInfoRecPtr AccelInfoRec; + + /* Other structures */ + + EntityInfoPtr pEnt; + ScreenBlockHandlerProcPtr BlockHandler; /* needed for video */ + XF86VideoAdaptorPtr adaptor; + + /* State save structures */ + + gfx_vga_struct FBgfxVgaRegs; + TVTIMING FBtvtiming; + GFX_DISPLAYTIMING FBgfxdisplaytiming; + CIM_DISPLAYTIMING FBcimdisplaytiming; + + unsigned int FBTVActive; + unsigned int FBSupport; + unsigned long FBDisplayOffset; + unsigned long PrevDisplayOffset; + + VESARec *vesa; + + int FBCompressionEnable; + VG_COMPRESSION_DATA FBCBData; + VG_CURSOR_DATA FBCursor; + unsigned long FBCompressionOffset; + unsigned short FBCompressionPitch; + unsigned short FBCompressionSize; + + /* Save the Cursor offset of the FB */ + unsigned long FBCursorOffset; + unsigned char FBBIOSMode; + + /* Hooks */ + + void (*WritePixmap) (ScrnInfoPtr pScrni, int x, int y, int w, int h, + unsigned char *src, int srcwidth, int rop, + unsigned int planemask, int trans, int bpp, int depth); + + void (*PointerMoved) (int index, int x, int y); + CloseScreenProcPtr CloseScreen; + Bool (*CreateScreenResources)(ScreenPtr); + + /* LX only */ + + unsigned long CmdBfrOffset; + unsigned long CmdBfrSize; + +#ifdef HAVE_TVSUPPORT Bool TVSupport; -#ifdef HAVE_LX int tv_encoder; int tv_bus_fmt; int tv_flags; @@ -296,159 +373,25 @@ typedef struct _geodeRec int tv_vsync_select; int tvox, tvoy; - int FPBiosResX, FPBiosResY; - int FPGeomDstSet, FPGeomDstX, FPGeomDstY; - int FPGeomActSet, FPGeomActX, FPGeomActY; -#endif -#ifdef HAVE_GX TVPARAMS TvParam; int TVOx, TVOy, TVOw, TVOh; Bool TV_Overscan_On; - - Bool Panel; - - /* Flatpanel support from Bios */ - int FPBX; /* xres */ - int FPBY; /* yres */ - int FPBB; /* bpp */ - int FPBF; /* freq */ -#endif - - int Rotate; - void (*Rotation) (int x, int y, int w, int h, int *newX, int *newY); - void (*RBltXlat) (int x, int y, int w, int h, int *newX, int *newY); - -#ifdef HAVE_GX - void (*WritePixmap) (ScrnInfoPtr pScrni, int x, int y, int w, int h, - unsigned char *src, int srcwidth, int rop, - unsigned int planemask, int trans, int bpp, int depth); -#endif - - Bool ShadowFB; - -#ifdef HAVE_LX - unsigned char *ShadowPtr; - int ShadowSize; - int ShadowPitch; - int ShadowInFBMem; -#endif - - int orig_virtX; /* original */ - int orig_virtY; - int HDisplay; /* rotated */ - int VDisplay; - - void (*PointerMoved) (int index, int x, int y); - /* CloseScreen function. */ - CloseScreenProcPtr CloseScreen; - - Bool Compression; -#ifdef HAVE_LX - VG_COMPRESSION_DATA CBData; #endif -#ifdef HAVE_GX - unsigned int CBOffset; - unsigned int CBPitch; - unsigned int CBSize; -#endif - unsigned long CursorStartOffset; - unsigned int CursorSize; - xf86CursorInfoPtr CursorInfo; - int CursorXHot; - int CursorYHot; - unsigned long OffscreenStartOffset; - unsigned int OffscreenSize; - - /***Image Write structures ***/ - - /* offset in video memory for ImageWrite Buffers */ - unsigned char **AccelImageWriteBuffers; - int NoOfImgBuffers; - unsigned char **AccelColorExpandBuffers; - int NoOfColorExpandLines; - -/*****************************************/ -/* Saved Console State */ -#ifdef HAVE_GX - gfx_vga_struct FBgfxVgaRegs; - TVTIMING FBtvtiming; - GFX_DISPLAYTIMING FBgfxdisplaytiming; -#endif -#ifdef HAVE_LX - CIM_DISPLAYTIMING FBcimdisplaytiming; -#endif - int FBVGAActive; - unsigned int FBTVActive; - unsigned int FBSupport; - unsigned long FBDisplayOffset; - unsigned long PrevDisplayOffset; - - VESARec *vesa; - - /* compression */ - int FBCompressionEnable; -#ifdef HAVE_LX - VG_COMPRESSION_DATA FBCBData; - VG_CURSOR_DATA FBCursor; -#endif -#ifdef HAVE_GX - unsigned long FBCompressionOffset; - unsigned short FBCompressionPitch; - unsigned short FBCompressionSize; - - /* Save the Cursor offset of the FB */ - unsigned long FBCursorOffset; -#endif - unsigned char FBBIOSMode; -/*****************************************/ - - XAAInfoRecPtr AccelInfoRec; - - DGAModePtr DGAModes; - int numDGAModes; - Bool DGAactive; - int DGAViewportStatus; -/*****************************************/ - int video_x; - int video_y; - short video_w; - short video_h; - short video_srcw; - short video_srch; - short video_dstw; - short video_dsth; - int video_id; - int video_offset; - ScrnInfoPtr video_scrnptr; - BOOL OverlayON; - - int videoKey; - XF86VideoAdaptorPtr adaptor; - Bool useEXA; -#if XF86EXA - ExaDriverPtr pExa; - unsigned int exaBfrOffset; - unsigned int exaBfrSz; - unsigned int cpySrcOffset; - int cpySrcPitch, cpySrcBpp; - int cpyDx, cpyDy; - unsigned int cmpSrcOffset; - int cmpSrcPitch, cmpSrcBpp; - unsigned int cmpSrcFmt, cmpDstFmt; - int cmpOp; -#endif - - DisplayModePtr curMode; - int rotation; - int displayWidth; - Bool starting; - Bool tryCompression; - Bool tryHWCursor; - unsigned int shadowSize; - unsigned int shadowOffset; - - Bool (*CreateScreenResources)(ScreenPtr); + + /* To be killed! */ + + int FBVGAActive; + unsigned int cpySrcOffset; + int cpySrcPitch, cpySrcBpp; + int cpyDx, cpyDy; + unsigned int cmpSrcOffset; + int cmpSrcPitch, cmpSrcBpp; + unsigned int cmpSrcFmt, cmpDstFmt; + int cmpOp; + + Bool Panel; + } GeodeRec, *GeodePtr; @@ -460,23 +403,16 @@ enum LX_OPTION_HW_CURSOR, LX_OPTION_NOCOMPRESSION, LX_OPTION_NOACCEL, - LX_OPTION_TV_ENCODER, - LX_OPTION_TV_BUS_FMT, - LX_OPTION_TV_FLAGS, - LX_OPTION_TV_601_FLAGS, - LX_OPTION_TV_VSYNC_SELECT, - LX_OPTION_TV_CONVERSION, + LX_OPTION_ACCEL_METHOD, + LX_OPTION_EXA_SCRATCH_BFRSZ, + LX_OPTION_TV_SUPPORT, + LX_OPTION_TV_OUTPUT, LX_OPTION_TV_OVERSCAN, - LX_OPTION_SHADOW_FB, LX_OPTION_ROTATE, - LX_OPTION_FLATPANEL, - LX_OPTION_CRTENABLE, + LX_OPTION_NOPANEL, LX_OPTION_COLOR_KEY, - LX_OPTION_OSM_IMG_BUFS, - LX_OPTION_OSM_CLR_BUFS, - LX_OPTION_CUSTOM_MODE, - LX_OPTION_FP_DEST_GEOM, - LX_OPTION_FP_ACTIVE_GEOM, + LX_OPTION_FBSIZE, + LX_OPTION_PANEL_GEOMETRY, LX_OPTION_DONT_PROGRAM } LX_GeodeOpts; @@ -517,4 +453,29 @@ GX_GeodeOpts; #define DCON_DEFAULT_REFRESH 50 extern Bool gx_dcon_init(ScrnInfoPtr pScrni); +/* amd_common.c */ + +void geode_memory_to_screen_blt(unsigned long, unsigned long, + unsigned long, unsigned long, long, long, int); +int GeodeGetRefreshRate(DisplayModePtr); +void GeodeCopyGreyscale(unsigned char *, unsigned char *, int, int, int, int); + +/* amd_gx_video.c */ + +int +GeodeQueryImageAttributes(ScrnInfoPtr, int id, unsigned short *w, + unsigned short *h, int *pitches, int *offsets); + + +Bool RegionsEqual(RegionPtr A, RegionPtr B); + +/* amd_gx_driver.c */ + +void GeodeProbeDDC(ScrnInfoPtr pScrni, int index); +xf86MonPtr GeodeDoDDC(ScrnInfoPtr pScrni, int index); +int GeodeGetFPGeometry(const char *str, int *width, int *height); +void GeodePointerMoved(int index, int x, int y); +void GeodeFreeScreen(int scrnIndex, int flags); +int GeodeCalculatePitchBytes(unsigned int width, unsigned int bpp); + #endif /* _AMD_GEODE_H_ */ diff --git a/src/amd_blend.h b/src/amd_blend.h new file mode 100644 index 0000000..6748ec0 --- /dev/null +++ b/src/amd_blend.h @@ -0,0 +1,62 @@ +#ifndef AMD_BLEND_H_ +#define AMD_BLEND_H_ + +#define GEODEPTR_FROM_PIXMAP(x) \ + GEODEPTR(xf86Screens[(x)->drawable.pScreen->myNum]) +#define GEODEPTR_FROM_SCREEN(x) \ + GEODEPTR(xf86Screens[(x)->myNum]) +#define GEODEPTR_FROM_PICTURE(x) \ + GEODEPTR(xf86Screens[(x)->pDrawable->pScreen->myNum]) + +#define usesPasses(op) ((( \ + ( 1 << PictOpAtop ) | \ + ( 1 << PictOpAtopReverse ) | \ + ( 1 << PictOpXor ) | \ + 0 ) >> (op)) & 1) + +/* pass1 or pass2 */ +#define usesSrcAlpha(op) ((( \ + ( 1 << PictOpOver ) | \ + ( 1 << PictOpInReverse ) | \ + ( 1 << PictOpOutReverse ) | \ + ( 1 << PictOpAtop ) | \ + ( 1 << PictOpAtopReverse ) | \ + ( 1 << PictOpXor ) | \ + 0 ) >> (op)) & 1) + +/* pass1 or pass2 */ +#define usesDstAlpha(op) ((( \ + ( 1 << PictOpOverReverse ) | \ + ( 1 << PictOpIn ) | \ + ( 1 << PictOpOut ) | \ + ( 1 << PictOpAtop ) | \ + ( 1 << PictOpAtopReverse ) | \ + ( 1 << PictOpXor ) | \ + 0 ) >> (op)) & 1) + +/* non 2 pass ops */ +#define usesChanB0(op) ((( \ + ( 1 << PictOpOver ) | \ + ( 1 << PictOpOverReverse ) | \ + ( 1 << PictOpIn ) | \ + ( 1 << PictOpInReverse ) | \ + ( 1 << PictOpOut ) | \ + ( 1 << PictOpOutReverse ) | \ + ( 1 << PictOpAdd ) | \ + 0 ) >> (op)) & 1) + +/* pass 1 ops */ +#define usesChanB1(op) ((( \ + ( 1 << PictOpAtop ) | \ + ( 1 << PictOpAtopReverse ) | \ + ( 1 << PictOpXor ) | \ + 0 ) >> (op)) & 1) + +/* pass 2 ops */ +#define usesChanB2(op) ((( \ + ( 1 << PictOpAtop ) | \ + ( 1 << PictOpAtopReverse ) | \ + ( 1 << PictOpXor ) | \ + 0 ) >> (op)) & 1) + +#endif diff --git a/src/amd_common.c b/src/amd_common.c new file mode 100644 index 0000000..f7e0d73 --- /dev/null +++ b/src/amd_common.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2007 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Neither the name of the Advanced Micro Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + */ + +/* We want to share as much code between GX and LX as we possibly can for obvious reasons */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" + +#define move0(d,s,n) \ + __asm__ __volatile__( \ + " rep; movsl\n" \ + : "=&c" (d0), "=&S" (d1), "=&D" (d2) \ + : "0" (n), "1" (s), "2" (d) \ + : "memory") + + + +#define move1(d,s,n) \ + __asm__ __volatile__( \ + " rep; movsl\n" \ + " movsb\n" \ + : "=&c" (d0), "=&S" (d1), "=&D" (d2) \ + : "0" (n), "1" (s), "2" (d) \ + : "memory") + +#define move2(d,s,n) \ + __asm__ __volatile__( \ + " rep; movsl\n" \ + " movsw\n" \ + : "=&c" (d0), "=&S" (d1), "=&D" (d2) \ + : "0" (n), "1" (s), "2" (d) \ + : "memory") + +#define move3(d,s,n) \ + __asm__ __volatile__( \ + " rep; movsl\n" \ + " movsw\n" \ + " movsb\n" \ + : "=&c" (d0), "=&S" (d1), "=&D" (d2) \ + : "0" (n), "1" (s), "2" (d) \ + : "memory") + + +void +geode_memory_to_screen_blt(unsigned long src, unsigned long dst, + unsigned long sp, unsigned long dp, long w, long h, int bpp) +{ + int d0, d1, d2; + int n = w * (bpp >> 3); + int m = n >> 2; + + switch (n & 3) { + case 0: + while (--h >= 0) { + move0(dst, src, m); + src += sp; + dst += dp; + } + break; + case 1: + while (--h >= 0) { + move1(dst, src, m); + src += sp; + dst += dp; + } + break; + case 2: + while (--h >= 0) { + move2(dst, src, m); + src += sp; + dst += dp; + } + break; + case 3: + while (--h >= 0) { + move3(dst, src, m); + src += sp; + dst += dp; + } + break; + } +} + +/* I borrowed this function from the i830 driver - its much better + then what we had before +*/ + +int +GeodeGetRefreshRate(DisplayModePtr pMode) +{ + if (pMode->VRefresh) + return (int)(pMode->VRefresh + 0.5); + + return (int)(pMode->Clock * 1000.0 / pMode->HTotal / pMode->VTotal + 0.5); +} + +/* This is used by both GX and LX. It could be accelerated for LX, probably, but + that would involve a two pass blt, the first to copy the data, and the second + to copy the grey (using a pattern). That seems like a bit of work for a + very underused format - so we'll just use the slow version. +*/ + +void +GeodeCopyGreyscale(unsigned char *src, unsigned char *dst, + int dstPitch, int srcPitch, int h, int w) +{ + int i; + unsigned char *src2 = src; + unsigned char *dst2 = dst; + unsigned char *dst3; + unsigned char *src3; + + dstPitch <<= 1; + + while (h--) { + dst3 = dst2; + src3 = src2; + for (i = 0; i < w; i++) { + *dst3++ = *src3++; /* Copy Y data */ + *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */ + } + + src3 = src2; + for (i = 0; i < w; i++) { + *dst3++ = *src3++; /* Copy Y data */ + *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */ + } + + dst2 += dstPitch; + src2 += srcPitch; + } +} diff --git a/src/amd_driver.c b/src/amd_driver.c index dde3805..5eae188 100644 --- a/src/amd_driver.c +++ b/src/amd_driver.c @@ -54,23 +54,7 @@ #define RC_MAX_DEPTH 24 -/* Frame buffer stuff */ -#if CFB -/* - * If using cfb, cfb.h is required. Select the others for the bpp values - * the driver supports. - */ -#define PSZ 8 /* needed for cfb.h */ -#include "cfb.h" -#undef PSZ -#include "cfb16.h" -#include "cfb24.h" -#include "cfb32.h" -#else #include "fb.h" -#endif - -#include "shadowfb.h" /* Machine independent stuff */ #include "mipointer.h" @@ -169,25 +153,19 @@ OptionInfoRec LX_GeodeOptions[] = { {LX_OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE}, {LX_OPTION_NOCOMPRESSION, "NoCompression", OPTV_BOOLEAN, {0}, FALSE}, {LX_OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, - {LX_OPTION_TV_ENCODER, "TV_Encoder", OPTV_ANYSTR, {0}, FALSE}, - {LX_OPTION_TV_BUS_FMT, "TV_Bus_Fmt", OPTV_ANYSTR, {0}, FALSE}, - {LX_OPTION_TV_FLAGS, "TV_Flags", OPTV_ANYSTR, {0}, FALSE}, - {LX_OPTION_TV_601_FLAGS, "TV_601_Flags", OPTV_ANYSTR, {0}, FALSE}, - {LX_OPTION_TV_VSYNC_SELECT, "TV_Vsync_Select", OPTV_ANYSTR, {0}, FALSE}, - {LX_OPTION_TV_CONVERSION, "TV_Conversion", OPTV_ANYSTR, {0}, FALSE}, - {LX_OPTION_TV_OVERSCAN, "TV_Overscan", OPTV_ANYSTR, {0}, FALSE}, - {LX_OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE}, + {LX_OPTION_ACCEL_METHOD, "AccelMethod", OPTV_STRING, {0}, FALSE}, + {LX_OPTION_TV_SUPPORT, "TV", OPTV_ANYSTR, {0}, FALSE}, + {LX_OPTION_TV_OUTPUT, "TV_Output", OPTV_ANYSTR, {0}, FALSE}, + {LX_OPTION_TV_OVERSCAN, "TVOverscan", OPTV_ANYSTR, {0}, FALSE}, {LX_OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE}, - {LX_OPTION_FLATPANEL, "FlatPanel", OPTV_BOOLEAN, {0}, FALSE}, - {LX_OPTION_CRTENABLE, "CrtEnable", OPTV_BOOLEAN, {0}, FALSE}, + {LX_OPTION_NOPANEL, "NoPanel", OPTV_BOOLEAN, {0}, FALSE}, {LX_OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE}, - {LX_OPTION_OSM_IMG_BUFS, "OSMImageBuffers", OPTV_INTEGER, {0}, FALSE}, - {LX_OPTION_OSM_CLR_BUFS, "OSMColorExpBuffers", OPTV_INTEGER, {0}, FALSE}, - {LX_OPTION_CUSTOM_MODE, "CustomMode", OPTV_BOOLEAN, {0}, FALSE}, - {LX_OPTION_FP_DEST_GEOM, "FPDestGeom", OPTV_ANYSTR, {0}, FALSE}, - {LX_OPTION_FP_ACTIVE_GEOM, "FPActiveGeom", OPTV_ANYSTR, {0}, FALSE}, + {LX_OPTION_EXA_SCRATCH_BFRSZ, "ExaScratch", OPTV_INTEGER, {0}, FALSE}, + {LX_OPTION_FBSIZE, "FBSize", OPTV_INTEGER, {0}, FALSE }, + {LX_OPTION_PANEL_GEOMETRY, "PanelGeometry", OPTV_STRING, {0}, FALSE }, {-1, NULL, OPTV_NONE, {0}, FALSE} }; + #endif #ifdef HAVE_GX @@ -250,21 +228,11 @@ const char *amdInt10Symbols[] = { NULL }; -#if CFB -const char *amdCfbSymbols[] = { - "cfbScreenInit", - "cfb16ScreenInit", - "cfb24ScreenInit", - "cfb32ScreenInit", - NULL -}; -#else const char *amdFbSymbols[] = { "fbScreenInit", "fbPictureInit", NULL }; -#endif const char *amdXaaSymbols[] = { "XAADestroyInfoRec", @@ -290,11 +258,6 @@ const char *amdRamdacSymbols[] = { NULL }; -const char *amdShadowSymbols[] = { - "ShadowFBInit", - NULL -}; - #ifdef XFree86LOADER /* Module loader interface */ @@ -353,13 +316,8 @@ AmdSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor) * module might refer to. */ LoaderRefSymLists(amdVgahwSymbols, amdVbeSymbols, -#if CFB - amdCfbSymbols, -#else - amdFbSymbols, -#endif - amdXaaSymbols, - amdInt10Symbols, amdRamdacSymbols, amdShadowSymbols, NULL); + amdFbSymbols, amdXaaSymbols, + amdInt10Symbols, amdRamdacSymbols, NULL); return (pointer) TRUE; } diff --git a/src/amd_gx_accel.c b/src/amd_gx_accel.c index 05b0300..798f26f 100644 --- a/src/amd_gx_accel.c +++ b/src/amd_gx_accel.c @@ -56,6 +56,10 @@ #include "gfx_defs.h" #include "gfx_regs.h" +/* Common macros for blend operations are here */ + +#include "amd_blend.h" + #undef ulong typedef unsigned long ulong; @@ -69,7 +73,7 @@ typedef unsigned short ushort; typedef unsigned char uchar; #define CALC_FBOFFSET(x, y) \ - (((ulong)(y) * gu2_pitch) + ((ulong)(x) << gu2_xshift)) + (((ulong)(y) * gu2_pitch + ((ulong)(x) << gu2_xshift))) #define FBADDR(x,y) \ ((unsigned char *)pGeode->FBBase + CALC_FBOFFSET(x, y)) @@ -163,78 +167,6 @@ static int PDfn_SM[16] = { 0x26, 0xA6, 0x66, 0xE6, 0x2E, 0xAE, 0x6E, 0xEE }; -#define move0(d,s,n) \ - __asm__ __volatile__( \ - " rep; movsl\n" \ - : "=&c" (d0), "=&S" (d1), "=&D" (d2) \ - : "0" (n), "1" (s), "2" (d) \ - : "memory") - -#define move1(d,s,n) \ - __asm__ __volatile__( \ - " rep; movsl\n" \ - " movsb\n" \ - : "=&c" (d0), "=&S" (d1), "=&D" (d2) \ - : "0" (n), "1" (s), "2" (d) \ - : "memory") - -#define move2(d,s,n) \ - __asm__ __volatile__( \ - " rep; movsl\n" \ - " movsw\n" \ - : "=&c" (d0), "=&S" (d1), "=&D" (d2) \ - : "0" (n), "1" (s), "2" (d) \ - : "memory") - -#define move3(d,s,n) \ - __asm__ __volatile__( \ - " rep; movsl\n" \ - " movsw\n" \ - " movsb\n" \ - : "=&c" (d0), "=&S" (d1), "=&D" (d2) \ - : "0" (n), "1" (s), "2" (d) \ - : "memory") - -static void -amd_memory_to_screen_blt(unsigned long src, unsigned long dst, - unsigned long sp, unsigned long dp, long w, long h, int bpp) -{ - int d0, d1, d2; - int n = w * (bpp >> 3); - int m = n >> 2; - - switch (n & 3) { - case 0: - while (--h >= 0) { - move0(dst, src, m); - src += sp; - dst += dp; - } - break; - case 1: - while (--h >= 0) { - move1(dst, src, m); - src += sp; - dst += dp; - } - break; - case 2: - while (--h >= 0) { - move2(dst, src, m); - src += sp; - dst += dp; - } - break; - case 3: - while (--h >= 0) { - move3(dst, src, m); - src += sp; - dst += dp; - } - break; - } -} - /*---------------------------------------------------------------------------- * GXAccelSync. * @@ -331,13 +263,13 @@ GXSubsequentSolidFillRect(ScrnInfoPtr pScrni, int x, int y, int w, int h) gfx_pattern_fill(x, y, w, h); #else { - unsigned int offset = CALC_FBOFFSET(x, y); - unsigned int size = (w << 16) | h; - - GU2_WAIT_PENDING; - WRITE_GP32(MGP_DST_OFFSET, offset); - WRITE_GP32(MGP_WID_HEIGHT, size); - WRITE_GP32(MGP_BLT_MODE, BLT_MODE); + unsigned int offset = CALC_FBOFFSET(x, y); + unsigned int size = (w << 16) | h; + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_DST_OFFSET, offset); + WRITE_GP32(MGP_WID_HEIGHT, size); + WRITE_GP32(MGP_BLT_MODE, BLT_MODE); } #endif } @@ -1493,7 +1425,7 @@ GXWritePixmap(ScrnInfoPtr pScrni, int x, int y, int w, int h, rop &= 0x0F; if (rop == GXcopy && trans == -1) { gfx_wait_until_idle(); - amd_memory_to_screen_blt((unsigned long)src, + geode_memory_to_screen_blt((unsigned long)src, (unsigned long)FBADDR(x, y), srcwidth, pGeode->Pitch, w, h, bpp); } else { @@ -1515,12 +1447,6 @@ GXWritePixmap(ScrnInfoPtr pScrni, int x, int y, int w, int h, #endif /* if GX_WRITE_PIXMAP_SUPPORT */ #if XF86EXA -#define GEODEPTR_FROM_PIXMAP(x) \ - GEODEPTR(xf86Screens[(x)->drawable.pScreen->myNum]) -#define GEODEPTR_FROM_SCREEN(x) \ - GEODEPTR(xf86Screens[(x)->myNum]) -#define GEODEPTR_FROM_PICTURE(x) \ - GEODEPTR(xf86Screens[(x)->pDrawable->pScreen->myNum]) static void amd_gx_exa_WaitMarker(ScreenPtr pScreen, int Marker) @@ -1543,7 +1469,7 @@ amd_gx_exa_UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, dst += y * dst_pitch + x * (bpp >> 3); GU2_WAIT_BUSY; - amd_memory_to_screen_blt((unsigned long)src, (unsigned long)dst, + geode_memory_to_screen_blt((unsigned long)src, (unsigned long)dst, src_pitch, dst_pitch, w, h, bpp); return TRUE; } @@ -1558,7 +1484,7 @@ amd_gx_exa_DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, src += y * src_pitch + x * (bpp >> 3); GU2_WAIT_BUSY; - amd_memory_to_screen_blt((unsigned long)src, (unsigned long)dst, + geode_memory_to_screen_blt((unsigned long)src, (unsigned long)dst, src_pitch, dst_pitch, w, h, bpp); return TRUE; } @@ -1712,57 +1638,6 @@ unsigned int amd_gx_exa_alpha_ops[] = (SRC_DST | A1_B1a | a_C), 0, /* add (src*1 + dst*1) */ }; -#define usesPasses(op) ((( \ - ( 1 << PictOpAtop ) | \ - ( 1 << PictOpAtopReverse ) | \ - ( 1 << PictOpXor ) | \ - 0 ) >> (op)) & 1) - -/* pass1 or pass2 */ -#define usesSrcAlpha(op) ((( \ - ( 1 << PictOpOver ) | \ - ( 1 << PictOpInReverse ) | \ - ( 1 << PictOpOutReverse ) | \ - ( 1 << PictOpAtop ) | \ - ( 1 << PictOpAtopReverse ) | \ - ( 1 << PictOpXor ) | \ - 0 ) >> (op)) & 1) - -/* pass1 or pass2 */ -#define usesDstAlpha(op) ((( \ - ( 1 << PictOpOverReverse ) | \ - ( 1 << PictOpIn ) | \ - ( 1 << PictOpOut ) | \ - ( 1 << PictOpAtop ) | \ - ( 1 << PictOpAtopReverse ) | \ - ( 1 << PictOpXor ) | \ - 0 ) >> (op)) & 1) - -/* non 2 pass ops */ -#define usesChanB0(op) ((( \ - ( 1 << PictOpOver ) | \ - ( 1 << PictOpOverReverse ) | \ - ( 1 << PictOpIn ) | \ - ( 1 << PictOpInReverse ) | \ - ( 1 << PictOpOut ) | \ - ( 1 << PictOpOutReverse ) | \ - ( 1 << PictOpAdd ) | \ - 0 ) >> (op)) & 1) - -/* pass 1 ops */ -#define usesChanB1(op) ((( \ - ( 1 << PictOpAtop ) | \ - ( 1 << PictOpAtopReverse ) | \ - ( 1 << PictOpXor ) | \ - 0 ) >> (op)) & 1) - -/* pass 2 ops */ -#define usesChanB2(op) ((( \ - ( 1 << PictOpAtop ) | \ - ( 1 << PictOpAtopReverse ) | \ - ( 1 << PictOpXor ) | \ - 0 ) >> (op)) & 1) - typedef struct { int exa_fmt; diff --git a/src/amd_gx_dcon.c b/src/amd_gx_dcon.c index f39f8fb..8058025 100644 --- a/src/amd_gx_dcon.c +++ b/src/amd_gx_dcon.c @@ -153,8 +153,8 @@ gx_dcon_init(ScrnInfoPtr pScrni) xf86DrvMsg(pScrni->scrnIndex, X_DEFAULT, "DCON detected.\n"); /* Panel size setup */ - pGeode->FPBX = DCON_DEFAULT_XRES; - pGeode->FPBY = DCON_DEFAULT_YRES; + pGeode->PanelX = DCON_DEFAULT_XRES; + pGeode->PanelY = DCON_DEFAULT_YRES; /* FIXME: Mode setup should go here */ /* FIXME: Controller setup should go here */ diff --git a/src/amd_gx_driver.c b/src/amd_gx_driver.c index 3226e52..eacf2b5 100644 --- a/src/amd_gx_driver.c +++ b/src/amd_gx_driver.c @@ -55,13 +55,6 @@ /* Bring in VGA functions */ #include "amd_gx_vga.c" -/* Chipset types */ - -#define GX 0x2 - -#define GX_CRT 0x04 | GX -#define GX_TFT 0x08 | GX - #define GX_MIN_PITCH 1024 #define GX_MAX_PITCH 8192 #define GX_MAX_WIDTH 1600 @@ -70,7 +63,9 @@ #define GX_CB_PITCH 544 #define GX_CB_SIZE 544 -static void GXPointerMoved(int index, int x, int y); +#define GX_CPU_REG_SIZE 0x4000 +#define GX_GP_REG_SIZE 0x4000 +#define GX_VID_REG_SIZE 0x4000 extern OptionInfoRec GX_GeodeOptions[]; @@ -84,373 +79,284 @@ extern const char *amdRamdacSymbols[]; unsigned char *XpressROMPtr; -const char *gxShadowSymbols[] = { - "ShadowInit", - "ShadowSetup", - "ShadowAdd", - NULL -}; - static inline void gx_enable_dac_power(void) { - gfx_write_vid32(RCDF_VID_MISC, - gfx_read_vid32(RCDF_VID_MISC) & RCDF_GAMMA_BYPASS_BOTH); + gfx_write_vid32(RCDF_VID_MISC, + gfx_read_vid32(RCDF_VID_MISC) & RCDF_GAMMA_BYPASS_BOTH); } static inline void gx_disable_dac_power(void) { - gfx_write_vid32(RCDF_VID_MISC, - RCDF_DAC_POWER_DOWN | RCDF_ANALOG_POWER_DOWN | - (gfx_read_vid32(RCDF_VID_MISC) & RCDF_GAMMA_BYPASS_BOTH)); -} - -/* Parser for the flatpanel info */ - -static inline int -GXGetFPInfo(const char *str, int *width, int *height) -{ - - int ret = sscanf(str, "%dx%d", width, height); - - return (ret == 2) ? 0 : 1; -} - -/* I borrowed this function from the i830 driver - its much better - then what we had before -*/ - -static int -GXGetRefreshRate(DisplayModePtr pMode) -{ - if (pMode->VRefresh) - return (int)(pMode->VRefresh + 0.5); - - return (int)(pMode->Clock * 1000.0 / pMode->HTotal / pMode->VTotal + 0.5); + gfx_write_vid32(RCDF_VID_MISC, + RCDF_DAC_POWER_DOWN | RCDF_ANALOG_POWER_DOWN | + (gfx_read_vid32(RCDF_VID_MISC) & RCDF_GAMMA_BYPASS_BOTH)); } -static int -GXCalculatePitchBytes(unsigned int width, unsigned int bpp) -{ - - int delta = width * (bpp >> 3); - /* Less then 640 has doubling enabled */ - if (width < 640) - delta <<= 1; - - /* Calculate the pitch (compression rquires a power of 2) */ - - if (delta > 4096) - delta = 8192; - else if (delta > 2048) - delta = 4096; - else if (delta > 1024) - delta = 2048; - else - delta = 1024; - - return delta; -} - -static void -GXFreeRec(ScrnInfoPtr pScrni) -{ - if (pScrni->driverPrivate != NULL) { - xfree(pScrni->driverPrivate); - pScrni->driverPrivate = NULL; - } -} static void GXInitEXAMemory(ScrnInfoPtr pScrni, unsigned int *offset, unsigned int *avail) { - GeodePtr pGeode = GEODEPTR(pScrni); + GeodePtr pGeode = GEODEPTR(pScrni); - if (pGeode->exaBfrSz > 0 && pGeode->exaBfrSz <= *avail) { - pGeode->exaBfrOffset = *offset; - *offset += pGeode->exaBfrOffset; - *avail -= pGeode->exaBfrOffset; - } + if (pGeode->exaBfrSz > 0 && pGeode->exaBfrSz <= *avail) { + pGeode->exaBfrOffset = *offset; + *offset += pGeode->exaBfrOffset; + *avail -= pGeode->exaBfrOffset; + } } static void GXInitXAAMemory(ScrnInfoPtr pScrni, unsigned int *offset, unsigned int *avail) { - GeodePtr pGeode = GEODEPTR(pScrni); - unsigned int size, i, pitch; - - /* XXX - FIXME - What if we are out of room? Then what? */ - /* For now, we NULL them all out. */ - - if (pGeode->NoOfImgBuffers > 0) { - size = pGeode->displayPitch * pGeode->NoOfImgBuffers; - if (size <= *avail) { - for (i = 0; i < pGeode->NoOfImgBuffers; i++) { - pGeode->AccelImageWriteBuffers[i] = pGeode->FBBase + *offset; - *offset += pGeode->displayPitch; - *avail -= pGeode->displayPitch; - } - } else { - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, - "Not enough memory for image write buffers.\n"); + GeodePtr pGeode = GEODEPTR(pScrni); + unsigned int size, i, pitch; + + /* XXX - FIXME - What if we are out of room? Then what? */ + /* For now, we NULL them all out. */ + + if (pGeode->NoOfImgBuffers > 0) { + size = pGeode->displayPitch * pGeode->NoOfImgBuffers; + if (size <= *avail) { + for (i = 0; i < pGeode->NoOfImgBuffers; i++) { + pGeode->AccelImageWriteBuffers[i] = pGeode->FBBase + *offset; + *offset += pGeode->displayPitch; + *avail -= pGeode->displayPitch; + } + } else { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Not enough memory for image write buffers.\n"); - for (i = 0; i < pGeode->NoOfImgBuffers; i++) - pGeode->AccelImageWriteBuffers[i] = NULL; - } + for (i = 0; i < pGeode->NoOfImgBuffers; i++) + pGeode->AccelImageWriteBuffers[i] = NULL; } + } - if (pGeode->NoOfColorExpandLines > 0) { - pitch = ((pGeode->displayPitch + 31) >> 5) << 2; - size = pitch * pGeode->NoOfColorExpandLines; - - if (size <= *avail) { - for (i = 0; i < pGeode->NoOfColorExpandLines; i++) { - pGeode->AccelColorExpandBuffers[i] = pGeode->FBBase + *offset; - *offset += pitch; - *avail -= pitch; - } - } else { - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, - "Not enough memory for color expansion buffers.\n"); + if (pGeode->NoOfColorExpandLines > 0) { + pitch = ((pGeode->displayPitch + 31) >> 5) << 2; + size = pitch * pGeode->NoOfColorExpandLines; - for (i = 0; i < pGeode->NoOfImgBuffers; i++) - pGeode->AccelColorExpandBuffers[i] = NULL; - } + if (size <= *avail) { + for (i = 0; i < pGeode->NoOfColorExpandLines; i++) { + pGeode->AccelColorExpandBuffers[i] = pGeode->FBBase + *offset; + *offset += pitch; + *avail -= pitch; + } + } else { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Not enough memory for color expansion buffers.\n"); + + for (i = 0; i < pGeode->NoOfImgBuffers; i++) + pGeode->AccelColorExpandBuffers[i] = NULL; } + } } static Bool GXAllocateMemory(ScreenPtr pScrn, ScrnInfoPtr pScrni, int rotate) { - GeodePtr pGeode = GEODEPTR(pScrni); + GeodePtr pGeode = GEODEPTR(pScrni); - unsigned int fboffset, fbavail; - unsigned int size; - unsigned int bytpp = (pScrni->bitsPerPixel + 7) / 8; - BOOL ret = TRUE; + unsigned int fboffset, fbavail; + unsigned int size; + unsigned int bytpp = (pScrni->bitsPerPixel + 7) / 8; + BOOL ret = TRUE; - if (pGeode->tryCompression) - pGeode->displayPitch = - GXCalculatePitchBytes(pScrni->virtualX, pScrni->bitsPerPixel); - else - pGeode->displayPitch = - ((pScrni->virtualX + 3) & ~3) * (pScrni->bitsPerPixel >> 3); + if (pGeode->tryCompression) + pGeode->displayPitch = + GeodeCalculatePitchBytes(pScrni->virtualX, pScrni->bitsPerPixel); + else + pGeode->displayPitch = + ((pScrni->virtualX + 3) & ~3) * (pScrni->bitsPerPixel >> 3); - pGeode->Pitch = pGeode->displayPitch; - pGeode->displayWidth = pGeode->displayPitch / bytpp; - pScrni->displayWidth = pGeode->displayWidth; + pGeode->Pitch = pGeode->displayPitch; + pGeode->displayWidth = pGeode->displayPitch / bytpp; + pScrni->displayWidth = pGeode->displayWidth; - fbavail = pGeode->FBAvail - 0x4000; + fbavail = pGeode->FBAvail - 0x4000; - pGeode->displayOffset = fboffset = 0; - pGeode->displaySize = pScrni->virtualY * pGeode->displayPitch; + pGeode->displayOffset = fboffset = 0; + pGeode->displaySize = pScrni->virtualY * pGeode->displayPitch; - fbavail -= pGeode->displaySize; - fboffset += pGeode->displaySize; + fbavail -= pGeode->displaySize; + fboffset += pGeode->displaySize; - if (pGeode->tryCompression) { - size = pScrni->virtualY * GX_CB_PITCH; + if (pGeode->tryCompression) { + size = pScrni->virtualY * GX_CB_PITCH; - if (size <= fbavail) { - pGeode->CBOffset = fboffset; + if (size <= fbavail) { + pGeode->CBData.compression_offset = fboffset; - fboffset += size; - fbavail -= size; + fboffset += size; + fbavail -= size; - pGeode->Compression = TRUE; - } else { - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, - "Not enough memory for compression\n"); - pGeode->Compression = FALSE; - } + pGeode->Compression = TRUE; + } else { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Not enough memory for compression\n"); + pGeode->Compression = FALSE; } + } - if (pGeode->tryHWCursor) { - pGeode->CursorSize = 1024; + if (pGeode->tryHWCursor) { + pGeode->CursorSize = 1024; - if (pGeode->CursorSize <= fbavail) { - pGeode->CursorStartOffset = fboffset; - fboffset += pGeode->CursorSize; - fbavail -= pGeode->CursorSize; - pGeode->HWCursor = TRUE; - } else { - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, - "Not enough memory for the hardware cursor\n"); - pGeode->HWCursor = FALSE; - } + if (pGeode->CursorSize <= fbavail) { + pGeode->CursorStartOffset = fboffset; + fboffset += pGeode->CursorSize; + fbavail -= pGeode->CursorSize; + pGeode->HWCursor = TRUE; + } else { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Not enough memory for the hardware cursor\n"); + pGeode->HWCursor = FALSE; } + } - if (!pGeode->NoAccel) { - if (pGeode->useEXA) - GXInitEXAMemory(pScrni, &fboffset, &fbavail); - else - GXInitXAAMemory(pScrni, &fboffset, &fbavail); - } + if (!pGeode->NoAccel) { + if (pGeode->useEXA) + GXInitEXAMemory(pScrni, &fboffset, &fbavail); + else + GXInitXAAMemory(pScrni, &fboffset, &fbavail); + } - pGeode->shadowSize = 0; + pGeode->shadowSize = 0; - if (rotate != RR_Rotate_0) { - if (rotate & (RR_Rotate_90 | RR_Rotate_270)) - size = pGeode->displayPitch * pScrni->virtualX; - else - size = pGeode->displayPitch * pScrni->virtualY; + if (rotate != RR_Rotate_0) { + if (rotate & (RR_Rotate_90 | RR_Rotate_270)) + size = pGeode->displayPitch * pScrni->virtualX; + else + size = pGeode->displayPitch * pScrni->virtualY; - if (size <= fbavail) { - pGeode->shadowOffset = fboffset; - pGeode->shadowSize = size; + if (size <= fbavail) { + pGeode->shadowOffset = fboffset; + pGeode->shadowSize = size; - fboffset += size; - fbavail -= size; - } else { - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, - "Not enough memory for the shadow framebuffer\n"); - ret = FALSE; - } + fboffset += size; + fbavail -= size; + } else { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Not enough memory for the shadow framebuffer\n"); + ret = FALSE; } + } - /* XAA always exists - we can't remove it on demand like we can with EXA. - So we assume the worse, and only give XAA enough offspace room to - account for any eventuality that RandR might throw at us. */ - - if (!pGeode->NoAccel) { + /* XAA always exists - we can't remove it on demand like we can with EXA. + So we assume the worse, and only give XAA enough offspace room to + account for any eventuality that RandR might throw at us. */ - if (pGeode->useEXA && pGeode->pExa) { - ExaDriverPtr pExa = pGeode->pExa; + if (!pGeode->NoAccel) { - pExa->offScreenBase = fboffset; - pExa->memorySize = fboffset + fbavail; - } + if (pGeode->useEXA && pGeode->pExa) { + ExaDriverPtr pExa = pGeode->pExa; - if (!pGeode->useEXA) { + pExa->offScreenBase = fboffset; + pExa->memorySize = fboffset + fbavail; + } - if (!xf86FBManagerRunning(pScrn)) { + if (!pGeode->useEXA) { - unsigned int offset = fboffset; - unsigned int avail = fbavail; - RegionRec OffscreenRegion; - BoxRec AvailBox; + if (!xf86FBManagerRunning(pScrn)) { - /* Assume the shadow FB exists even if it doesnt */ + unsigned int offset = fboffset; + unsigned int avail = fbavail; + RegionRec OffscreenRegion; + BoxRec AvailBox; - if (pGeode->shadowSize == 0) { - size = (pScrn->width * bytpp) * pScrni->virtualX; - offset += size; - avail -= size; - } + /* Assume the shadow FB exists even if it doesnt */ - AvailBox.x1 = 0; - AvailBox.y1 = - (offset + pGeode->displayPitch - - 1) / pGeode->displayPitch; + if (pGeode->shadowSize == 0) { + size = (pScrn->width * bytpp) * pScrni->virtualX; + offset += size; + avail -= size; + } - AvailBox.x2 = pGeode->displayWidth; - AvailBox.y2 = (offset + avail) / pGeode->displayPitch; + AvailBox.x1 = 0; + AvailBox.y1 = + (offset + pGeode->displayPitch - + 1) / pGeode->displayPitch; - if (AvailBox.y1 < AvailBox.y2) { - REGION_INIT(pScrn, &OffscreenRegion, &AvailBox, 2); + AvailBox.x2 = pGeode->displayWidth; + AvailBox.y2 = (offset + avail) / pGeode->displayPitch; - if (!xf86InitFBManagerRegion(pScrn, &OffscreenRegion)) - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, - "Memory manager initialization failed.\n"); + if (AvailBox.y1 < AvailBox.y2) { + REGION_INIT(pScrn, &OffscreenRegion, &AvailBox, 2); - REGION_UNINIT(pScrn, &OffscreenRegion); - } else - xf86DrvMsg(pScrni->scrnIndex, X_INFO, - "Cache disabled - no offscreen memory available.\n"); - } else - xf86DrvMsgp(pScrni->scrnIndex, X_INFO, + if (!xf86InitFBManagerRegion(pScrn, &OffscreenRegion)) + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Memory manager initialization failed.\n"); + + REGION_UNINIT(pScrn, &OffscreenRegion); + } else + xf86DrvMsg(pScrni->scrnIndex, X_INFO, + "Cache disabled - no offscreen memory available.\n"); + } else + xf86DrvMsgp(pScrni->scrnIndex, X_INFO, "XAA offscreen memory has already been allocated.\n"); - } } + } } static Bool GXSaveScreen(ScreenPtr pScrn, int mode) { - ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; - GeodePtr pGeode = GEODEPTR(pScrni); + ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; + GeodePtr pGeode = GEODEPTR(pScrni); - if (pGeode->useVGA && !pScrni->vtSema) - return vgaHWSaveScreen(pScrn, mode); + if (pGeode->useVGA && !pScrni->vtSema) + return vgaHWSaveScreen(pScrn, mode); - return TRUE; + return TRUE; } -static void -GXProbeDDC(ScrnInfoPtr pScrni, int index) -{ - vbeInfoPtr pVbe; - if (xf86LoadSubModule(pScrni, "vbe")) { - pVbe = VBEInit(NULL, index); - ConfiguredMonitor = vbeDoEDID(pVbe, NULL); - vbeFree(pVbe); - } -} -/* From the Intel driver */ +/* Common function - used by the LX too */ + -static xf86MonPtr -GXDoDDC(ScrnInfoPtr pScrni, int index) -{ - vbeInfoPtr pVbe; - xf86MonPtr info = NULL; - - if (xf86LoadSubModule(pScrni, "vbe")) { - xf86LoaderReqSymLists(amdVbeSymbols, NULL); - info = vbeDoEDID(pVbe, NULL); - xf86PrintEDID(info); - xf86SetDDCproperties(pScrni, info); - vbeFree(pVbe); - } else - xf86DrvMsg(pScrni->scrnIndex, X_INFO, - "We cannot do DDC without VBE.\n"); - - return info; -} extern unsigned long gfx_gx2_scratch_base; static Bool GXMapMem(ScrnInfoPtr pScrni) { - GeodeRec *pGeode = GEODEPTR(pScrni); - int index = pScrni->scrnIndex; + GeodeRec *pGeode = GEODEPTR(pScrni); + int index = pScrni->scrnIndex; - pciVideoRec *pci = xf86GetPciInfoForEntity(pGeode->pEnt->index); + pciVideoRec *pci = xf86GetPciInfoForEntity(pGeode->pEnt->index); - gfx_virt_regptr = (unsigned char *)xf86MapVidMem(index, VIDMEM_MMIO, - pci->memBase[2], pci->size[2]); + gfx_virt_regptr = (unsigned char *)xf86MapVidMem(index, VIDMEM_MMIO, + pci->memBase[2], pci->size[2]); - gfx_virt_gpptr = (unsigned char *)xf86MapVidMem(index, VIDMEM_MMIO, - pci->memBase[1], pci->size[1]); + gfx_virt_gpptr = (unsigned char *)xf86MapVidMem(index, VIDMEM_MMIO, + pci->memBase[1], pci->size[1]); - gfx_virt_vidptr = (unsigned char *)xf86MapVidMem(index, VIDMEM_MMIO, - pci->memBase[3], pci->size[3]); + gfx_virt_vidptr = (unsigned char *)xf86MapVidMem(index, VIDMEM_MMIO, + pci->memBase[3], pci->size[3]); - gfx_virt_fbptr = (unsigned char *)xf86MapVidMem(index, VIDMEM_FRAMEBUFFER, - pci->memBase[0], pGeode->FBAvail); + gfx_virt_fbptr = (unsigned char *)xf86MapVidMem(index, VIDMEM_FRAMEBUFFER, + pci->memBase[0], pGeode->FBAvail); - gfx_gx2_scratch_base = pGeode->FBAvail - 0x4000; + gfx_gx2_scratch_base = pGeode->FBAvail - 0x4000; - XpressROMPtr = xf86MapVidMem(index, VIDMEM_FRAMEBUFFER, 0xF0000, 0x10000); + XpressROMPtr = xf86MapVidMem(index, VIDMEM_FRAMEBUFFER, 0xF0000, 0x10000); - pGeode->FBBase = gfx_virt_fbptr; + pGeode->FBBase = gfx_virt_fbptr; - if ((!gfx_virt_regptr) || (!gfx_virt_gpptr) || - (!gfx_virt_vidptr) || (!gfx_virt_fbptr)) - return FALSE; + if ((!gfx_virt_regptr) || (!gfx_virt_gpptr) || + (!gfx_virt_vidptr) || (!gfx_virt_fbptr)) + return FALSE; - if (!pGeode->NoAccel && pGeode->useEXA) - pGeode->pExa->memoryBase = pGeode->FBBase; + if (!pGeode->NoAccel && pGeode->useEXA) + pGeode->pExa->memoryBase = pGeode->FBBase; - xf86DrvMsg(index, X_INFO, "Found Geode %lx %p\n", - pGeode->FBAvail, pGeode->FBBase); + xf86DrvMsg(index, X_INFO, "Found Geode %lx %p\n", + pGeode->FBAvail, pGeode->FBBase); - return TRUE; + return TRUE; } /* Check to see if VGA exists - we map the space and look for a @@ -476,373 +382,364 @@ GXCheckVGA(ScrnInfoPtr pScrni) { static Bool GXPreInit(ScrnInfoPtr pScrni, int flags) { - GeodePtr pGeode; - ClockRangePtr GeodeClockRange; - OptionInfoRec *GeodeOptions = &GX_GeodeOptions[0]; - int ret; - QQ_WORD msrValue; - rgb defaultWeight = { 0, 0, 0 }; - int modecnt; - int maj, min; - char *s, *panelgeo; - char **modes; - - pGeode = pScrni->driverPrivate = xnfcalloc(sizeof(GeodeRec), 1); - - if (pGeode == NULL) - return FALSE; - - /* Probe for VGA */ - pGeode->useVGA = FALSE; - - if (xf86LoadSubModule(pScrni, "vgahw")) { - if (vgaHWGetHWRec(pScrni)) { - pGeode->useVGA = GXCheckVGA(pScrni); - } + GeodePtr pGeode; + ClockRangePtr GeodeClockRange; + OptionInfoRec *GeodeOptions = &GX_GeodeOptions[0]; + int ret; + QQ_WORD msrValue; + rgb defaultWeight = { 0, 0, 0 }; + int modecnt; + int maj, min; + char *s, *panelgeo; + char **modes; + + pGeode = pScrni->driverPrivate = xnfcalloc(sizeof(GeodeRec), 1); + + if (pGeode == NULL) + return FALSE; + + /* Probe for VGA */ + pGeode->useVGA = FALSE; + + if (xf86LoadSubModule(pScrni, "vgahw")) { + if (vgaHWGetHWRec(pScrni)) { + pGeode->useVGA = GXCheckVGA(pScrni); } + } #if INT10_SUPPORT - if (pGeode->useVGA) - pGeode->vesa = xcalloc(sizeof(VESARec), 1); + if (pGeode->useVGA) + pGeode->vesa = xcalloc(sizeof(VESARec), 1); #endif - if (pScrni->numEntities != 1) - return FALSE; - - pGeode->pEnt = xf86GetEntityInfo(pScrni->entityList[0]); + if (pScrni->numEntities != 1) + return FALSE; - if (pGeode->pEnt->resources) - return FALSE; + pGeode->pEnt = xf86GetEntityInfo(pScrni->entityList[0]); - /* ISSUE - this won't work without VGA, but its too early to know if we can use VGA or not */ + if (pGeode->pEnt->resources) + return FALSE; - if (pGeode->useVGA && (flags & PROBE_DETECT)) { - GXProbeDDC(pScrni, pGeode->pEnt->index); - return TRUE; - } + /* ISSUE - this won't work without VGA, but its too early to know if we can use VGA or not */ - gfx_msr_init(); + if (pGeode->useVGA && (flags & PROBE_DETECT)) { + GeodeProbeDDC(pScrni, pGeode->pEnt->index); + return TRUE; + } - /* Note that we assume that we are on a GX */ + gfx_msr_init(); - pGeode->DetectedChipSet = GX_CRT; - ret = gfx_msr_read(RC_ID_DF, MBD_MSR_CONFIG, &msrValue); + ret = gfx_msr_read(RC_ID_DF, MBD_MSR_CONFIG, &msrValue); - if (!ret) - pGeode->DetectedChipSet = - ((msrValue.low & RCDF_CONFIG_FMT_MASK) == - RCDF_CONFIG_FMT_FP) ? GX_TFT : GX_CRT; + if (!ret) { + pGeode->Output = + ((msrValue.low & RCDF_CONFIG_FMT_MASK) == + RCDF_CONFIG_FMT_FP) ? OUTPUT_CRT : OUTPUT_PANEL; + } - /* Fill in the monitor information */ - pScrni->monitor = pScrni->confScreen->monitor; + /* Fill in the monitor information */ + pScrni->monitor = pScrni->confScreen->monitor; - if (!xf86SetDepthBpp(pScrni, 8, 8, 8, Support24bppFb | Support32bppFb)) - return FALSE; + if (!xf86SetDepthBpp(pScrni, 8, 8, 8, Support24bppFb | Support32bppFb)) + return FALSE; - switch (pScrni->depth) { - case 8: - pScrni->rgbBits = 8; - case 16: - case 24: - case 32: - break; - default: - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, - "The driver does not support %d as a depth.\n", pScrni->depth); - return FALSE; - } + switch (pScrni->depth) { + case 8: + pScrni->rgbBits = 8; + case 16: + case 24: + case 32: + break; + default: + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "The driver does not support %d as a depth.\n", pScrni->depth); + return FALSE; + } - xf86PrintDepthBpp(pScrni); + xf86PrintDepthBpp(pScrni); - if (!xf86SetWeight(pScrni, defaultWeight, defaultWeight)) - return FALSE; + if (!xf86SetWeight(pScrni, defaultWeight, defaultWeight)) + return FALSE; - if (!xf86SetDefaultVisual(pScrni, -1)) - return FALSE; + if (!xf86SetDefaultVisual(pScrni, -1)) + return FALSE; - pScrni->progClock = TRUE; - xf86CollectOptions(pScrni, NULL); - xf86ProcessOptions(pScrni->scrnIndex, pScrni->options, GeodeOptions); + pScrni->progClock = TRUE; + xf86CollectOptions(pScrni, NULL); + xf86ProcessOptions(pScrni->scrnIndex, pScrni->options, GeodeOptions); - /* Set up our various options that may get reversed as we go on */ + /* Set up our various options that may get reversed as we go on */ - pGeode->FBVGAActive = FALSE; - pGeode->tryHWCursor = TRUE; - pGeode->tryCompression = TRUE; + pGeode->FBVGAActive = FALSE; + pGeode->tryHWCursor = TRUE; + pGeode->tryCompression = TRUE; - pGeode->NoAccel = FALSE; - pGeode->useEXA = TRUE; + pGeode->NoAccel = FALSE; + pGeode->useEXA = TRUE; - if (pGeode->DetectedChipSet == GX_TFT) - pGeode->Panel = TRUE; - else if (pGeode->DetectedChipSet == GX_CRT) - pGeode->Panel = FALSE; + pGeode->Panel = (pGeode->Output & OUTPUT_PANEL) ? TRUE : FALSE; - pGeode->NoOfImgBuffers = DEFAULT_IMG_LINE_BUFS; - pGeode->NoOfColorExpandLines = DEFAULT_CLR_LINE_BUFS; - pGeode->exaBfrSz = DEFAULT_EXA_SCRATCH_BFRSZ; + pGeode->NoOfImgBuffers = DEFAULT_IMG_LINE_BUFS; + pGeode->NoOfColorExpandLines = DEFAULT_CLR_LINE_BUFS; + pGeode->exaBfrSz = DEFAULT_EXA_SCRATCH_BFRSZ; - xf86GetOptValBool(GeodeOptions, GX_OPTION_HW_CURSOR, - &pGeode->tryHWCursor); + xf86GetOptValBool(GeodeOptions, GX_OPTION_HW_CURSOR, + &pGeode->tryHWCursor); - if (!xf86GetOptValInteger(GeodeOptions, GX_OPTION_FBSIZE, - &(pGeode->FBAvail))) - pGeode->FBAvail = 0; + if (!xf86GetOptValInteger(GeodeOptions, GX_OPTION_FBSIZE, + &(pGeode->FBAvail))) + pGeode->FBAvail = 0; - /* For compatability - allow SWCursor too */ + /* For compatability - allow SWCursor too */ - if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_SW_CURSOR, FALSE)) - pGeode->tryHWCursor = FALSE; + if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_SW_CURSOR, FALSE)) + pGeode->tryHWCursor = FALSE; - if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_NOCOMPRESSION, FALSE)) - pGeode->tryCompression = FALSE; + if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_NOCOMPRESSION, FALSE)) + pGeode->tryCompression = FALSE; - if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_NOACCEL, FALSE)) - pGeode->NoAccel = TRUE; + if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_NOACCEL, FALSE)) + pGeode->NoAccel = TRUE; - pGeode->rotation = RR_Rotate_0; + pGeode->rotation = RR_Rotate_0; - if ((s = xf86GetOptValString(GeodeOptions, GX_OPTION_ROTATE))) { + if ((s = xf86GetOptValString(GeodeOptions, GX_OPTION_ROTATE))) { - if (!xf86NameCmp(s, "LEFT")) - pGeode->rotation = RR_Rotate_90; - else if (!xf86NameCmp(s, "INVERT")) - pGeode->rotation = RR_Rotate_180; - else if (!xf86NameCmp(s, "CCW")) - pGeode->rotation = RR_Rotate_270; - else - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, - "Invalid rotation %s.\n", s); - } + if (!xf86NameCmp(s, "LEFT")) + pGeode->rotation = RR_Rotate_90; + else if (!xf86NameCmp(s, "INVERT")) + pGeode->rotation = RR_Rotate_180; + else if (!xf86NameCmp(s, "CCW")) + pGeode->rotation = RR_Rotate_270; + else + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Invalid rotation %s.\n", s); + } - xf86GetOptValInteger(GeodeOptions, GX_OPTION_OSM_IMG_BUFS, - &(pGeode->NoOfImgBuffers)); + xf86GetOptValInteger(GeodeOptions, GX_OPTION_OSM_IMG_BUFS, + &(pGeode->NoOfImgBuffers)); - if (pGeode->NoOfImgBuffers <= 0) - pGeode->NoOfImgBuffers = 0; + if (pGeode->NoOfImgBuffers <= 0) + pGeode->NoOfImgBuffers = 0; - xf86GetOptValInteger(GeodeOptions, GX_OPTION_OSM_CLR_BUFS, - &(pGeode->NoOfColorExpandLines)); + xf86GetOptValInteger(GeodeOptions, GX_OPTION_OSM_CLR_BUFS, + &(pGeode->NoOfColorExpandLines)); - if (pGeode->NoOfColorExpandLines <= 0) - pGeode->NoOfColorExpandLines = 0; + if (pGeode->NoOfColorExpandLines <= 0) + pGeode->NoOfColorExpandLines = 0; - xf86GetOptValInteger(GeodeOptions, GX_OPTION_OSM_CLR_BUFS, - &(pGeode->exaBfrSz)); + xf86GetOptValInteger(GeodeOptions, GX_OPTION_OSM_CLR_BUFS, + &(pGeode->exaBfrSz)); - if (pGeode->exaBfrSz <= 0) - pGeode->exaBfrSz = 0; + if (pGeode->exaBfrSz <= 0) + pGeode->exaBfrSz = 0; - if (pGeode->Panel == TRUE) { - if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_NOPANEL, FALSE)) - pGeode->Panel = FALSE; - } + if (pGeode->Panel == TRUE) { + if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_NOPANEL, FALSE)) + pGeode->Panel = FALSE; + } - panelgeo = xf86GetOptValString(GeodeOptions, GX_OPTION_PANEL_GEOMETRY); + panelgeo = xf86GetOptValString(GeodeOptions, GX_OPTION_PANEL_GEOMETRY); - if ((s = xf86GetOptValString(GeodeOptions, GX_OPTION_ACCEL_METHOD))) { - if (!xf86NameCmp(s, "XAA")) - pGeode->useEXA = FALSE; - else if (xf86NameCmp(s, "EXA")) - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, - "Unknown accleration method %s. Defaulting to EXA.\n", s); - } + if ((s = xf86GetOptValString(GeodeOptions, GX_OPTION_ACCEL_METHOD))) { + if (!xf86NameCmp(s, "XAA")) + pGeode->useEXA = FALSE; + else if (xf86NameCmp(s, "EXA")) + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Unknown accleration method %s. Defaulting to EXA.\n", s); + } - xf86DrvMsg(pScrni->scrnIndex, X_INFO, - "Using %s acceleration architecture\n", - pGeode->useEXA ? "EXA" : "XAA"); + xf86DrvMsg(pScrni->scrnIndex, X_INFO, + "Using %s acceleration architecture\n", + pGeode->useEXA ? "EXA" : "XAA"); - /* Set up the panel */ + /* Set up the panel */ - if (gx_dcon_init(pScrni)) { - pGeode->Panel = TRUE; - } else if (pGeode->Panel) { - if (panelgeo != NULL) { - if (GXGetFPInfo(panelgeo, &pGeode->FPBX, &pGeode->FPBY)) - pGeode->Panel = FALSE; - } + if (gx_dcon_init(pScrni)) { + pGeode->Panel = TRUE; + } else if (pGeode->Panel) { + if (panelgeo != NULL) { + if (GXGetFPInfo(panelgeo, &pGeode->PanelX, &pGeode->PanelY)) + pGeode->Panel = FALSE; + } #ifdef PNL_SUP - else { - int b, f; + else { + int b, f; - /* The bitdepth and refresh isn't used anywhere else in the driver */ + /* The bitdepth and refresh isn't used anywhere else in the driver */ - if ((pGeode->Panel = Pnl_IsPanelEnabledInBIOS())) - Pnl_GetPanelInfoFromBIOS(&pGeode->FPBX, &pGeode->FPBY, &b, - &f); - } -#endif + if ((pGeode->Panel = Pnl_IsPanelEnabledInBIOS())) + Pnl_GetPanelInfoFromBIOS(&pGeode->PanelX, &pGeode->PanelY, &b, + &f); } +#endif + } - /* Set up the VGA */ + /* Set up the VGA */ - if (pGeode->useVGA) { + if (pGeode->useVGA) { #if INT10_SUPPORT - VESARec *pVesa; + VESARec *pVesa; - if (!xf86LoadSubModule(pScrni, "int10")) - return FALSE; - xf86LoaderReqSymLists(amdInt10Symbols, NULL); + if (!xf86LoadSubModule(pScrni, "int10")) + return FALSE; + xf86LoaderReqSymLists(amdInt10Symbols, NULL); - pVesa = pGeode->vesa; + pVesa = pGeode->vesa; - if ((pVesa->pInt = xf86InitInt10(pGeode->pEnt->index)) == NULL) { - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, - "Unable to initialize 1NT10 support\n"); - pGeode->useVGA = FALSE; - } + if ((pVesa->pInt = xf86InitInt10(pGeode->pEnt->index)) == NULL) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Unable to initialize 1NT10 support\n"); + pGeode->useVGA = FALSE; + } #endif - xf86LoaderReqSymLists(amdVgahwSymbols, NULL); - pGeode->FBVGAActive = gu2_get_vga_active(); - } + xf86LoaderReqSymLists(amdVgahwSymbols, NULL); + pGeode->FBVGAActive = gu2_get_vga_active(); + } - if (pGeode->FBAvail == 0) - pGeode->FBAvail = gfx_get_frame_buffer_size(); + if (pGeode->FBAvail == 0) + pGeode->FBAvail = gfx_get_frame_buffer_size(); - if (pScrni->memPhysBase == 0) - pScrni->memPhysBase = gfx_get_frame_buffer_base(); + if (pScrni->memPhysBase == 0) + pScrni->memPhysBase = gfx_get_frame_buffer_base(); - pScrni->fbOffset = 0; + pScrni->fbOffset = 0; - if (pGeode->pEnt->device->videoRam == 0) - pScrni->videoRam = pGeode->FBAvail / 1024; - else - pScrni->videoRam = pGeode->pEnt->device->videoRam; + if (pGeode->pEnt->device->videoRam == 0) + pScrni->videoRam = pGeode->FBAvail / 1024; + else + pScrni->videoRam = pGeode->pEnt->device->videoRam; - pGeode->maxWidth = GX_MAX_WIDTH; - pGeode->maxHeight = GX_MAX_HEIGHT; + pGeode->maxWidth = GX_MAX_WIDTH; + pGeode->maxHeight = GX_MAX_HEIGHT; - GeodeClockRange = (ClockRangePtr) xnfcalloc(sizeof(ClockRange), 1); - GeodeClockRange->next = NULL; - GeodeClockRange->minClock = 25175; - GeodeClockRange->maxClock = 229500; - GeodeClockRange->clockIndex = -1; - GeodeClockRange->interlaceAllowed = TRUE; - GeodeClockRange->doubleScanAllowed = FALSE; + GeodeClockRange = (ClockRangePtr) xnfcalloc(sizeof(ClockRange), 1); + GeodeClockRange->next = NULL; + GeodeClockRange->minClock = 25175; + GeodeClockRange->maxClock = 229500; + GeodeClockRange->clockIndex = -1; + GeodeClockRange->interlaceAllowed = TRUE; + GeodeClockRange->doubleScanAllowed = FALSE; - if (pGeode->useVGA) - pScrni->monitor->DDC = GXDoDDC(pScrni, pGeode->pEnt->index); - else - pScrni->monitor->DDC = NULL; - - /* I'm still not 100% sure this uses the right values */ - - modecnt = xf86ValidateModes(pScrni, - pScrni->monitor->Modes, - pScrni->display->modes, - GeodeClockRange, - NULL, GX_MIN_PITCH, GX_MAX_PITCH, - 32, GX_MIN_HEIGHT, GX_MAX_HEIGHT, - pScrni->display->virtualX, - pScrni->display->virtualY, pGeode->FBAvail, LOOKUP_BEST_REFRESH); - - if (modecnt <= 0) { - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes were found\n"); - return FALSE; - } + if (pGeode->useVGA) + pScrni->monitor->DDC = GeodeDoDDC(pScrni, pGeode->pEnt->index); + else + pScrni->monitor->DDC = NULL; - xf86PruneDriverModes(pScrni); + /* I'm still not 100% sure this uses the right values */ - if (pScrni->modes == NULL) { - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes were found\n"); - return FALSE; - } + modecnt = xf86ValidateModes(pScrni, + pScrni->monitor->Modes, + pScrni->display->modes, + GeodeClockRange, + NULL, GX_MIN_PITCH, GX_MAX_PITCH, + 32, GX_MIN_HEIGHT, GX_MAX_HEIGHT, + pScrni->display->virtualX, + pScrni->display->virtualY, pGeode->FBAvail, LOOKUP_BEST_REFRESH); - xf86SetCrtcForModes(pScrni, 0); - pScrni->currentMode = pScrni->modes; + if (modecnt <= 0) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes were found\n"); + return FALSE; + } - xf86PrintModes(pScrni); - xf86SetDpi(pScrni, 0, 0); + xf86PruneDriverModes(pScrni); - /* Load the modules we'll need */ + if (pScrni->modes == NULL) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes were found\n"); + return FALSE; + } - if (xf86LoadSubModule(pScrni, "fb") == NULL) { - return FALSE; - } + xf86SetCrtcForModes(pScrni, 0); + pScrni->currentMode = pScrni->modes; - xf86LoaderReqSymLists(amdFbSymbols, NULL); + xf86PrintModes(pScrni); + xf86SetDpi(pScrni, 0, 0); - if (pGeode->NoAccel == FALSE) { - const char *module = (pGeode->useEXA) ? "exa" : "xaa"; - const char **symbols = (pGeode->useEXA) ? - &amdExaSymbols[0] : &amdXaaSymbols[0]; + /* Load the modules we'll need */ - if (!xf86LoadSubModule(pScrni, module)) { - return FALSE; - } + if (xf86LoadSubModule(pScrni, "fb") == NULL) { + return FALSE; + } - xf86LoaderReqSymLists(symbols, NULL); - } + xf86LoaderReqSymLists(amdFbSymbols, NULL); - if (pGeode->tryHWCursor == TRUE) { - if (!xf86LoadSubModule(pScrni, "ramdac")) { - return FALSE; - } + if (pGeode->NoAccel == FALSE) { + const char *module = (pGeode->useEXA) ? "exa" : "xaa"; + const char **symbols = (pGeode->useEXA) ? + &amdExaSymbols[0] : &amdXaaSymbols[0]; - xf86LoaderReqSymLists(amdRamdacSymbols, NULL); + if (!xf86LoadSubModule(pScrni, module)) { + return FALSE; } - if (xf86RegisterResources(pGeode->pEnt->index, NULL, ResExclusive)) { - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, - "Couldn't register the resources.\n"); - return FALSE; + xf86LoaderReqSymLists(symbols, NULL); + } + + if (pGeode->tryHWCursor == TRUE) { + if (!xf86LoadSubModule(pScrni, "ramdac")) { + return FALSE; } - return TRUE; + xf86LoaderReqSymLists(amdRamdacSymbols, NULL); + } + + if (xf86RegisterResources(pGeode->pEnt->index, NULL, ResExclusive)) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Couldn't register the resources.\n"); + return FALSE; + } + + return TRUE; } static void GXRestore(ScrnInfoPtr pScrni) { - GeodeRec *pGeode = GEODEPTR(pScrni); + GeodeRec *pGeode = GEODEPTR(pScrni); - if (pGeode->useVGA && pGeode->FBVGAActive) { - vgaHWPtr pvgaHW = VGAHWPTR(pScrni); + if (pGeode->useVGA && pGeode->FBVGAActive) { + vgaHWPtr pvgaHW = VGAHWPTR(pScrni); - vgaHWProtect(pScrni, TRUE); - vgaHWRestore(pScrni, &pvgaHW->SavedReg, VGA_SR_ALL); - vgaHWProtect(pScrni, FALSE); - } + vgaHWProtect(pScrni, TRUE); + vgaHWRestore(pScrni, &pvgaHW->SavedReg, VGA_SR_ALL); + vgaHWProtect(pScrni, FALSE); + } } static Bool GXUnmapMem(ScrnInfoPtr pScrni) { - GeodeRec *pGeode = GEODEPTR(pScrni); - - /* unmap all the memory map's */ + GeodeRec *pGeode = GEODEPTR(pScrni); - xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_regptr, pGeode->cpu_reg_size); + /* unmap all the memory map's */ - if (pGeode->DetectedChipSet & GX) { - xf86UnMapVidMem(pScrni->scrnIndex, - gfx_virt_gpptr, pGeode->gp_reg_size); - } - xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_vidptr, pGeode->vid_reg_size); - xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_fbptr, pGeode->FBAvail); - return TRUE; + xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_regptr, GX_CPU_REG_SIZE); + xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_gpptr, GX_GP_REG_SIZE); + xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_vidptr, GX_VID_REG_SIZE); + xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_fbptr, pGeode->FBAvail); + return TRUE; } static void GXSetDvLineSize(unsigned int pitch) { - unsigned long temp, dv_size = MDC_DV_LINE_SIZE_1024; - - if (pitch > 1024) { - dv_size = MDC_DV_LINE_SIZE_2048; - } - if (pitch > 2048) { - dv_size = MDC_DV_LINE_SIZE_4096; - } - if (pitch > 4096) { - dv_size = MDC_DV_LINE_SIZE_8192; - } - - /* WRITE DIRTY/VALID CONTROL WITH LINE LENGTH */ - - temp = READ_REG32(MDC_DV_CTL); - WRITE_REG32(MDC_DV_CTL, (temp & ~MDC_DV_LINE_SIZE_MASK) | dv_size); + unsigned long temp, dv_size = MDC_DV_LINE_SIZE_1024; + + if (pitch > 1024) { + dv_size = MDC_DV_LINE_SIZE_2048; + } + if (pitch > 2048) { + dv_size = MDC_DV_LINE_SIZE_4096; + } + if (pitch > 4096) { + dv_size = MDC_DV_LINE_SIZE_8192; + } + + /* WRITE DIRTY/VALID CONTROL WITH LINE LENGTH */ + + temp = READ_REG32(MDC_DV_CTL); + WRITE_REG32(MDC_DV_CTL, (temp & ~MDC_DV_LINE_SIZE_MASK) | dv_size); } /* XXX - this is nothing like the original function - not sure exactly what the purpose is for this quite yet */ @@ -850,674 +747,678 @@ GXSetDvLineSize(unsigned int pitch) static void GXAdjustFrame(int scrnIndex, int x, int y, int flags) { - ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; - GeodeRec *pGeode = GEODEPTR(pScrni); - unsigned long offset; + ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; + GeodeRec *pGeode = GEODEPTR(pScrni); + unsigned long offset; - offset = - pGeode->FBOffset + y * pGeode->Pitch + - x * (pScrni->bitsPerPixel >> 3); + offset = + pGeode->FBOffset + y * pGeode->Pitch + + x * (pScrni->bitsPerPixel >> 3); - gfx_set_display_offset(offset); + gfx_set_display_offset(offset); } static Bool GXSetVideoMode(ScrnInfoPtr pScrni, DisplayModePtr pMode) { - GeodeRec *pGeode = GEODEPTR(pScrni); - int flags; - - pScrni->vtSema = TRUE; - - gx_disable_dac_power(); - - if (pMode->Flags & V_NHSYNC) - flags |= 1; - if (pMode->Flags & V_NVSYNC) - flags |= 2; - - /* XXX Question - why even use set_display_mode at all - shouldn't the - * mode timings be the same that we advertise? */ - - /* Only use the panel mode for built in modes */ - - if ((pMode->type && pMode->type != M_T_USERDEF) && pGeode->Panel) { - GFX(set_fixed_timings(pGeode->FPBX, pGeode->FPBY, - pMode->CrtcHDisplay, pMode->CrtcVDisplay, - pScrni->bitsPerPixel)); - } else { - if (pGeode->Panel) - GFX(set_panel_present(pGeode->FPBX, pGeode->FPBY, - pMode->CrtcHDisplay, pMode->CrtcVDisplay, - pScrni->bitsPerPixel)); - - GFX(set_display_timings(pScrni->bitsPerPixel, flags, - pMode->CrtcHDisplay, pMode->CrtcHBlankStart, - pMode->CrtcHSyncStart, pMode->CrtcHSyncEnd, - pMode->CrtcHBlankEnd, pMode->CrtcHTotal, - pMode->CrtcVDisplay, pMode->CrtcVBlankStart, - pMode->CrtcVSyncStart, pMode->CrtcVSyncEnd, - pMode->CrtcVBlankEnd, pMode->CrtcVTotal, - (int)((pMode->SynthClock / 1000.0) * 0x10000))); - } - - GFX(set_crt_enable(CRT_ENABLE)); - GFX(set_display_pitch(pGeode->displayPitch)); - GFX(set_display_offset(0L)); - GFX(wait_vertical_blank()); - - if (pGeode->Compression) { - GXSetDvLineSize(pGeode->Pitch); - - gfx_set_compression_offset(pGeode->CBOffset); - gfx_set_compression_pitch(GX_CB_PITCH); - gfx_set_compression_size(GX_CB_SIZE); - - gfx_set_compression_enable(1); - } - - if (pGeode->HWCursor && !(pMode->Flags & V_DBLSCAN)) { - GXLoadCursorImage(pScrni, NULL); - GFX(set_cursor_position(pGeode->CursorStartOffset, 0, 0, 0, 0)); - GXShowCursor(pScrni); - } else { - GFX(set_cursor_enable(0)); - pGeode->HWCursor = FALSE; - } - - GXAdjustFrame(pScrni->scrnIndex, pScrni->frameX0, pScrni->frameY0, 0); - gx_enable_dac_power(); - - return TRUE; + GeodeRec *pGeode = GEODEPTR(pScrni); + int flags; + + pScrni->vtSema = TRUE; + + gx_disable_dac_power(); + + if (pMode->Flags & V_NHSYNC) + flags |= 1; + if (pMode->Flags & V_NVSYNC) + flags |= 2; + + /* XXX Question - why even use set_display_mode at all - shouldn't the + * mode timings be the same that we advertise? */ + + /* Only use the panel mode for built in modes */ + + if ((pMode->type && pMode->type != M_T_USERDEF) && pGeode->Panel) { + GFX(set_fixed_timings(pGeode->PanelX, pGeode->PanelY, + pMode->CrtcHDisplay, pMode->CrtcVDisplay, + pScrni->bitsPerPixel)); + } else { + if (pGeode->Panel) + GFX(set_panel_present(pGeode->PanelX, pGeode->PanelY, + pMode->CrtcHDisplay, pMode->CrtcVDisplay, + pScrni->bitsPerPixel)); + + GFX(set_display_timings(pScrni->bitsPerPixel, flags, + pMode->CrtcHDisplay, pMode->CrtcHBlankStart, + pMode->CrtcHSyncStart, pMode->CrtcHSyncEnd, + pMode->CrtcHBlankEnd, pMode->CrtcHTotal, + pMode->CrtcVDisplay, pMode->CrtcVBlankStart, + pMode->CrtcVSyncStart, pMode->CrtcVSyncEnd, + pMode->CrtcVBlankEnd, pMode->CrtcVTotal, + (int)((pMode->SynthClock / 1000.0) * 0x10000))); + } + + GFX(set_crt_enable(CRT_ENABLE)); + GFX(set_display_pitch(pGeode->displayPitch)); + GFX(set_display_offset(0L)); + GFX(wait_vertical_blank()); + + if (pGeode->Compression) { + GXSetDvLineSize(pGeode->Pitch); + + gfx_set_compression_offset(pGeode->CBData.compression_offset); + gfx_set_compression_pitch(GX_CB_PITCH); + gfx_set_compression_size(GX_CB_SIZE); + + gfx_set_compression_enable(1); + } + + if (pGeode->HWCursor && !(pMode->Flags & V_DBLSCAN)) { + GXLoadCursorImage(pScrni, NULL); + GFX(set_cursor_position(pGeode->CursorStartOffset, 0, 0, 0, 0)); + GXShowCursor(pScrni); + } else { + GFX(set_cursor_enable(0)); + pGeode->HWCursor = FALSE; + } + + GXAdjustFrame(pScrni->scrnIndex, pScrni->frameX0, pScrni->frameY0, 0); + gx_enable_dac_power(); + + return TRUE; } static Bool GXSwitchMode(int index, DisplayModePtr pMode, int flags) { - ScrnInfoPtr pScrni = xf86Screens[index]; - GeodeRec *pGeode = GEODEPTR(pScrni); - int ret = TRUE; - int rotate; + ScrnInfoPtr pScrni = xf86Screens[index]; + GeodeRec *pGeode = GEODEPTR(pScrni); + int ret = TRUE; + int rotate; - /* Syn the engine and shutdown the DAC momentarily */ + /* Syn the engine and shutdown the DAC momentarily */ - gfx_wait_until_idle(); + gfx_wait_until_idle(); - /* Set up the memory for the new mode */ - rotate = GXGetRotation(pScrni->pScreen); - ret = GXAllocateMemory(pScrni->pScreen, pScrni, rotate); + /* Set up the memory for the new mode */ + rotate = GXGetRotation(pScrni->pScreen); + ret = GXAllocateMemory(pScrni->pScreen, pScrni, rotate); - if (ret) { - if (pGeode->curMode != pMode) - ret = GXSetVideoMode(pScrni, pMode); - } + if (ret) { + if (pGeode->curMode != pMode) + ret = GXSetVideoMode(pScrni, pMode); + } - if (ret) - ret = GXRotate(pScrni, pMode); + if (ret) + ret = GXRotate(pScrni, pMode); - /* Go back the way it was */ + /* Go back the way it was */ - if (ret == FALSE) { - if (!GXSetVideoMode(pScrni, pGeode->curMode)) - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, - "Could not restore the previous mode\n"); - } else - pGeode->curMode = pMode; + if (ret == FALSE) { + if (!GXSetVideoMode(pScrni, pGeode->curMode)) + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Could not restore the previous mode\n"); + } else + pGeode->curMode = pMode; - return ret; + return ret; } static void GXLeaveGraphics(ScrnInfoPtr pScrni) { - GeodeRec *pGeode = GEODEPTR(pScrni); - - gfx_wait_until_idle(); - - /* Restore VG registers */ - gfx_set_display_timings(pGeode->FBgfxdisplaytiming.wBpp, - pGeode->FBgfxdisplaytiming.wPolarity, - pGeode->FBgfxdisplaytiming.wHActive, - pGeode->FBgfxdisplaytiming.wHBlankStart, - pGeode->FBgfxdisplaytiming.wHSyncStart, - pGeode->FBgfxdisplaytiming.wHSyncEnd, - pGeode->FBgfxdisplaytiming.wHBlankEnd, - pGeode->FBgfxdisplaytiming.wHTotal, - pGeode->FBgfxdisplaytiming.wVActive, - pGeode->FBgfxdisplaytiming.wVBlankStart, - pGeode->FBgfxdisplaytiming.wVSyncStart, - pGeode->FBgfxdisplaytiming.wVSyncEnd, - pGeode->FBgfxdisplaytiming.wVBlankEnd, - pGeode->FBgfxdisplaytiming.wVTotal, - pGeode->FBgfxdisplaytiming.dwDotClock); - - gfx_set_compression_enable(0); - - /* Restore the previous Compression state */ - if (pGeode->FBCompressionEnable) { - gfx_set_compression_offset(pGeode->FBCompressionOffset); - gfx_set_compression_pitch(pGeode->FBCompressionPitch); - gfx_set_compression_size(pGeode->FBCompressionSize); - gfx_set_compression_enable(1); - } - - gfx_set_display_pitch(pGeode->FBgfxdisplaytiming.wPitch); - - gfx_set_display_offset(pGeode->FBDisplayOffset); - - /* Restore Cursor */ - gfx_set_cursor_position(pGeode->FBCursorOffset, 0, 0, 0, 0); - - if (pGeode->useVGA) { - pGeode->vesa->pInt->num = 0x10; - pGeode->vesa->pInt->ax = 0x0 | pGeode->FBBIOSMode; - pGeode->vesa->pInt->bx = 0; - xf86ExecX86int10(pGeode->vesa->pInt); - gfx_delay_milliseconds(3); - } - - GXRestore(pScrni); - - gx_enable_dac_power(); + GeodeRec *pGeode = GEODEPTR(pScrni); + + gfx_wait_until_idle(); + + /* Restore VG registers */ + gfx_set_display_timings(pGeode->FBgfxdisplaytiming.wBpp, + pGeode->FBgfxdisplaytiming.wPolarity, + pGeode->FBgfxdisplaytiming.wHActive, + pGeode->FBgfxdisplaytiming.wHBlankStart, + pGeode->FBgfxdisplaytiming.wHSyncStart, + pGeode->FBgfxdisplaytiming.wHSyncEnd, + pGeode->FBgfxdisplaytiming.wHBlankEnd, + pGeode->FBgfxdisplaytiming.wHTotal, + pGeode->FBgfxdisplaytiming.wVActive, + pGeode->FBgfxdisplaytiming.wVBlankStart, + pGeode->FBgfxdisplaytiming.wVSyncStart, + pGeode->FBgfxdisplaytiming.wVSyncEnd, + pGeode->FBgfxdisplaytiming.wVBlankEnd, + pGeode->FBgfxdisplaytiming.wVTotal, + pGeode->FBgfxdisplaytiming.dwDotClock); + + gfx_set_compression_enable(0); + + /* Restore the previous Compression state */ + if (pGeode->FBCompressionEnable) { + gfx_set_compression_offset(pGeode->FBCompressionOffset); + gfx_set_compression_pitch(pGeode->FBCompressionPitch); + gfx_set_compression_size(pGeode->FBCompressionSize); + gfx_set_compression_enable(1); + } + + gfx_set_display_pitch(pGeode->FBgfxdisplaytiming.wPitch); + + gfx_set_display_offset(pGeode->FBDisplayOffset); + + /* Restore Cursor */ + gfx_set_cursor_position(pGeode->FBCursorOffset, 0, 0, 0, 0); + + if (pGeode->useVGA) { + pGeode->vesa->pInt->num = 0x10; + pGeode->vesa->pInt->ax = 0x0 | pGeode->FBBIOSMode; + pGeode->vesa->pInt->bx = 0; + xf86ExecX86int10(pGeode->vesa->pInt); + gfx_delay_milliseconds(3); + } + + GXRestore(pScrni); + + gx_enable_dac_power(); } static Bool GXCloseScreen(int scrnIndex, ScreenPtr pScrn) { - ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; - GeodeRec *pGeode = GEODEPTR(pScrni); + ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; + GeodeRec *pGeode = GEODEPTR(pScrni); - if (pScrni->vtSema) - GXLeaveGraphics(pScrni); + if (pScrni->vtSema) + GXLeaveGraphics(pScrni); - if (pGeode->AccelInfoRec) - XAADestroyInfoRec(pGeode->AccelInfoRec); + if (pGeode->AccelInfoRec) + XAADestroyInfoRec(pGeode->AccelInfoRec); - if (pGeode->AccelImageWriteBuffers) { - xfree(pGeode->AccelImageWriteBuffers[0]); - xfree(pGeode->AccelImageWriteBuffers); - pGeode->AccelImageWriteBuffers = NULL; - } + if (pGeode->AccelImageWriteBuffers) { + xfree(pGeode->AccelImageWriteBuffers[0]); + xfree(pGeode->AccelImageWriteBuffers); + pGeode->AccelImageWriteBuffers = NULL; + } - if (pGeode->AccelColorExpandBuffers) { - xfree(pGeode->AccelColorExpandBuffers); - pGeode->AccelColorExpandBuffers = NULL; - } + if (pGeode->AccelColorExpandBuffers) { + xfree(pGeode->AccelColorExpandBuffers); + pGeode->AccelColorExpandBuffers = NULL; + } - if (pGeode->pExa) { - exaDriverFini(pScrn); - xfree(pGeode->pExa); - pGeode->pExa = NULL; - } + if (pGeode->pExa) { + exaDriverFini(pScrn); + xfree(pGeode->pExa); + pGeode->pExa = NULL; + } - pScrni->vtSema = FALSE; + pScrni->vtSema = FALSE; - GXUnmapMem(pScrni); + GXUnmapMem(pScrni); - if (pGeode && (pScrn->CloseScreen = pGeode->CloseScreen)) { - pGeode->CloseScreen = NULL; - return ((*pScrn->CloseScreen) (scrnIndex, pScrn)); - } + + pScrni->PointerMoved = pGeode->PointerMoved; + pScrn->CloseScreen = pGeode->CloseScreen; + + if (pScrn->CloseScreen) + return (*pScrn->CloseScreen)(scrnIndex, pScrn); - return TRUE; + return TRUE; } static Bool GXEnterGraphics(ScreenPtr pScrn, ScrnInfoPtr pScrni) { - GeodeRec *pGeode = GEODEPTR(pScrni); - - if (!GXMapMem(pScrni)) - return FALSE; - - gfx_wait_until_idle(); - - /* Save off the current state (should this be somewhere else)? */ - - pGeode->FBgfxdisplaytiming.dwDotClock = gfx_get_clock_frequency(); - pGeode->FBgfxdisplaytiming.wPitch = gfx_get_display_pitch(); - pGeode->FBgfxdisplaytiming.wBpp = gfx_get_display_bpp(); - pGeode->FBgfxdisplaytiming.wHTotal = gfx_get_htotal(); - pGeode->FBgfxdisplaytiming.wHActive = gfx_get_hactive(); - pGeode->FBgfxdisplaytiming.wHSyncStart = gfx_get_hsync_start(); - pGeode->FBgfxdisplaytiming.wHSyncEnd = gfx_get_hsync_end(); - pGeode->FBgfxdisplaytiming.wHBlankStart = gfx_get_hblank_start(); - pGeode->FBgfxdisplaytiming.wHBlankEnd = gfx_get_hblank_end(); - pGeode->FBgfxdisplaytiming.wVTotal = gfx_get_vtotal(); - pGeode->FBgfxdisplaytiming.wVActive = gfx_get_vactive(); - pGeode->FBgfxdisplaytiming.wVSyncStart = gfx_get_vsync_start(); - pGeode->FBgfxdisplaytiming.wVSyncEnd = gfx_get_vsync_end(); - pGeode->FBgfxdisplaytiming.wVBlankStart = gfx_get_vblank_start(); - pGeode->FBgfxdisplaytiming.wVBlankEnd = gfx_get_vblank_end(); - pGeode->FBgfxdisplaytiming.wPolarity = gfx_get_sync_polarities(); - - pGeode->FBDisplayOffset = gfx_get_display_offset(); - - if (pGeode->useVGA) { - vgaHWPtr pvgaHW = VGAHWPTR(pScrni); - pGeode->FBBIOSMode = pvgaHW->readCrtc(pvgaHW, 0x040); - } + GeodeRec *pGeode = GEODEPTR(pScrni); + + if (!GXMapMem(pScrni)) + return FALSE; - pGeode->FBCompressionEnable = gfx_get_compression_enable(); - pGeode->FBCompressionOffset = gfx_get_compression_offset(); - pGeode->FBCompressionPitch = gfx_get_compression_pitch(); - pGeode->FBCompressionSize = gfx_get_compression_size(); + gfx_wait_until_idle(); + + /* Save off the current state (should this be somewhere else)? */ + + pGeode->FBgfxdisplaytiming.dwDotClock = gfx_get_clock_frequency(); + pGeode->FBgfxdisplaytiming.wPitch = gfx_get_display_pitch(); + pGeode->FBgfxdisplaytiming.wBpp = gfx_get_display_bpp(); + pGeode->FBgfxdisplaytiming.wHTotal = gfx_get_htotal(); + pGeode->FBgfxdisplaytiming.wHActive = gfx_get_hactive(); + pGeode->FBgfxdisplaytiming.wHSyncStart = gfx_get_hsync_start(); + pGeode->FBgfxdisplaytiming.wHSyncEnd = gfx_get_hsync_end(); + pGeode->FBgfxdisplaytiming.wHBlankStart = gfx_get_hblank_start(); + pGeode->FBgfxdisplaytiming.wHBlankEnd = gfx_get_hblank_end(); + pGeode->FBgfxdisplaytiming.wVTotal = gfx_get_vtotal(); + pGeode->FBgfxdisplaytiming.wVActive = gfx_get_vactive(); + pGeode->FBgfxdisplaytiming.wVSyncStart = gfx_get_vsync_start(); + pGeode->FBgfxdisplaytiming.wVSyncEnd = gfx_get_vsync_end(); + pGeode->FBgfxdisplaytiming.wVBlankStart = gfx_get_vblank_start(); + pGeode->FBgfxdisplaytiming.wVBlankEnd = gfx_get_vblank_end(); + pGeode->FBgfxdisplaytiming.wPolarity = gfx_get_sync_polarities(); + + pGeode->FBDisplayOffset = gfx_get_display_offset(); + + if (pGeode->useVGA) { + vgaHWPtr pvgaHW = VGAHWPTR(pScrni); + pGeode->FBBIOSMode = pvgaHW->readCrtc(pvgaHW, 0x040); + } + + pGeode->FBCompressionEnable = gfx_get_compression_enable(); + pGeode->FBCompressionOffset = gfx_get_compression_offset(); + pGeode->FBCompressionPitch = gfx_get_compression_pitch(); + pGeode->FBCompressionSize = gfx_get_compression_size(); #ifdef PNL_SUP - Pnl_SavePanelState(); + Pnl_SavePanelState(); #endif - /* Turn off the VGA */ + /* Turn off the VGA */ - if (pGeode->useVGA && pGeode->FBVGAActive) { - unsigned short sequencer; - vgaHWPtr pvgaHW = VGAHWPTR(pScrni); + if (pGeode->useVGA && pGeode->FBVGAActive) { + unsigned short sequencer; + vgaHWPtr pvgaHW = VGAHWPTR(pScrni); - /* Map VGA aperture */ - if (!vgaHWMapMem(pScrni)) - return FALSE; + /* Map VGA aperture */ + if (!vgaHWMapMem(pScrni)) + return FALSE; - /* Unlock VGA registers */ - vgaHWUnlock(pvgaHW); + /* Unlock VGA registers */ + vgaHWUnlock(pvgaHW); - /* Save the current state and setup the current mode */ - vgaHWSave(pScrni, &VGAHWPTR(pScrni)->SavedReg, VGA_SR_ALL); + /* Save the current state and setup the current mode */ + vgaHWSave(pScrni, &VGAHWPTR(pScrni)->SavedReg, VGA_SR_ALL); - /* DISABLE VGA SEQUENCER */ - /* This allows the VGA state machine to terminate. We must delay */ - /* such that there are no pending MBUS requests. */ + /* DISABLE VGA SEQUENCER */ + /* This allows the VGA state machine to terminate. We must delay */ + /* such that there are no pending MBUS requests. */ - gfx_outb(MDC_SEQUENCER_INDEX, MDC_SEQUENCER_CLK_MODE); - sequencer = gfx_inb(MDC_SEQUENCER_DATA); - sequencer |= MDC_CLK_MODE_SCREEN_OFF; - gfx_outb(MDC_SEQUENCER_DATA, sequencer); + gfx_outb(MDC_SEQUENCER_INDEX, MDC_SEQUENCER_CLK_MODE); + sequencer = gfx_inb(MDC_SEQUENCER_DATA); + sequencer |= MDC_CLK_MODE_SCREEN_OFF; + gfx_outb(MDC_SEQUENCER_DATA, sequencer); - gfx_delay_milliseconds(1); + gfx_delay_milliseconds(1); - /* BLANK THE VGA DISPLAY */ - gfx_outw(MDC_SEQUENCER_INDEX, MDC_SEQUENCER_RESET); - sequencer = gfx_inb(MDC_SEQUENCER_DATA); - sequencer &= ~MDC_RESET_VGA_DISP_ENABLE; - gfx_outb(MDC_SEQUENCER_DATA, sequencer); + /* BLANK THE VGA DISPLAY */ + gfx_outw(MDC_SEQUENCER_INDEX, MDC_SEQUENCER_RESET); + sequencer = gfx_inb(MDC_SEQUENCER_DATA); + sequencer &= ~MDC_RESET_VGA_DISP_ENABLE; + gfx_outb(MDC_SEQUENCER_DATA, sequencer); - gfx_delay_milliseconds(1); - } + gfx_delay_milliseconds(1); + } - /* Set up the memory */ - /* XXX - FIXME - when we alow inital rotation, it should be here */ - GXAllocateMemory(pScrn, pScrni, pGeode->rotation); + /* Set up the memory */ + /* XXX - FIXME - when we alow inital rotation, it should be here */ + GXAllocateMemory(pScrn, pScrni, pGeode->rotation); - /* Clear the framebuffer */ - memset(pGeode->FBBase + pGeode->displayOffset, 0, pGeode->displaySize); + /* Clear the framebuffer */ + memset(pGeode->FBBase + pGeode->displayOffset, 0, pGeode->displaySize); - /* Set up the video mode */ - GXSetVideoMode(pScrni, pScrni->currentMode); - pGeode->curMode = pScrni->currentMode; + /* Set up the video mode */ + GXSetVideoMode(pScrni, pScrni->currentMode); + pGeode->curMode = pScrni->currentMode; - return TRUE; + return TRUE; } static void GXLoadPalette(ScrnInfoPtr pScrni, - int numColors, int *indizes, LOCO * colors, VisualPtr pVisual) + int numColors, int *indizes, LOCO * colors, VisualPtr pVisual) { - int i, index, color; + int i, index, color; - for (i = 0; i < numColors; i++) { - index = indizes[i] & 0xFF; - color = (((unsigned long)(colors[index].red & 0xFF)) << 16) | - (((unsigned long)(colors[index].green & 0xFF)) << 8) | - ((unsigned long)(colors[index].blue & 0xFF)); + for (i = 0; i < numColors; i++) { + index = indizes[i] & 0xFF; + color = (((unsigned long)(colors[index].red & 0xFF)) << 16) | + (((unsigned long)(colors[index].green & 0xFF)) << 8) | + ((unsigned long)(colors[index].blue & 0xFF)); - GFX(set_display_palette_entry(index, color)); - } + GFX(set_display_palette_entry(index, color)); + } } #ifdef DPMSExtension static void GXPanelPower(int enable) { - unsigned long power = READ_VID32(RCDF_POWER_MANAGEMENT); + unsigned long power = READ_VID32(RCDF_POWER_MANAGEMENT); - if (enable != 0) - power |= RCDF_PM_PANEL_POWER_ON; - else - power &= ~RCDF_PM_PANEL_POWER_ON; + if (enable != 0) + power |= RCDF_PM_PANEL_POWER_ON; + else + power &= ~RCDF_PM_PANEL_POWER_ON; - WRITE_VID32(RCDF_POWER_MANAGEMENT, power); + WRITE_VID32(RCDF_POWER_MANAGEMENT, power); } static void GXDPMSSet(ScrnInfoPtr pScrni, int mode, int flags) { - GeodeRec *pGeode; + GeodeRec *pGeode; - pGeode = GEODEPTR(pScrni); + pGeode = GEODEPTR(pScrni); - if (!pScrni->vtSema) - return; + if (!pScrni->vtSema) + return; - switch (mode) { - case DPMSModeOn: - /* Screen: On; HSync: On; VSync: On */ - GFX(set_crt_enable(CRT_ENABLE)); + switch (mode) { + case DPMSModeOn: + /* Screen: On; HSync: On; VSync: On */ + GFX(set_crt_enable(CRT_ENABLE)); #if defined(PNL_SUP) - if (pGeode->Panel) { - Pnl_PowerUp(); - GXPanelPower(1); - } + if (pGeode->Panel) { + Pnl_PowerUp(); + GXPanelPower(1); + } #endif - break; + break; - case DPMSModeStandby: - /* Screen: Off; HSync: Off; VSync: On */ - GFX(set_crt_enable(CRT_STANDBY)); + case DPMSModeStandby: + /* Screen: Off; HSync: Off; VSync: On */ + GFX(set_crt_enable(CRT_STANDBY)); #if defined(PNL_SUP) - if (pGeode->Panel) { - Pnl_PowerDown(); - GXPanelPower(0); - } + if (pGeode->Panel) { + Pnl_PowerDown(); + GXPanelPower(0); + } #endif - break; + break; - case DPMSModeSuspend: - /* Screen: Off; HSync: On; VSync: Off */ - GFX(set_crt_enable(CRT_SUSPEND)); + case DPMSModeSuspend: + /* Screen: Off; HSync: On; VSync: Off */ + GFX(set_crt_enable(CRT_SUSPEND)); #if defined(PNL_SUP) - if (pGeode->Panel) { - Pnl_PowerDown(); - GXPanelPower(0); - } + if (pGeode->Panel) { + Pnl_PowerDown(); + GXPanelPower(0); + } #endif - break; + break; - case DPMSModeOff: - /* Screen: Off; HSync: Off; VSync: Off */ - GFX(set_crt_enable(CRT_DISABLE)); + case DPMSModeOff: + /* Screen: Off; HSync: Off; VSync: Off */ + GFX(set_crt_enable(CRT_DISABLE)); #if defined(PNL_SUP) - if (pGeode->Panel) { - Pnl_PowerDown(); - GXPanelPower(0); - } -#endif - break; + if (pGeode->Panel) { + Pnl_PowerDown(); + GXPanelPower(0); } +#endif + break; + } } #endif static Bool GXCreateScreenResources(ScreenPtr pScreen) { - ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; - GeodeRec *pGeode = GEODEPTR(pScrni); - - pScreen->CreateScreenResources = pGeode->CreateScreenResources; - if (!(*pScreen->CreateScreenResources) (pScreen)) - return FALSE; - - if (xf86LoaderCheckSymbol("GXRandRSetConfig") - && pGeode->rotation != RR_Rotate_0) { - Rotation(*GXRandRSetConfig) (ScreenPtr pScreen, Rotation rr, int rate, - RRScreenSizePtr pSize) = NULL; - RRScreenSize p; - Rotation requestedRotation = pGeode->rotation; - - pGeode->rotation = RR_Rotate_0; - - /* Just setup enough for an initial rotate */ - - p.width = pScreen->width; - p.height = pScreen->height; - p.mmWidth = pScreen->mmWidth; - p.mmHeight = pScreen->mmHeight; - - GXRandRSetConfig = LoaderSymbol("GXRandRSetConfig"); - if (GXRandRSetConfig) { - pGeode->starting = TRUE; - (*GXRandRSetConfig) (pScreen, requestedRotation, 0, &p); - pGeode->starting = FALSE; - } + ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; + GeodeRec *pGeode = GEODEPTR(pScrni); + + pScreen->CreateScreenResources = pGeode->CreateScreenResources; + if (!(*pScreen->CreateScreenResources) (pScreen)) + return FALSE; + + if (xf86LoaderCheckSymbol("GXRandRSetConfig") + && pGeode->rotation != RR_Rotate_0) { + Rotation(*GXRandRSetConfig) (ScreenPtr pScreen, Rotation rr, int rate, + RRScreenSizePtr pSize) = NULL; + RRScreenSize p; + Rotation requestedRotation = pGeode->rotation; + + pGeode->rotation = RR_Rotate_0; + + /* Just setup enough for an initial rotate */ + + p.width = pScreen->width; + p.height = pScreen->height; + p.mmWidth = pScreen->mmWidth; + p.mmHeight = pScreen->mmHeight; + + GXRandRSetConfig = LoaderSymbol("GXRandRSetConfig"); + if (GXRandRSetConfig) { + pGeode->starting = TRUE; + (*GXRandRSetConfig) (pScreen, requestedRotation, 0, &p); + pGeode->starting = FALSE; } + } - return TRUE; + return TRUE; } static Bool GXScreenInit(int scrnIndex, ScreenPtr pScrn, int argc, char **argv) { - ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; - GeodeRec *pGeode = GEODEPTR(pScrni); - XF86ModReqInfo shadowReq; - int maj, min, ret, rotate; - BOOL shadowfb = TRUE; + ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; + GeodeRec *pGeode = GEODEPTR(pScrni); + XF86ModReqInfo shadowReq; + int maj, min, ret, rotate; + BOOL shadowfb = TRUE; - pGeode->starting = TRUE; + pGeode->starting = TRUE; - /* If we are using VGA then go ahead and map the memory */ + /* If we are using VGA then go ahead and map the memory */ - if (pGeode->useVGA) { + if (pGeode->useVGA) { - if (!vgaHWMapMem(pScrni)) - return FALSE; + if (!vgaHWMapMem(pScrni)) + return FALSE; - vgaHWGetIOBase(VGAHWPTR(pScrni)); - } + vgaHWGetIOBase(VGAHWPTR(pScrni)); + } - if (!pGeode->NoAccel) { - - if (pGeode->useEXA) { - - if (!(pGeode->pExa = xnfcalloc(sizeof(ExaDriverRec), 1))) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Couldn't allocate the EXA structure.\n"); - pGeode->NoAccel = TRUE; - } else { - ExaDriverPtr pExa = pGeode->pExa; - - /* THis is set in GXAllocMem */ - pExa->memoryBase = 0; - - /* This is set in GXAllocateMemory */ - pExa->memorySize = 0; - - pExa->pixmapOffsetAlign = 32; - pExa->pixmapPitchAlign = 32; - pExa->flags = EXA_OFFSCREEN_PIXMAPS; - pExa->maxX = pGeode->maxWidth - 1; - pExa->maxY = pGeode->maxHeight - 1; - } - } else { - pGeode->AccelImageWriteBuffers = - xcalloc(sizeof(pGeode->AccelImageWriteBuffers[0]), + if (!pGeode->NoAccel) { + + if (pGeode->useEXA) { + + if (!(pGeode->pExa = xnfcalloc(sizeof(ExaDriverRec), 1))) { + xf86DrvMsg(scrnIndex, X_ERROR, + "Couldn't allocate the EXA structure.\n"); + pGeode->NoAccel = TRUE; + } else { + ExaDriverPtr pExa = pGeode->pExa; + + /* THis is set in GXAllocMem */ + pExa->memoryBase = 0; + + /* This is set in GXAllocateMemory */ + pExa->memorySize = 0; + + pExa->pixmapOffsetAlign = 32; + pExa->pixmapPitchAlign = 32; + pExa->flags = EXA_OFFSCREEN_PIXMAPS; + pExa->maxX = pGeode->maxWidth - 1; + pExa->maxY = pGeode->maxHeight - 1; + } + } else { + pGeode->AccelImageWriteBuffers = + xcalloc(sizeof(pGeode->AccelImageWriteBuffers[0]), pGeode->NoOfImgBuffers); - pGeode->AccelColorExpandBuffers = - xcalloc(sizeof(pGeode->AccelColorExpandBuffers[0]), + pGeode->AccelColorExpandBuffers = + xcalloc(sizeof(pGeode->AccelColorExpandBuffers[0]), pGeode->NoOfColorExpandLines); - } } + } - /* XXX FIXME - Take down any of the structures on failure? */ + /* XXX FIXME - Take down any of the structures on failure? */ - if (!GXEnterGraphics(pScrn, pScrni)) - return FALSE; + if (!GXEnterGraphics(pScrn, pScrni)) + return FALSE; - miClearVisualTypes(); + miClearVisualTypes(); - /* XXX Again - take down anything? */ + /* XXX Again - take down anything? */ - if (pScrni->bitsPerPixel > 8) { - if (!miSetVisualTypes(pScrni->depth, - TrueColorMask, pScrni->rgbBits, pScrni->defaultVisual)) { - return FALSE; - } - } else { - if (!miSetVisualTypes(pScrni->depth, - miGetDefaultVisualMask(pScrni->depth), - pScrni->rgbBits, pScrni->defaultVisual)) { - return FALSE; - } + if (pScrni->bitsPerPixel > 8) { + if (!miSetVisualTypes(pScrni->depth, + TrueColorMask, pScrni->rgbBits, pScrni->defaultVisual)) { + return FALSE; + } + } else { + if (!miSetVisualTypes(pScrni->depth, + miGetDefaultVisualMask(pScrni->depth), + pScrni->rgbBits, pScrni->defaultVisual)) { + return FALSE; } + } - miSetPixmapDepths(); + miSetPixmapDepths(); - /* Point at the visible area to start */ + /* Point at the visible area to start */ - ret = fbScreenInit(pScrn, pGeode->FBBase + pGeode->displayOffset, - pScrni->virtualX, pScrni->virtualY, - pScrni->xDpi, pScrni->yDpi, pGeode->displayWidth, - pScrni->bitsPerPixel); + ret = fbScreenInit(pScrn, pGeode->FBBase + pGeode->displayOffset, + pScrni->virtualX, pScrni->virtualY, + pScrni->xDpi, pScrni->yDpi, pGeode->displayWidth, + pScrni->bitsPerPixel); - if (!ret) - return FALSE; + if (!ret) + return FALSE; - xf86SetBlackWhitePixels(pScrn); + xf86SetBlackWhitePixels(pScrn); - /* Set up the color ordering */ + /* Set up the color ordering */ - if (pScrni->bitsPerPixel > 8) { - VisualPtr visual = pScrn->visuals + pScrn->numVisuals; + if (pScrni->bitsPerPixel > 8) { + VisualPtr visual = pScrn->visuals + pScrn->numVisuals; - while (--visual >= pScrn->visuals) { - if ((visual->class | DynamicClass) == DirectColor) { - visual->offsetRed = pScrni->offset.red; - visual->offsetGreen = pScrni->offset.green; - visual->offsetBlue = pScrni->offset.blue; - visual->redMask = pScrni->mask.red; - visual->greenMask = pScrni->mask.green; - visual->blueMask = pScrni->mask.blue; - } - } + while (--visual >= pScrn->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScrni->offset.red; + visual->offsetGreen = pScrni->offset.green; + visual->offsetBlue = pScrni->offset.blue; + visual->redMask = pScrni->mask.red; + visual->greenMask = pScrni->mask.green; + visual->blueMask = pScrni->mask.blue; + } } + } - /* Must follow the color ordering */ - fbPictureInit(pScrn, 0, 0); + /* Must follow the color ordering */ + fbPictureInit(pScrn, 0, 0); - if (!pGeode->NoAccel) - GXAccelInit(pScrn); + if (!pGeode->NoAccel) + GXAccelInit(pScrn); - miInitializeBackingStore(pScrn); - xf86SetBackingStore(pScrn); + miInitializeBackingStore(pScrn); + xf86SetBackingStore(pScrn); - /* Set up the soft cursor */ - miDCInitialize(pScrn, xf86GetPointerScreenFuncs()); + /* Set up the soft cursor */ + miDCInitialize(pScrn, xf86GetPointerScreenFuncs()); - /* Set up the HW cursor - must follow the soft cursor init */ + /* Set up the HW cursor - must follow the soft cursor init */ - if (pGeode->tryHWCursor) { - if (!GXHWCursorInit(pScrn)) - xf86DrvMsg(scrnIndex, X_ERROR, - "Hardware cursor initialization failed.\n"); - } + if (pGeode->tryHWCursor) { + if (!GXHWCursorInit(pScrn)) + xf86DrvMsg(scrnIndex, X_ERROR, + "Hardware cursor initialization failed.\n"); + } - /* Set up the color map */ + /* Set up the color map */ - if (!miCreateDefColormap(pScrn)) - return FALSE; + if (!miCreateDefColormap(pScrn)) + return FALSE; - if (pScrni->bitsPerPixel == 8) { - /* Must follow initialization of the default colormap */ + if (pScrni->bitsPerPixel == 8) { + /* Must follow initialization of the default colormap */ - if (!xf86HandleColormaps(pScrn, 256, 8, - GXLoadPalette, NULL, - CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) { - return FALSE; - } + if (!xf86HandleColormaps(pScrn, 256, 8, + GXLoadPalette, NULL, + CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) { + return FALSE; } + } #ifdef DPMSExtension - xf86DPMSInit(pScrn, GXDPMSSet, 0); + xf86DPMSInit(pScrn, GXDPMSSet, 0); #endif - GXInitVideo(pScrn); + GXInitVideo(pScrn); - /* Set up RandR */ + /* Set up RandR */ - xf86DisableRandR(); /* We provide our own RandR goodness */ + xf86DisableRandR(); /* We provide our own RandR goodness */ - /* Try to set up the shadow FB for rotation */ + /* Try to set up the shadow FB for rotation */ - memset(&shadowReq, 0, sizeof(shadowReq)); - shadowReq.majorversion = 1; - shadowReq.minorversion = 1; + memset(&shadowReq, 0, sizeof(shadowReq)); + shadowReq.majorversion = 1; + shadowReq.minorversion = 1; - if (LoadSubModule(pScrni->module, "shadow", - NULL, NULL, NULL, &shadowReq, &maj, &min)) { + if (LoadSubModule(pScrni->module, "shadow", + NULL, NULL, NULL, &shadowReq, &maj, &min)) { - rotate = RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270; - shadowSetup(pScrn); - } else { - LoaderErrorMsg(NULL, "shadow", maj, min); - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, - "Error loading shadow - rotation not available.\n"); + rotate = RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270; + shadowSetup(pScrn); + } else { + LoaderErrorMsg(NULL, "shadow", maj, min); + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Error loading shadow - rotation not available.\n"); - if (pGeode->rotation != RR_Rotate_0) - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, - "Reverting back to normal rotation.\n"); + if (pGeode->rotation != RR_Rotate_0) + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Reverting back to normal rotation.\n"); - rotate = pGeode->rotation = RR_Rotate_0; - } + rotate = pGeode->rotation = RR_Rotate_0; + } - GXRandRInit(pScrn, rotate); + GXRandRInit(pScrn, rotate); - pGeode->PointerMoved = pScrni->PointerMoved; - pScrni->PointerMoved = GXPointerMoved; - pGeode->CreateScreenResources = pScrn->CreateScreenResources; - pScrn->CreateScreenResources = GXCreateScreenResources; + pGeode->PointerMoved = pScrni->PointerMoved; + pScrni->PointerMoved = GeodePointerMoved; - pGeode->CloseScreen = pScrn->CloseScreen; - pScrn->CloseScreen = GXCloseScreen; - pScrn->SaveScreen = GXSaveScreen; + pGeode->CreateScreenResources = pScrn->CreateScreenResources; + pScrn->CreateScreenResources = GXCreateScreenResources; - if (serverGeneration == 1) - xf86ShowUnusedOptions(pScrni->scrnIndex, pScrni->options); + pGeode->CloseScreen = pScrn->CloseScreen; + pScrn->CloseScreen = GXCloseScreen; + pScrn->SaveScreen = GXSaveScreen; - pGeode->starting = FALSE; + if (serverGeneration == 1) + xf86ShowUnusedOptions(pScrni->scrnIndex, pScrni->options); - return TRUE; + pGeode->starting = FALSE; + + return TRUE; } static int GXValidMode(int scrnIndex, DisplayModePtr pMode, Bool Verbose, int flags) { - ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; - GeodeRec *pGeode = GEODEPTR(pScrni); - int p, ret; + ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; + GeodeRec *pGeode = GEODEPTR(pScrni); + int p, ret; - /* Not sure if this is an X bug or not - but on my current build, - * user defined modes pass a type of 0 */ + /* Not sure if this is an X bug or not - but on my current build, + * user defined modes pass a type of 0 */ - if (pMode->type && pMode->type != M_T_USERDEF) { + if (pMode->type && pMode->type != M_T_USERDEF) { - if (pGeode->Panel) { - if (pMode->CrtcHDisplay > pGeode->FPBX || - pMode->CrtcVDisplay > pGeode->FPBY || - gfx_is_panel_mode_supported(pGeode->FPBX, pGeode->FPBY, - pMode->CrtcHDisplay, pMode->CrtcVDisplay, - pScrni->bitsPerPixel) < 0) { + if (pGeode->Panel) { + if (pMode->CrtcHDisplay > pGeode->PanelX || + pMode->CrtcVDisplay > pGeode->PanelY || + gfx_is_panel_mode_supported(pGeode->PanelX, pGeode->PanelY, + pMode->CrtcHDisplay, pMode->CrtcVDisplay, + pScrni->bitsPerPixel) < 0) { - return MODE_BAD; - } - } + return MODE_BAD; + } + } - ret = gfx_is_display_mode_supported(pMode->CrtcHDisplay, - pMode->CrtcVDisplay, - pScrni->bitsPerPixel, GXGetRefreshRate(pMode)); - if (ret < 0) { - return MODE_BAD; - } + ret = gfx_is_display_mode_supported(pMode->CrtcHDisplay, + pMode->CrtcVDisplay, + pScrni->bitsPerPixel, + GeodeGetRefreshRate(pMode)); + if (ret < 0) { + return MODE_BAD; } + } - if (pMode->Flags & V_INTERLACE) - return MODE_NO_INTERLACE; + if (pMode->Flags & V_INTERLACE) + return MODE_NO_INTERLACE; - if (pGeode->tryCompression) - p = GXCalculatePitchBytes(pMode->CrtcHDisplay, pScrni->bitsPerPixel); - else - p = ((pMode->CrtcHDisplay + 3) & ~3) * (pScrni->bitsPerPixel >> 3); + if (pGeode->tryCompression) + p = GeodeCalculatePitchBytes(pMode->CrtcHDisplay, pScrni->bitsPerPixel); + else + p = ((pMode->CrtcHDisplay + 3) & ~3) * (pScrni->bitsPerPixel >> 3); - if (p * pMode->CrtcVDisplay > pGeode->FBAvail) - return MODE_MEM; + if (p * pMode->CrtcVDisplay > pGeode->FBAvail) + return MODE_MEM; - return MODE_OK; + return MODE_OK; } /* XXX - Way more to do here */ @@ -1525,92 +1426,155 @@ GXValidMode(int scrnIndex, DisplayModePtr pMode, Bool Verbose, int flags) static Bool GXEnterVT(int scrnIndex, int flags) { - return GXEnterGraphics(NULL, xf86Screens[scrnIndex]); + return GXEnterGraphics(NULL, xf86Screens[scrnIndex]); } static void GXLeaveVT(int scrnIndex, int flags) { - ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; - GeodeRec *pGeode = GEODEPTR(pScrni); + ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; + GeodeRec *pGeode = GEODEPTR(pScrni); - pGeode->PrevDisplayOffset = gfx_get_display_offset(); - GXLeaveGraphics(xf86Screens[scrnIndex]); + pGeode->PrevDisplayOffset = gfx_get_display_offset(); + GXLeaveGraphics(xf86Screens[scrnIndex]); } -static void -GXFreeScreen(int scrnIndex, int flags) +void +GXSetupChipsetFPtr(ScrnInfoPtr pScrn) { - GeodeRec *pGeode = GEODEPTR(xf86Screens[scrnIndex]); + pScrn->PreInit = GXPreInit; + pScrn->ScreenInit = GXScreenInit; + pScrn->SwitchMode = GXSwitchMode; + pScrn->AdjustFrame = GXAdjustFrame; + pScrn->EnterVT = GXEnterVT; + pScrn->LeaveVT = GXLeaveVT; + pScrn->FreeScreen = GeodeFreeScreen; + pScrn->ValidMode = GXValidMode; +} - if (pGeode == NULL) - return; +/* ====== Common functions ====== +/* These are all the common functions that we use for both GX and LX - They live here + * because most of them came along for the GX first, and then were adapted to the LX. + * We could move these to a common function, but there is no hurry + * ============================== */ - if (pGeode->useVGA) { - if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) - vgaHWFreeHWRec(xf86Screens[scrnIndex]); - } - GXFreeRec(xf86Screens[scrnIndex]); +void +GeodePointerMoved(int index, int x, int y) +{ + ScrnInfoPtr pScrni = xf86Screens[index]; + GeodeRec *pGeode = GEODEPTR(pScrni); + + int newX = x, newY = y; + + switch (pGeode->rotation) { + case RR_Rotate_0: + break; + case RR_Rotate_90: + newX = y; + newY = pScrni->pScreen->width - x - 1; + break; + case RR_Rotate_180: + newX = pScrni->pScreen->width - x - 1; + newY = pScrni->pScreen->height - y - 1; + break; + case RR_Rotate_270: + newX = pScrni->pScreen->height - y - 1; + newY = x; + break; + } + + (*pGeode->PointerMoved)(index, newX, newY); } void -GXSetupChipsetFPtr(ScrnInfoPtr pScrn) +GeodeProbeDDC(ScrnInfoPtr pScrni, int index) { - pScrn->PreInit = GXPreInit; - pScrn->ScreenInit = GXScreenInit; - pScrn->SwitchMode = GXSwitchMode; - pScrn->AdjustFrame = GXAdjustFrame; - pScrn->EnterVT = GXEnterVT; - pScrn->LeaveVT = GXLeaveVT; - pScrn->FreeScreen = GXFreeScreen; - pScrn->ValidMode = GXValidMode; + vbeInfoPtr pVbe; + + if (xf86LoadSubModule(pScrni, "vbe")) { + pVbe = VBEInit(NULL, index); + ConfiguredMonitor = vbeDoEDID(pVbe, NULL); + vbeFree(pVbe); + } } -/* STUPID STUFF */ +xf86MonPtr +GeodeDoDDC(ScrnInfoPtr pScrni, int index) +{ + vbeInfoPtr pVbe; + xf86MonPtr info = NULL; + + if (xf86LoadSubModule(pScrni, "vbe") && + (pVbe = VBEInit(NULL, index))) { + xf86LoaderReqSymLists(amdVbeSymbols, NULL); + info = vbeDoEDID(pVbe, NULL); + xf86PrintEDID(info); + xf86SetDDCproperties(pScrni, info); + vbeFree(pVbe); + } else + xf86DrvMsg(pScrni->scrnIndex, X_INFO, + "We cannot do DDC without VBE.\n"); + + return info; +} + +int +GeodeGetFPGeometry(const char *str, int *width, int *height) +{ + + int ret = sscanf(str, "%dx%d", width, height); + + return (ret == 2) ? 0 : 1; +} static void -GXPointerMoved(int index, int x, int y) +GeodeFreeRec(ScrnInfoPtr pScrni) { - ScrnInfoPtr pScrni = xf86Screens[index]; - GeodeRec *pGeode = GEODEPTR(pScrni); - Bool frameChanged = FALSE; - - if (x < 0) - x = 0; - else if (x >= pScrni->virtualX) - x = pScrni->virtualX - 1; - - if (y < 0) - y = 0; - else if (y >= pScrni->virtualY) - y = pScrni->virtualY - 1; - - if (pScrni->frameX0 > x) { - pScrni->frameX0 = x; - pScrni->frameX1 = x + pGeode->HDisplay - 1; - frameChanged = TRUE; - } + if (pScrni->driverPrivate != NULL) { + xfree(pScrni->driverPrivate); + pScrni->driverPrivate = NULL; + } +} - if (pScrni->frameX1 < x) { - pScrni->frameX1 = x + 1; - pScrni->frameX0 = x - pGeode->HDisplay + 1; - frameChanged = TRUE; - } +void +GeodeFreeScreen(int scrnIndex, int flags) +{ + GeodeRec *pGeode = GEODEPTR(xf86Screens[scrnIndex]); - if (pScrni->frameY0 > y) { - pScrni->frameY0 = y; - pScrni->frameY1 = y + pGeode->VDisplay - 1; - frameChanged = TRUE; - } + if (pGeode == NULL) + return; - if (pScrni->frameY1 < y) { - pScrni->frameY1 = y; - pScrni->frameY0 = y - pGeode->VDisplay + 1; - frameChanged = TRUE; - } + if (pGeode->useVGA) { + if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) + vgaHWFreeHWRec(xf86Screens[scrnIndex]); + } + + GeodeFreeRec(xf86Screens[scrnIndex]); +} - if (frameChanged && pScrni->AdjustFrame != NULL) - pScrni->AdjustFrame(pScrni->scrnIndex, pScrni->frameX0, - pScrni->frameY0, 0); +int +GeodeCalculatePitchBytes(unsigned int width, unsigned int bpp) +{ + + int delta = width * (bpp >> 3); + + /* Less then 640 has doubling enabled */ + + if (width < 640) + delta <<= 1; + + /* Calculate the pitch (compression rquires a power of 2) */ + + if (delta > 4096) + delta = 8192; + else if (delta > 2048) + delta = 4096; + else if (delta > 1024) + delta = 2048; + else + delta = 1024; + + return delta; } + diff --git a/src/amd_gx_video.c b/src/amd_gx_video.c index f7c6f77..bede67b 100644 --- a/src/amd_gx_video.c +++ b/src/amd_gx_video.c @@ -11,7 +11,7 @@ * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * IMPDIs2IED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING @@ -625,37 +625,6 @@ GXQueryBestSize(ScrnInfoPtr pScrni, *p_w = 16384; } -static void -GXCopyGreyscale(unsigned char *src, - unsigned char *dst, int srcPitch, int dstPitch, int h, int w) -{ - int i; - unsigned char *src2 = src; - unsigned char *dst2 = dst; - unsigned char *dst3; - unsigned char *src3; - - dstPitch <<= 1; - - while (h--) { - dst3 = dst2; - src3 = src2; - for (i = 0; i < w; i++) { - *dst3++ = *src3++; /* Copy Y data */ - *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */ - } - - src3 = src2; - for (i = 0; i < w; i++) { - *dst3++ = *src3++; /* Copy Y data */ - *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */ - } - - dst2 += dstPitch; - src2 += srcPitch; - } -} - /*---------------------------------------------------------------------------- * GXCopyData420 * @@ -994,8 +963,9 @@ GXDisplayVideo(ScrnInfoPtr pScrni, src_h, drw_w, drw_h, id, offset, pScrni); } -#if REINIT -static Bool +/* Used by LX as well */ + +Bool RegionsEqual(RegionPtr A, RegionPtr B) { int *dataA, *dataB; @@ -1024,7 +994,6 @@ RegionsEqual(RegionPtr A, RegionPtr B) return TRUE; } -#endif /*---------------------------------------------------------------------------- * GXPutImage :This function writes a single frame of video into a @@ -1211,7 +1180,8 @@ GXPutImage(ScrnInfoPtr pScrni, #endif switch (id) { case FOURCC_Y800: - GXCopyGreyscale(buf, dst_start, srcPitch, dstPitch, nlines, npixels); + /* This is shared between LX and GX, so it lives in amd_common.c */ + GeodeCopyGreyscale(buf, dst_start, srcPitch, dstPitch, nlines, npixels); break; case FOURCC_YV12: case FOURCC_I420: @@ -1275,8 +1245,9 @@ GXPutImage(ScrnInfoPtr pScrni, * *---------------------------------------------------------------------------- */ -static int -GXQueryImageAttributes(ScrnInfoPtr pScrni, + +int +GeodeQueryImageAttributes(ScrnInfoPtr pScrni, int id, unsigned short *w, unsigned short *h, int *pitches, int *offsets) { int size; diff --git a/src/amd_lx_accel.c b/src/amd_lx_accel.c deleted file mode 100644 index 4f72d63..0000000 --- a/src/amd_lx_accel.c +++ /dev/null @@ -1,1563 +0,0 @@ -/* - * Copyright (c) 2006 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Neither the name of the Advanced Micro Devices, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - */ - -/* - * File Contents: This file is consists of main Xfree - * acceleration supported routines like solid fill used - * here. - * Project: Geode Xfree Frame buffer device driver. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <sys/types.h> - -/* Xfree86 header files */ - -#include "vgaHW.h" -#include "xf86.h" -#include "xf86_ansic.h" -#include "xaalocal.h" -#include "xf86fbman.h" -#include "miline.h" -#include "xf86_libc.h" -#include "xaarop.h" -#include "amd.h" - -typedef unsigned char uchar; -typedef unsigned int uint; -typedef unsigned short ushort; - -#if DEBUGLVL>0 -extern FILE *zdfp; - -#if DEBUGTIM>0 -#ifndef USE_RDTSC -#define DBLOG(n,s...) do { if((DEBUGLVL)>=(n)) { long secs,usecs; \ - getsecs(&secs,&usecs); fprintf(zdfp,"%d,%d ",secs,usecs); \ - fprintf(zdfp,s); } } while(0) -#else -#define tsc(n) __asm__ __volatile__ ( \ - " rdtsc" \ - : "=a" (((int*)(&(n)))[0]), "=d" (((int*)(&(n)))[1]) \ - : ) -#define DBLOG(n,s...) do { if((DEBUGLVL)>=(n)) { long long t; \ - tsc(t); fprintf(zdfp,"%lld ",t); \ - fprintf(zdfp,s); } } while(0) -#endif -#else -#define DBLOG(n,s...) do { if((DEBUGLVL)>=(n)) fprintf(zdfp,s); } while(0) -#endif -#else -#define DBLOG(n,s...) do {} while(0) -#endif - -#define CALC_FBOFFSET(x, y) (((ulong)(y) << gu3_yshift) | \ - ((ulong)(x) << gu3_xshift)) - -#define OS_UDELAY 0 -#if OS_UDELAY > 0 -#define OS_USLEEP(usec) usleep(usec); -#else -#define OS_USLEEP(usec) -#endif - -#define HOOK(fn) localRecPtr->fn = LX##fn - -static int lx0 = -1, ly0 = -1; -static int lx1 = -1, ly1 = -1; -static int ROP; - -/* #define ENABLE_PREFETCH CIMGP_ENABLE_PREFETCH */ -#define ENABLE_PREFETCH 0 -#define BLTFLAGS_HAZARD CIMGP_BLTFLAGS_HAZARD - -/* specify dst bounding box, upper left/lower right */ -static int -lx_flags0(int x0, int y0, int x1, int y1) -{ - int n = ((ROP ^ (ROP >> 1)) & 0x55) == 0 || /* no dst */ - x0 >= lx1 || y0 >= ly1 || /* rght/below */ - x1 <= lx0 || y1 <= ly0 ? /* left/above */ - ENABLE_PREFETCH : BLTFLAGS_HAZARD; - - lx0 = x0; - ly0 = y0; - lx1 = x1; - ly1 = y1; - return n; -} - -/* specify dst bounding box, upper left/WxH */ -static int -lx_flags1(int x0, int y0, int w, int h) -{ - return lx_flags0(x0, y0, x0 + w, y0 + h); -} - -/* specify dst bounding box, two points */ -static int -lx_flags2(int x0, int y0, int x1, int y1) -{ - int n; - - if (x0 >= x1) { - n = x0; - x0 = x1 - 1; - x1 = n + 1; - } - if (y0 >= y1) { - n = y0; - y0 = y1 - 1; - y1 = n + 1; - } - - return lx_flags0(x0, y0, x1, y1); -} - -/* specify src/dst bounding box, upper left/WxH */ -static int -lx_flags3(int x0, int y0, int x1, int y1, int w, int h) -{ - int x2 = x1 + w, y2 = y1 + h; - - /* dst not hazzard and src not hazzard */ - int n = (((ROP ^ (ROP >> 1)) & 0x55) == 0 || - x1 >= lx1 || y1 >= ly1 || - x2 <= lx0 || y2 <= ly0) && - (((ROP ^ (ROP >> 2)) & 0x33) == 0 || - x0 >= lx1 || y0 >= ly1 || x0 + w <= lx0 || y0 + h <= ly0) - ? ENABLE_PREFETCH : BLTFLAGS_HAZARD; - - lx0 = x1; - ly0 = y1; - lx1 = x2; - ly1 = y2; - - return n; -} - -static void -lx_endpt(int x, int y, int len, int mag, int min, int err, int oct, int *px, - int *py) -{ - int u = len - 1; - int v = (u * min - err) / mag; - - switch (oct) { - default: - case 0: - x += u; - y += v; - break; - case 1: - x += v; - y += u; - break; - case 2: - x += u; - y -= v; - break; - case 3: - x += v; - y -= u; - break; - case 4: - x -= u; - y += v; - break; - case 5: - x -= v; - y += u; - break; - case 6: - x -= u; - y -= v; - break; - case 7: - x -= v; - y -= u; - break; - } - - *px = x; - *py = y; -} - -/* static storage declarations */ - -typedef struct sGBltBox -{ - ulong x, y; - ulong w, h; - ulong color; - int bpp, transparent; -} GBltBox; - -static GBltBox giwr; -static GBltBox gc2s; - -typedef struct sGDashLine -{ - ulong pat; - int len; - int fg; - int bg; -} GDashLine; - -static GDashLine gdln; - -static uint gu3_xshift = 1; -static uint gu3_yshift = 1; -static uint gu3_img_fmt = 0; - -#if !LX_USE_OFFSCRN_MEM -static uint ImgBufOffset; -#else -static uchar *ImgLnsBuffers; -#endif -static uchar *ClrLnsBuffers; -static XAAInfoRecPtr localRecPtr; - -static int lx_src_fmt[4] = { - CIMGP_SOURCE_FMT_8BPP_INDEXED, - CIMGP_SOURCE_FMT_0_5_6_5, - CIMGP_SOURCE_FMT_24BPP, - CIMGP_SOURCE_FMT_8_8_8_8 -}; - -/* pat 0xF0 */ -/* src 0xCC */ -/* dst 0xAA */ - -/* (src FUNC dst) */ - -static const int SDfn[16] = { - 0x00, 0x88, 0x44, 0xCC, 0x22, 0xAA, 0x66, 0xEE, - 0x11, 0x99, 0x55, 0xDD, 0x33, 0xBB, 0x77, 0xFF -}; - -/* ((src FUNC dst) AND pat-mask) OR (dst AND (NOT pat-mask)) */ - -static const int SDfn_PM[16] = { - 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, - 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA -}; - -/* (pat FUNC dst) */ - -static int PDfn[16] = { - 0x00, 0xA0, 0x50, 0xF0, 0x0A, 0xAA, 0x5A, 0xFA, - 0x05, 0xA5, 0x55, 0xF5, 0x0F, 0xAF, 0x5F, 0xFF -}; - -/* ((pat FUNC dst) AND src-mask) OR (dst AND (NOT src-mask)) */ - -static int PDfn_SM[16] = { - 0x22, 0xA2, 0x62, 0xE2, 0x2A, 0xAA, 0x6A, 0xEA, - 0x26, 0xA6, 0x66, 0xE6, 0x2E, 0xAE, 0x6E, 0xEE -}; - -/*---------------------------------------------------------------------------- - * LXAccelSync. - * - * Description :This function is called to synchronize with the graphics - * engine and it waits until the graphic engine is idle. - * This is required before allowing direct access to the - * framebuffer. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * - * Returns :none - *---------------------------------------------------------------------------*/ -void -LXAccelSync(ScrnInfoPtr pScrni) -{ - DBLOG(3, "LXAccelSync()\n"); - while (gp_test_blt_busy() != 0) { - OS_USLEEP(OS_UDELAY) - } -} - -#if LX_FILL_RECT_SUPPORT -/*---------------------------------------------------------------------------- - * LXSetupForSolidFill. - * - * Description :The SetupFor and Subsequent SolidFill(Rect) provide - * filling rectangular areas of the screen with a - * foreground color. - * - * Parameters. - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * color int foreground fill color - * rop int unmapped raster op - * planemask uint -1 (fill) or pattern data - * - * Returns :none - *--------------------------------------------------------------------------*/ -static void -LXSetupForSolidFill(ScrnInfoPtr pScrni, int color, int rop, uint planemask) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(2, "LXSetupForSolidFill(%#x,%#x,%#x)\n", color, rop, planemask); - rop &= 0x0F; - gp_declare_blt(0); - if (planemask == ~0U) { /* fill with color */ - gp_set_raster_operation(ROP = SDfn[rop]); - } else { /* select rop that uses source data for planemask */ - gp_set_raster_operation(ROP = SDfn_PM[rop]); - gp_set_solid_pattern(planemask); - } - gp_set_solid_source(color); - gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch); - gp_write_parameters(); -} - - /*---------------------------------------------------------------------------- - * LXSubsequentSolidFillRect. - * - * Description :see LXSetupForSolidFill. - * - * Parameters. - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * x int destination x offset - * y int destination y offset - * w int fill area width (pixels) - * h int fill area height (pixels) - * - * Returns :none - * - * Sample application uses: - * - Window backgrounds. - * - pull down highlighting. - * - x11perf: rectangle tests (-rect500). - * - x11perf: fill trapezoid tests (-trap100). - * - x11perf: horizontal line segments (-hseg500). - *---------------------------------------------------------------------------*/ -static void -LXSubsequentSolidFillRect(ScrnInfoPtr pScrni, int x, int y, int w, int h) -{ - int flags; - - DBLOG(2, "LXSubsequentSolidFillRect() at %d,%d %dx%d\n", x, y, w, h); - flags = lx_flags1(x, y, w, h); - gp_declare_blt(flags); - gp_pattern_fill(CALC_FBOFFSET(x, y), w, h); -} - -/* LX_FILL_RECT_SUPPORT */ -#endif - -#if LX_CLREXP_8X8_PAT_SUPPORT -/*---------------------------------------------------------------------------- - * LXSetupForColor8x8PatternFill - * - * Description :8x8 color pattern data is 64 pixels of full color data - * stored linearly in offscreen video memory. These patterns - * are useful as a substitute for 8x8 mono patterns when tiling, - * doing opaque stipples, or regular stipples. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * patx int x offset to pattern data - * paty int y offset to pattern data - * rop int unmapped raster operation - * planemask uint -1 (copy) or pattern data - * trans_color int -1 (copy) or transparent color (not enabled) - * trans color only supported on source channel - * or in monochrome pattern channel - * - * Returns :none. - * - *---------------------------------------------------------------------------*/ - -static void -LXSetupForColor8x8PatternFill(ScrnInfoPtr pScrni, int patx, int paty, int rop, - uint planemask, int trans_color) -{ - unsigned long *pat_8x8; - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(2, "LXSetupForColor8x8PatternFill() pat %#x,%#x rop %#x %#x %#x\n", - patx, paty, rop, planemask, trans_color); - pat_8x8 = (unsigned long *)(pGeode->FBBase + CALC_FBOFFSET(patx, paty)); - /* since the cache may be loaded by blt, we must wait here */ - LXAccelSync(pScrni); - gp_set_color_pattern(pat_8x8, gu3_img_fmt, 0, 0); - rop &= 0x0F; - gp_declare_blt(0); - if (planemask == ~0U) { /* fill with pattern */ - gp_set_raster_operation(ROP = PDfn[rop]); - } else { /* select rop that uses source data for planemask */ - gp_set_raster_operation(ROP = PDfn_SM[rop]); - gp_set_solid_source((ulong) planemask); - } - gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch); - gp_write_parameters(); -} - -/*---------------------------------------------------------------------------- - * LXSubsequentColor8x8PatternFillRect - * - * Description :see LXSetupForColor8x8PatternFill. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * patx int pattern phase x offset - * paty int pattern phase y offset - * x int destination x offset - * y int destination y offset - * w int fill area width (pixels) - * h int fill area height (pixels) - * - * Returns :none - * - * Sample application uses: - * - Patterned desktops - * - x11perf: stippled rectangle tests (-srect500). - * - x11perf: opaque stippled rectangle tests (-osrect500). - *--------------------------------------------------------------------------*/ -static void -LXSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrni, int patx, int paty, - int x, int y, int w, int h) -{ - int flags; - - DBLOG(2, - "LXSubsequentColor8x8PatternFillRect() patxy %d,%d at %d,%d %dsx%d\n", - patx, paty, x, y, w, h); - flags = lx_flags1(x, y, w, h); - gp_declare_blt(flags); - gp_set_pattern_origin(patx, paty); - gp_pattern_fill(CALC_FBOFFSET(x, y), w, h); -} - -/* LX_CLREXP_8X8_PAT_SUPPORT */ -#endif - -#if LX_MONO_8X8_PAT_SUPPORT -/*---------------------------------------------------------------------------- - * LXSetupForMono8x8PatternFill - * - * Description :8x8 mono pattern data is 64 bits of color expansion data - * with ones indicating the foreground color and zeros - * indicating the background color. These patterns are - * useful when tiling, doing opaque stipples, or regular - * stipples. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * patx int x offset to pattern data - * paty int y offset to pattern data - * fg int foreground color - * bg int -1 (transparent) or background color - * rop int unmapped raster operation - * planemask uint -1 (copy) or pattern data - * - * Returns :none. - * - * Comments :none. - * - *--------------------------------------------------------------------------*/ -static void -LXSetupForMono8x8PatternFill(ScrnInfoPtr pScrni, int patx, int paty, - int fg, int bg, int rop, uint planemask) -{ - int trans; - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(2, - "LXSetupForMono8x8PatternFill() pat %#x,%#x fg %#x bg %#x %#x %#x\n", - patx, paty, fg, bg, rop, planemask); - rop &= 0x0F; - gp_declare_blt(0); - if (planemask == ~0U) { /* fill with pattern */ - gp_set_raster_operation(ROP = PDfn[rop]); - } else { /* select rop that uses source data for planemask */ - gp_set_raster_operation(ROP = PDfn_SM[rop]); - gp_set_solid_source((ulong) planemask); - } - trans = bg == -1 ? 1 : 0; - gp_set_mono_pattern(bg, fg, patx, paty, trans, 0, 0); - gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch); - gp_write_parameters(); -} - -/*---------------------------------------------------------------------------- - * LXSubsequentMono8x8PatternFillRect - * - * Description :see LXSetupForMono8x8PatternFill - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * patx int pattern phase x offset - * paty int pattern phase y offset - * x int destination x offset - * y int destination y offset - * w int fill area width (pixels) - * h int fill area height (pixels) - - * Returns :none - * - * Sample application uses: - * - Patterned desktops - * - x11perf: stippled rectangle tests (-srect500). - * - x11perf: opaque stippled rectangle tests (-osrect500). - *--------------------------------------------------------------------------*/ -static void -LXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrni, int patx, int paty, - int x, int y, int w, int h) -{ - int flags; - - DBLOG(2, - "LXSubsequentMono8x8PatternFillRect() pat %#x,%#x at %d,%d %dx%d\n", - patx, paty, x, y, w, h); - flags = lx_flags1(x, y, w, h); - gp_declare_blt(flags); - gp_set_pattern_origin(patx, paty); - gp_pattern_fill(CALC_FBOFFSET(x, y), w, h); -} - -/* LX_MONO_8X8_PAT_SUPPORT */ -#endif - -#if LX_SCR2SCRCPY_SUPPORT -/*---------------------------------------------------------------------------- - * LXSetupForScreenToScreenCopy - * - * Description :SetupFor and Subsequent ScreenToScreenCopy functions - * provide an interface for copying rectangular areas from - * video memory to video memory. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * xdir int x copy direction (up/dn) - * ydir int y copy direction (up/dn) - * rop int unmapped raster operation - * planemask uint -1 (copy) or pattern data - * trans_color int -1 (copy) or transparent color - * - * Returns :none - *---------------------------------------------------------------------------*/ -static void -LXSetupForScreenToScreenCopy(ScrnInfoPtr pScrni, int xdir, int ydir, int rop, - uint planemask, int trans_color) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(2, "LXSetupForScreenToScreenCopy() xd%d yd%d rop %#x %#x %#x\n", - xdir, ydir, rop, planemask, trans_color); - rop &= 0x0F; - gp_declare_blt(0); - if (planemask == ~0U) { - gp_set_raster_operation(ROP = SDfn[rop]); - } else { - gp_set_raster_operation(ROP = SDfn_PM[rop]); - gp_set_solid_pattern((ulong) planemask); - } - gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch); - gp_write_parameters(); - gc2s.transparent = (trans_color == -1) ? 0 : 1; - gc2s.color = trans_color; -} - -/*---------------------------------------------------------------------------- - * LXSubsquentScreenToScreenCopy - * - * Description :see LXSetupForScreenToScreenCopy. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * x1 int source x offset - * y1 int source y offset - * x2 int destination x offset - * y2 int destination y offset - * w int copy area width (pixels) - * h int copy area height (pixels) - * - * Returns :none - * - * Sample application uses (non-transparent): - * - Moving windows. - * - x11perf: scroll tests (-scroll500). - * - x11perf: copy from window to window (-copywinwin500). - *---------------------------------------------------------------------------*/ -static void -LXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrni, - int x1, int y1, int x2, int y2, int w, int h) -{ - int flags; - - DBLOG(2, "LXSubsequentScreenToScreenCopy() from %d,%d to %d,%d %dx%d\n", - x1, y1, x2, y2, w, h); - - flags = lx_flags3(x1, y1, x2, y2, w, h); - gp_declare_blt(flags); - - if (gc2s.transparent) { - gp_set_source_transparency(gc2s.color, ~0); - } - - flags = 0; - - if (x2 > x1) - flags |= 1; - if (y2 > y1) - flags |= 2; - - gp_screen_to_screen_blt(CALC_FBOFFSET(x2, y2), CALC_FBOFFSET(x1, y1), w, - h, flags); -} - -/* LX_SCR2SCRCPY_SUPPORT */ -#endif - -#if LX_SCANLINE_SUPPORT -/*---------------------------------------------------------------------------- - * LXSetupForScanlineImageWrite - * - * Description :SetupFor/Subsequent ScanlineImageWrite and ImageWriteScanline - * transfer full color pixel data from system memory to video - * memory. This is useful for dealing with alignment issues and - * performing raster ops on the data. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * rop int unmapped raster operation - * planemask uint -1 (copy) or pattern data - * bpp int bits per pixel (unused) - * depth int color depth (unused) - * - * Returns :none - * - * x11perf -putimage10 - * x11perf -putimage100 - * x11perf -putimage500 -*---------------------------------------------------------------------------- -*/ -static void -LXSetupForScanlineImageWrite(ScrnInfoPtr pScrni, int rop, uint planemask, - int trans_color, int bpp, int depth) -{ - int Bpp = (bpp + 7) >> 3; - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(2, "LXSetupForScanlineImageWrite() rop %#x %#x %#x %d %d\n", - rop, planemask, trans_color, bpp, depth); - rop &= 0x0F; - gp_set_source_format(lx_src_fmt[Bpp - 1]); - gp_declare_blt(0); - if (planemask == ~0U) { - gp_set_raster_operation(ROP = SDfn[rop]); - } else { - gp_set_raster_operation(ROP = SDfn_PM[rop]); - gp_set_solid_pattern(planemask); - } - gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch); - gp_write_parameters(); - giwr.transparent = (trans_color == -1) ? 0 : 1; - giwr.color = trans_color; -} - -/*---------------------------------------------------------------------------- - * LXSubsequentScanlineImageWriteRect - * - * Description : see LXSetupForScanlineImageWrite. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * x int destination x offset - * y int destination y offset - * w int copy area width (pixels) - * h int copy area height (pixels) - * skipleft int x margin (pixels) to skip (not enabled) - * - * Returns :none - *---------------------------------------------------------------------------*/ -static void -LXSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrni, - int x, int y, int w, int h, int skipleft) -{ - DBLOG(2, "LXSubsequentScanlineImageWriteRect() rop %d,%d %dx%d %d\n", x, - y, w, h, skipleft); - giwr.x = x; - giwr.y = y; - giwr.w = w; - giwr.h = h; - /* since the image buffer must be not busy (it may be busy from - * a previous ScanlineWriteImage), we must add a Sync here */ -#if !LX_USE_OFFSCRN_MEM - LXAccelSync(pScrni); -#endif -} - -/*---------------------------------------------------------------------------- - * LXSubsquentImageWriteScanline - * - * Description : see LXSetupForScanlineImageWrite. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * bufno int scanline number in write group - * - * Returns :none - * - * Sample application uses (non-transparent): - * - Moving windows. - * - x11perf: scroll tests (-scroll500). - * - x11perf: copy from window to window (-copywinwin500). - * - *---------------------------------------------------------------------------*/ -static void -LXSubsequentImageWriteScanline(ScrnInfoPtr pScrni, int bufno) -{ - GeodeRec *pGeode; - int blt_height = 0; - - DBLOG(3, "LXSubsequentImageWriteScanline() %d\n", bufno); - pGeode = GEODEPTR(pScrni); - - if ((blt_height = pGeode->NoOfImgBuffers) > giwr.h) - blt_height = giwr.h; - if (++bufno < blt_height) - return; - - gp_declare_blt(ENABLE_PREFETCH); - if (giwr.transparent) { - gp_set_source_transparency(giwr.color, ~0); - } -#if !LX_USE_OFFSCRN_MEM - gp_screen_to_screen_blt(CALC_FBOFFSET(giwr.x, giwr.y), ImgBufOffset, - giwr.w, blt_height, 0); - LXAccelSync(pScrni); -#else - gp_color_bitmap_to_screen_blt(CALC_FBOFFSET(giwr.x, giwr.y), 0, - giwr.w, blt_height, ImgLnsBuffers, pGeode->AccelPitch); -#endif - giwr.h -= blt_height; - giwr.y += blt_height; -} - -/* LX_SCANLINE_SUPPORT */ -#endif - -#if LX_CPU2SCREXP_SUPPORT -/*---------------------------------------------------------------------------- - * LXSetupForScanlineCPUToScreenColorExpandFill - * - * Description :SetupFor/Subsequent CPUToScreenColorExpandFill and - * ColorExpandScanline routines provide an interface for - * doing expansion blits from source patterns stored in - * system memory. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * fg int foreground color - * bg int -1 (transparent) or background color - * rop int unmapped raster operation - * planemask uint -1 (copy) or pattern data - * - * Returns :none. - *---------------------------------------------------------------------------*/ - -static void -LXSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrni, - int fg, int bg, int rop, uint planemask) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(2, - "LXSetupForScanlineCPUToScreenColorExpandFill() " - "fg %#x bg %#x rop %#x %#x\n", fg, bg, rop, planemask); - rop &= 0x0F; - gp_declare_blt(0); - if (planemask == ~0U) { - gp_set_raster_operation(ROP = SDfn[rop]); - } else { - gp_set_raster_operation(ROP = SDfn_PM[rop]); - gp_set_solid_pattern(planemask); - } - gp_set_mono_source(bg, fg, (bg == -1)); - gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch); - gp_write_parameters(); - gc2s.bpp = 1; - gc2s.transparent = 0; - gc2s.color = 0; -} - -/*---------------------------------------------------------------------------- - * LXSubsequentScanlineCPUToScreenColorExpandFill - * - * Description :see LXSetupForScanlineCPUToScreenColorExpandFill - * - * Parameters: - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * x int destination x offset - * y int destination y offset - * w int fill area width (pixels) - * h int fill area height (pixels) - * - * Returns :none - * - *---------------------------------------------------------------------------*/ -static void -LXSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrni, - int x, int y, int w, int h, int skipleft) -{ - DBLOG(2, - "LXSubsequentScanlineCPUToScreenColorExpandFill() %d,%d %dx%d %d\n", - x, y, w, h, skipleft); - gc2s.x = x; - gc2s.y = y; - gc2s.w = w; - gc2s.h = h; -} - -/*---------------------------------------------------------------------------- - * LXSubsequentColorExpandScanline - * - * Description :see LXSetupForScanlineCPUToScreenColorExpandFill - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * bufno int scanline number in write group - * - * Returns :none -*---------------------------------------------------------------------------- -*/ -static void -LXSubsequentColorExpandScanline(ScrnInfoPtr pScrni, int bufno) -{ - GeodeRec *pGeode; - ulong srcpitch; - int blt_height = 0; - - DBLOG(3, "LXSubsequentColorExpandScanline() %d\n", bufno); - pGeode = GEODEPTR(pScrni); - - if ((blt_height = pGeode->NoOfImgBuffers) > gc2s.h) - blt_height = gc2s.h; - if (++bufno < blt_height) - return; - - gp_declare_blt(ENABLE_PREFETCH); - /* convert from bits to dwords */ - srcpitch = ((pGeode->AccelPitch + 31) >> 5) << 2; - gp_mono_bitmap_to_screen_blt(CALC_FBOFFSET(gc2s.x, gc2s.y), 0, gc2s.w, - blt_height, ClrLnsBuffers, srcpitch); - gc2s.h -= blt_height; - gc2s.y += blt_height; -} - -/* LX_CPU2SCREXP_SUPPORT */ -#endif - -#if LX_SCR2SCREXP_SUPPORT - -/*---------------------------------------------------------------------------- - * LXSetupForScreenToScreenColorExpandFill - * - * Description :SetupFor/Subsequent ScreenToScreenColorExpandFill and - * ColorExpandScanline routines provide an interface for - * doing expansion blits from source patterns stored in - * video memory. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * fg int foreground color - * bg int -1 (transparent) or background color - * rop int unmapped raster operation - * planemask uint -1 (copy) or pattern data - * - * Returns :none. - *---------------------------------------------------------------------------*/ - -static void -LXSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrni, int fg, int bg, - int rop, uint planemask) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(2, - "LXSetupForScreenToScreenColorExpandFill() " - "fg %#x bg %#x rop %#x %#x\n", fg, bg, rop, planemask); - rop &= 0x0F; - gp_declare_blt(0); - if (planemask == ~0U) { - gp_set_raster_operation(ROP = SDfn[rop]); - } else { - gp_set_raster_operation(ROP = SDfn_PM[rop]); - gp_set_solid_pattern(planemask); - } - gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch); - gp_set_mono_source(bg, fg, (bg == -1)); - gp_write_parameters(); -} - -/*---------------------------------------------------------------------------- - * LXSubsequentScreenToScreenColorExpandFill - * - * Description :see LXSetupForScreenToScreenColorExpandFill - * - * Parameters: - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * x int destination x offset - * y int destination y offset - * w int fill area width (pixels) - * h int fill area height (pixels) - * offset int initial x offset - * - * Returns :none - * - *---------------------------------------------------------------------------*/ -static void -LXSubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrni, - int x, int y, int w, int h, int srcx, int srcy, int offset) -{ - int flags; - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(2, - "LXSubsequentScreenToScreenColorExpandFill() %d,%d %dx%d %d,%d %d\n", - x, y, w, h, srcx, srcy, offset); - flags = lx_flags3(srcx, srcy, x, y, w, h); - gp_declare_blt(flags); - gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch); - gp_mono_expand_blt(CALC_FBOFFSET(x, y), CALC_FBOFFSET(srcx, srcy), offset, - w, h, 0); -} - -/* LX_SCR2SCREXP_SUPPORT */ -#endif - -#define VM_X_MAJOR 0 -#define VM_Y_MAJOR 1 -#define VM_MAJOR_INC 2 -#define VM_MAJOR_DEC 0 -#define VM_MINOR_INC 4 -#define VM_MINOR_DEC 0 - -static ushort vmode[] = { - VM_X_MAJOR | VM_MAJOR_INC | VM_MINOR_INC, /* !XDECR !YDECR !YMAJOR */ - VM_Y_MAJOR | VM_MAJOR_INC | VM_MINOR_INC, /* !XDECR !YDECR YMAJOR */ - VM_X_MAJOR | VM_MAJOR_INC | VM_MINOR_DEC, /* !XDECR YDECR !YMAJOR */ - VM_Y_MAJOR | VM_MAJOR_DEC | VM_MINOR_INC, /* !XDECR YDECR YMAJOR */ - VM_X_MAJOR | VM_MAJOR_DEC | VM_MINOR_INC, /* XDECR !YDECR !YMAJOR */ - VM_Y_MAJOR | VM_MAJOR_INC | VM_MINOR_DEC, /* XDECR !YDECR YMAJOR */ - VM_X_MAJOR | VM_MAJOR_DEC | VM_MINOR_DEC, /* XDECR YDECR !YMAJOR */ - VM_Y_MAJOR | VM_MAJOR_DEC | VM_MINOR_DEC, /* XDECR YDECR YMAJOR */ -}; - -#define ABS(_val1, _val2) (((_val1) > (_val2)) ? \ - ((_val1)-(_val2)) : ((_val2) - (_val1))) - -#if LX_BRES_LINE_SUPPORT -/*---------------------------------------------------------------------------- - * LXSetupForSolidLine - * - * Description :SetupForSolidLine and Subsequent HorVertLine TwoPointLine - * BresenhamLine provides an interface for drawing thin - * solid lines. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * color int foreground fill color - * rop int unmapped raster op - * planemask uint -1 (fill) or pattern data (not enabled) - * - * Returns :none -*---------------------------------------------------------------------------*/ -static void -LXSetupForSolidLine(ScrnInfoPtr pScrni, int color, int rop, uint planemask) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(2, "LXSetupForSolidLine() %#x %#x %#x\n", color, rop, planemask); - rop &= 0x0F; - gp_declare_vector(CIMGP_BLTFLAGS_HAZARD); - if (planemask == ~0U) { - gp_set_raster_operation(ROP = PDfn[rop]); - } else { - gp_set_raster_operation(ROP = PDfn_SM[rop]); - gp_set_solid_source(planemask); - } - gp_set_solid_pattern((ulong) color); - gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch); - gp_write_parameters(); -} - -/*--------------------------------------------------------------------------- - * LXSubsequentSolidBresenhamLine - * - * Description :see LXSetupForSolidLine - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * x1 int destination x offset - * y1 int destination y offset - * absmaj int Bresenman absolute major - * absmin int Bresenman absolute minor - * err int Bresenman initial error term - * len int length of the vector (pixels) - * octant int specifies sign and magnitude relationships - * used to determine axis of magor rendering - * and direction of vector progress. - * - * Returns :none - * - * - Window outlines on window move. - * - x11perf: line segments (-line500). - * - x11perf: line segments (-seg500). - *---------------------------------------------------------------------------*/ -static void -LXSubsequentSolidBresenhamLine(ScrnInfoPtr pScrni, int x1, int y1, - int absmaj, int absmin, int err, int len, int octant) -{ - int x2, y2, flags; - long axial, diagn; - - DBLOG(2, "LXSubsequentSolidBresenhamLine() %d,%d %d %d, %d %d, %d\n", - x1, y1, absmaj, absmin, err, len, octant); - if (len <= 0) - return; - lx_endpt(x1, y1, len, absmaj, absmin, err, octant, &x2, &y2); - flags = lx_flags2(x1, y1, x2 + 1, y2 + 1); - gp_declare_vector(flags); - axial = absmin; - err += axial; - diagn = absmin - absmaj; - gp_bresenham_line(CALC_FBOFFSET(x1, y1), len, err, axial, diagn, - vmode[octant]); -} - -/*--------------------------------------------------------------------------- - * LXSubsequentSolidTwoPointLine - * - * Description :see LXSetupForSolidLine - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * x0 int destination x start offset - * y0 int destination y start offset - * x1 int destination x end offset - * y1 int destination y end offset - * flags int OMIT_LAST, dont draw last pixel (not used) - * - * Returns :none - *---------------------------------------------------------------------------*/ -static void -LXSubsequentSolidTwoPointLine(ScrnInfoPtr pScrni, int x0, int y0, - int x1, int y1, int flags) -{ - long dx, dy, dmaj, dmin, octant, bias; - long axial, diagn, err, len; - - DBLOG(2, "LXSubsequentSolidTwoPointLine() %d,%d %d,%d, %#x\n", - x0, y0, x1, y1, flags); - - if ((dx = x1 - x0) < 0) - dx = -dx; - if ((dy = y1 - y0) < 0) - dy = -dy; - - if (dy >= dx) { - dmaj = dy; - dmin = dx; - octant = YMAJOR; - } else { - dmaj = dx; - dmin = dy; - octant = 0; - } - len = dmaj; - if ((flags & OMIT_LAST) == 0) - ++len; - if (len <= 0) - return; - if (x1 < x0) - octant |= XDECREASING; - if (y1 < y0) - octant |= YDECREASING; - - flags = lx_flags2(x0, y0, x1 + 1, y1 + 1); - gp_declare_vector(flags); - axial = dmin << 1; - bias = miGetZeroLineBias(pScrni->pScreen); - err = axial - dmaj - ((bias >> octant) & 1); - diagn = (dmin - dmaj) << 1; - gp_bresenham_line(CALC_FBOFFSET(x0, y0), len, err, axial, diagn, - vmode[octant]); -} - -/*--------------------------------------------------------------------------- - * LXSubsequentSolidHorVertLine - * - * Description :see LXSetupForSolidLine - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * x int destination x offset - * y int destination y offset - * len int length of the vector (pixels) - * dir int DEGREES_270 or DEGREES_0 line direction - * - * Sample application uses: - * - Window outlines on window move. - * - x11perf: line segments (-hseg500). - * - x11perf: line segments (-vseg500). - *--------------------------------------------------------------------------- - */ -static void -LXSubsequentSolidHorVertLine(ScrnInfoPtr pScrni, - int x, int y, int len, int dir) -{ - int flags, w, h; - - DBLOG(2, "LXSubsequentHorVertLine() %d,%d %d %d\n", x, y, len, dir); - gp_declare_blt(0); - if (dir == DEGREES_0) { - w = len; - h = 1; - } else { - w = 1; - h = len; - } - flags = lx_flags1(x, y, w, h); - gp_declare_blt(flags); - gp_pattern_fill(CALC_FBOFFSET(x, y), ((dir == DEGREES_0) ? len : 1), - ((dir == DEGREES_0) ? 1 : len)); -} - -/* LX_BRES_LINE_SUPPORT */ -#endif - -#if LX_DASH_LINE_SUPPORT -/*---------------------------------------------------------------------------- - * LXSetupForDashedLine - * - * Description :SetupForDashedLine and Subsequent TwoPointLine - * BresenhamLine provides an interface for drawing thin - * dashed lines. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * fg int foreground fill color - * bg int -1 (transp) or background fill color - * rop int unmapped raster op - * planemask uint -1 (fill) or pattern data (not enabled) - * length int pattern length (bits) - * pattern uchar* dash pattern mask - * - * Returns :none -*---------------------------------------------------------------------------*/ -static void -LXSetupForDashedLine(ScrnInfoPtr pScrni, - int fg, int bg, int rop, uint planemask, int length, uchar * pattern) -{ - int n; - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(2, - "LXSetupForDashedLine() " - "fg %#x bg %#x rop %#x pm %#x len %d, pat %#x\n", - fg, bg, rop, planemask, length, *(ulong *) pattern); - gdln.fg = fg; - gdln.bg = bg; - gdln.len = length; - n = (length + 7) / 8; - if (n > sizeof(gdln.pat)) - n = sizeof(gdln.pat); - memcpy(&gdln.pat, pattern, n); - rop &= 0x0F; - gp_declare_vector(CIMGP_BLTFLAGS_HAZARD); - if (planemask == ~0U) { - gp_set_raster_operation(ROP = PDfn[rop]); - } else { - gp_set_raster_operation(ROP = PDfn_SM[rop]); - gp_set_solid_source(planemask); - } - gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch); - gp_write_parameters(); -} - -/*--------------------------------------------------------------------------- - * LXSubsequentDashedBresenhamLine - * - * Description :see LXSetupForDashedLine - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * x1 int destination x offset - * y1 int destination y offset - * absmaj int Bresenman absolute major - * absmin int Bresenman absolute minor - * err int Bresenman initial error term - * len int length of the vector (pixels) - * octant int specifies sign and magnitude relationships - * used to determine axis of magor rendering - * and direction of vector progress. - * phase int initial pattern offset at x1,y1 - * - * Returns :none - *---------------------------------------------------------------------------*/ -static void -LXSubsequentDashedBresenhamLine(ScrnInfoPtr pScrni, int x1, int y1, - int absmaj, int absmin, int err, int len, int octant, int phase) -{ - int x2, y2, flags; - long axial, diagn; - ulong pattern; - - DBLOG(2, "LXSubsequentDashedBresenhamLine() %d,%d %d %d, %d %d, %d %d\n", - x1, y1, absmaj, absmin, err, len, octant, phase); - if (len <= 0) - return; - pattern = gdln.pat; - if (phase > 0) { - int n = gdln.len - phase; - - pattern = ((pattern >> phase) & ((1UL << n) - 1)) | (pattern << n); - } - gp_set_vector_pattern(pattern, gdln.fg, gdln.len); - lx_endpt(x1, y1, len, absmaj, absmin, err, octant, &x2, &y2); - flags = lx_flags2(x1, y1, x2 + 1, y2 + 1); - gp_declare_vector(flags); - axial = absmin; - err += axial; - diagn = absmin - absmaj; - gp_bresenham_line(CALC_FBOFFSET(x1, y1), len, err, axial, diagn, - vmode[octant]); -} - -/*--------------------------------------------------------------------------- - * LXSubsequentDashedTwoPointLine - * - * Description :see LXSetupForDashedLine - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * x0 int destination x start offset - * y0 int destination y start offset - * x1 int destination x end offset - * y1 int destination y end offset - * flags int OMIT_LAST, dont draw last pixel (not used) - * phase int initial pattern offset at x1,y1 - * - * Returns :none - *---------------------------------------------------------------------------*/ -static void -LXSubsequentDashedTwoPointLine(ScrnInfoPtr pScrni, int x0, int y0, - int x1, int y1, int flags, int phase) -{ - ulong pattern; - long dx, dy, dmaj, dmin, octant, bias; - long axial, diagn, err, len; - - DBLOG(2, "LXSubsequentDashedTwoPointLine() %d,%d %d,%d, %#x %d\n", - x0, y0, x1, y1, flags, phase); - - if ((dx = x1 - x0) < 0) - dx = -dx; - if ((dy = y1 - y0) < 0) - dy = -dy; - if (dy >= dx) { - dmaj = dy; - dmin = dx; - octant = YMAJOR; - } else { - dmaj = dx; - dmin = dy; - octant = 0; - } - len = dmaj; - if ((flags & OMIT_LAST) == 0) - ++len; - if (len <= 0) - return; - if (x1 < x0) - octant |= XDECREASING; - if (y1 < y0) - octant |= YDECREASING; - - pattern = gdln.pat; - if (phase > 0) { - int n = gdln.len - phase; - - pattern = ((pattern >> phase) & ((1UL << n) - 1)) | (pattern << n); - } - gp_set_vector_pattern(pattern, gdln.fg, gdln.len); - flags = lx_flags2(x0, y0, x1 + 1, y1 + 1); - gp_declare_vector(flags); - - axial = dmin << 1; - bias = miGetZeroLineBias(pScrni->pScreen); - err = axial - dmaj - ((bias >> octant) & 1); - diagn = (dmin - dmaj) << 1; - gp_bresenham_line(CALC_FBOFFSET(x0, y0), len, err, axial, diagn, - vmode[octant]); -} - -/* LX_DASH_LINE_SUPPORT */ -#endif - -#if LX_WRITE_PIXMAP_SUPPORT -void -LXWritePixmap(ScrnInfoPtr pScrni, int x, int y, int w, int h, - unsigned char *src, int srcwidth, int rop, - unsigned int planemask, int trans, int bpp, int depth) -{ - int flags, dx, dy; - int Bpp = (bpp + 7) >> 3; - unsigned long offset; - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(2, "LXWritePixmap() %d,%d %dx%d, s%#x sp%d %#x %#x %#x %d %d\n", - x, y, w, h, src, srcwidth, rop, planemask, trans, bpp, depth); - - rop &= 0x0F; - gp_set_source_format(lx_src_fmt[Bpp - 1]); - /* must assign before lx_flags */ - ROP = planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]; - - if (src >= pGeode->FBBase && src < pGeode->FBBase + pGeode->FBSize) { - offset = src - pGeode->FBBase; - dx = (offset & ((1 << gu3_yshift) - 1)) >> Bpp; - dy = offset >> gu3_yshift; - flags = lx_flags3(x, y, dx, dy, w, h); - } else - flags = ENABLE_PREFETCH; - - gp_declare_blt(flags); - gp_set_raster_operation(ROP); - if (planemask != ~0U) - gp_set_solid_pattern(planemask); - gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch); - if (trans != -1) { - gp_set_source_transparency(trans, ~0); - } - - gp_color_bitmap_to_screen_blt(CALC_FBOFFSET(x, y), 0, w, h, src, - srcwidth); - SET_SYNC_FLAG(pGeode->AccelInfoRec); -} -#endif - -/*---------------------------------------------------------------------------- - * LXAccelInit. - * - * Description :Create and initialize XAAInfoRec structure. - * The XAAInfoRec structure contains many fields, most of - * which are primitive function pointers and flags. Each - * primitive will have two or more functions and a set of - * associated associated flags. These functions can be - * classified into two principle classes, the "SetupFor" - * and "Subsequent" functions. The "SetupFor" function tells - * the driver that the hardware should be initialized for - * a particular type of graphics operation. After the - * "SetupFor" function, one or more calls to the "Subsequent" - * function will be made to indicate that an instance of the - * particular primitive should be rendered by the hardware. - * - * Arg Type Comment - * pScrn ScreenPtr pointer to active Screen data - * - * Returns :TRUE on success and FALSE on Failure - * - * Comments :This function is called in LXScreenInit in - * amd_lx_driver.c to initialize acceleration. - *---------------------------------------------------------------------------*/ -Bool -LXAccelInit(ScreenPtr pScrn) -{ - GeodeRec *pGeode; - ScrnInfoPtr pScrni; - -#if DEBUGLVL>0 - if (zdfp == NULL) { - zdfp = fopen("/tmp/xwin.log", "w"); - setbuf(zdfp, NULL); - } -#endif - DBLOG(2, "LXAccelInit()\n"); - - pScrni = xf86Screens[pScrn->myNum]; - pGeode = GEODEPTR(pScrni); - - switch (pScrni->bitsPerPixel) { - case 8: - gu3_img_fmt = CIMGP_SOURCE_FMT_3_3_2; - break; - case 16: - gu3_img_fmt = CIMGP_SOURCE_FMT_0_5_6_5; - break; - case 32: - gu3_img_fmt = CIMGP_SOURCE_FMT_8_8_8_8; - break; - } - - gu3_xshift = pScrni->bitsPerPixel >> 4; - - switch (pGeode->AccelPitch) { - case 1024: - gu3_yshift = 10; - break; - case 2048: - gu3_yshift = 11; - break; - case 4096: - gu3_yshift = 12; - break; - case 8192: - gu3_yshift = 13; - break; - } - - /* Getting the pointer for acceleration Inforecord */ - pGeode->AccelInfoRec = localRecPtr = XAACreateInfoRec(); - - /* SET ACCELERATION FLAGS */ - localRecPtr->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS | - LINEAR_FRAMEBUFFER; - - /* HOOK SYNCRONIZARION ROUTINE */ - localRecPtr->Sync = LXAccelSync; - -#if LX_FILL_RECT_SUPPORT - /* HOOK FILLED RECTANGLES */ - HOOK(SetupForSolidFill); - HOOK(SubsequentSolidFillRect); - localRecPtr->SolidFillFlags = 0; -#endif - -#if LX_MONO_8X8_PAT_SUPPORT - /* HOOK 8x8 Mono EXPAND PATTERNS */ - HOOK(SetupForMono8x8PatternFill); - HOOK(SubsequentMono8x8PatternFillRect); - localRecPtr->Mono8x8PatternFillFlags = - BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | - HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_PROGRAMMED_ORIGIN; -#endif - -#if LX_CLREXP_8X8_PAT_SUPPORT - /* Color expansion */ - HOOK(SetupForColor8x8PatternFill); - HOOK(SubsequentColor8x8PatternFillRect); - localRecPtr->Color8x8PatternFillFlags = - BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | - NO_TRANSPARENCY | HARDWARE_PATTERN_PROGRAMMED_ORIGIN; -#endif - -#if LX_SCR2SCRCPY_SUPPORT - /* HOOK SCREEN TO SCREEN COPIES - * Set flag to only allow copy if transparency is enabled. - */ - HOOK(SetupForScreenToScreenCopy); - HOOK(SubsequentScreenToScreenCopy); - localRecPtr->ScreenToScreenCopyFlags = - BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD; -#endif - -#if LX_BRES_LINE_SUPPORT - /* HOOK BRESENHAM SOLID LINES */ - localRecPtr->SolidLineFlags = NO_PLANEMASK; - HOOK(SetupForSolidLine); - HOOK(SubsequentSolidBresenhamLine); - HOOK(SubsequentSolidHorVertLine); - HOOK(SubsequentSolidTwoPointLine); - localRecPtr->SolidBresenhamLineErrorTermBits = 15; -#endif - -#if LX_DASH_LINE_SUPPORT - /* HOOK BRESENHAM DASHED LINES */ - localRecPtr->DashedLineFlags = NO_PLANEMASK | TRANSPARENCY_ONLY | - LINE_PATTERN_LSBFIRST_LSBJUSTIFIED | SCANLINE_PAD_DWORD; - HOOK(SetupForDashedLine); - HOOK(SubsequentDashedBresenhamLine); - HOOK(SubsequentDashedTwoPointLine); - localRecPtr->DashedBresenhamLineErrorTermBits = 15; - localRecPtr->DashPatternMaxLength = 32; -#endif - -#if LX_SCR2SCREXP_SUPPORT - /* Color expansion */ - HOOK(SetupForScreenToScreenColorExpandFill); - HOOK(SubsequentScreenToScreenColorExpandFill); - localRecPtr->ScreenToScreenColorExpandFillFlags = - BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD; -#endif - - if (pGeode->AccelImageWriteBuffers) { -#if LX_SCANLINE_SUPPORT - localRecPtr->ScanlineImageWriteBuffers = - pGeode->AccelImageWriteBuffers; - localRecPtr->NumScanlineImageWriteBuffers = pGeode->NoOfImgBuffers; - HOOK(SetupForScanlineImageWrite); - HOOK(SubsequentScanlineImageWriteRect); - HOOK(SubsequentImageWriteScanline); - localRecPtr->ScanlineImageWriteFlags = - BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD; -#endif -#if !LX_USE_OFFSCRN_MEM - ImgBufOffset = pGeode->AccelImageWriteBuffers[0] - pGeode->FBBase; -#else - ImgLnsBuffers = (uchar *) pGeode->AccelImageWriteBuffers[0]; -#endif - } else { - localRecPtr->PixmapCacheFlags = DO_NOT_BLIT_STIPPLES; - } - - if (pGeode->AccelColorExpandBuffers) { -#if LX_CPU2SCREXP_SUPPORT - /* Color expansion */ - localRecPtr->ScanlineColorExpandBuffers = - pGeode->AccelColorExpandBuffers; - localRecPtr->NumScanlineColorExpandBuffers = - pGeode->NoOfColorExpandLines; - HOOK(SetupForScanlineCPUToScreenColorExpandFill); - HOOK(SubsequentScanlineCPUToScreenColorExpandFill); - HOOK(SubsequentColorExpandScanline); - localRecPtr->ScanlineCPUToScreenColorExpandFillFlags = - BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD; -#endif - ClrLnsBuffers = (uchar *) pGeode->AccelColorExpandBuffers[0]; - } -#if LX_WRITE_PIXMAP_SUPPORT - HOOK(WritePixmap); -#endif - - return (XAAInit(pScrn, localRecPtr)); -} - -/* END OF FILE */ diff --git a/src/amd_lx_cursor.c b/src/amd_lx_cursor.c index 5417d4b..61f3d5d 100644 --- a/src/amd_lx_cursor.c +++ b/src/amd_lx_cursor.c @@ -1,12 +1,11 @@ -/* - * Copyright (c) 2006 Advanced Micro Devices, Inc. +/* Copyright (c) 2003-2007 Advanced Micro Devices, Inc. * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. @@ -16,21 +15,20 @@ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. * * Neither the name of the Advanced Micro Devices, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. - */ + * */ /* - * File Contents: Xfree cursor implementation routines - * for geode HWcursor init.setting cursor color,image etc - * are done here. - * Project: Geode Xfree Frame buffer device driver. - * - */ + * File Contents: Xfree cursor implementation routines for geode HWcursor + * init.setting cursor color,image etc. are done here. + * + * Project: Geode Xfree Frame buffer device driver. + * */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -53,13 +51,13 @@ void LXShowCursor(ScrnInfoPtr pScrni); static Bool LXUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs); extern void LXSetVideoPosition(int x, int y, int width, int height, short src_w, short src_h, short drw_w, - short drw_h, int id, int offset, ScrnInfoPtr pScrni); + short drw_h, int id, int offset, ScrnInfoPtr pScrn); /*---------------------------------------------------------------------------- - * LXHWCursorInit. +* LXHWCursorInit. * * Description :This function sets the cursor information by probing the - * hardware. + * hardware. * * Parameters. * pScrn :Screeen pointer structure. @@ -67,9 +65,9 @@ extern void LXSetVideoPosition(int x, int y, int width, int height, * Returns :TRUE on success and FALSE on Failure * * Comments :Geode supports the hardware_cursor,no need to enable SW - * cursor. -*---------------------------------------------------------------------------- -*/ + * cursor. + *---------------------------------------------------------------------------- + */ Bool LXHWCursorInit(ScreenPtr pScrn) { @@ -80,7 +78,7 @@ LXHWCursorInit(ScreenPtr pScrn) infoPtr = xf86CreateCursorInfoRec(); if (!infoPtr) return FALSE; - /* the geode structure is initialized with the cursor infoRec */ + /* the geode structure is intiallized with the cursor infoRec */ pGeode->CursorInfo = infoPtr; infoPtr->MaxWidth = 32; infoPtr->MaxHeight = 32; @@ -88,8 +86,8 @@ LXHWCursorInit(ScreenPtr pScrn) infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED; - /* cursor info ptr is initialized with the values obtained from - * cimarron calls + /* cursor info ptr is intiallized with the values obtained from + * * durnago calls */ infoPtr->SetCursorColors = LXSetCursorColors; infoPtr->SetCursorPosition = LXSetCursorPosition; @@ -97,7 +95,6 @@ LXHWCursorInit(ScreenPtr pScrn) infoPtr->HideCursor = LXHideCursor; infoPtr->ShowCursor = LXShowCursor; infoPtr->UseHWCursor = LXUseHWCursor; - return (xf86InitCursor(pScrn, infoPtr)); } @@ -105,21 +102,22 @@ LXHWCursorInit(ScreenPtr pScrn) * LXSetCursorColors. * * Description :This function sets the cursor foreground and background - * colors + * colors * Parameters: - * pScrni: Screeen information pointer structure. - * bg: Specifies the color value of cursor background color. - * fg: Specifies the color value of cursor foreground color. - * Returns: none. + * pScrn: Screeen pointer structure. + * bg: Specifies the color value of cursor background color. + * fg: Specifies the color value of cursor foreground color. + * + * Returns: none. * - * Comments: The integer color value passed by this function is + * Comments: The integer color value passed by this function is * converted into * RGB value by the gfx_set_color routines. *---------------------------------------------------------------------------- */ static void LXSetCursorColors(ScrnInfoPtr pScrni, int bg, int fg) { - vg_set_mono_cursor_colors(bg, fg); + vg_set_mono_cursor_colors(bg, fg); } /*---------------------------------------------------------------------------- @@ -129,10 +127,11 @@ LXSetCursorColors(ScrnInfoPtr pScrni, int bg, int fg) * cursor. * * Parameters: - * pScrni: Screeen information pointer structure. - * x: Specifies the x-cordinates of the cursor. - * y: Specifies the y co-ordinate of the cursor. - * Returns: none. + * pScrn: Screeen pointer structure. + * x: Specifies the x-cordinates of the cursor. + * y: Specifies the y co-ordinate of the cursor. + * + * Returns: none. * *---------------------------------------------------------------------------- */ @@ -141,50 +140,67 @@ LXSetCursorPosition(ScrnInfoPtr pScrni, int x, int y) { static unsigned long panOffset = 0; GeodeRec *pGeode = GEODEPTR(pScrni); - VG_PANNING_COORDINATES panning; + int savex, savey; int newX, newY; + int hsx, hsy; + + /* Adjust xf86HWCursor messing about */ - (*pGeode->Rotation) (x, y, pGeode->HDisplay, pGeode->VDisplay, &newX, - &newY); - (*pGeode->RBltXlat) (newX, newY, 32, 32, &newX, &newY); + savex = x + pScrni->frameX0; + savey = y + pScrni->frameY0; + + switch(pGeode->rotation) { + case RR_Rotate_0: + newX = savex; newY = savey; + hsx= 31; hsy = 31; + break; + + case RR_Rotate_90: + newX = savey; + newY = pScrni->pScreen->width - savex; + hsx= 31; hsy = 0; + break; + + case RR_Rotate_180: + newX = pScrni->pScreen->width - savex; + newY = pScrni->pScreen->height - savey; + hsx = 0; hsy = 0; + break; + + case RR_Rotate_270: + newX = pScrni->pScreen->height - savey; + newY = savex; + hsx= 0; hsy= 31; + break; + } - if (newX < -31) - newX = -31; - if (newY < -31) - newY = -31; + newX -= pScrni->frameX0; + newY -= pScrni->frameY0; - vg_set_cursor_position(newX + 31, newY + 31, &panning); + { + VG_PANNING_COORDINATES panning; + vg_set_cursor_position(newX + hsx, newY + hsy, &panning); + } + vg_set_cursor_enable(1); -#ifndef AMD_V4L2_VIDEO - if ((pGeode->OverlayON) && (pGeode->EnabledOutput & LX_OT_FP)) { - pGeode->PrevDisplayOffset = vg_get_display_offset(); - if (pGeode->PrevDisplayOffset != panOffset) { - LXSetVideoPosition(pGeode->video_x, pGeode->video_y, - pGeode->video_w, pGeode->video_h, - pGeode->video_srcw, pGeode->video_srch, - pGeode->video_dstw, pGeode->video_dsth, - pGeode->video_id, pGeode->video_offset, - pGeode->video_scrnptr); - panOffset = pGeode->PrevDisplayOffset; - } - } -#endif + /* FIXME: Adjust for video panning? */ } /*---------------------------------------------------------------------------- * LXLoadCursorImage * - * Description :This function loads the 32x32 cursor pattern.The shape - * and color is set by AND and XOR masking of arrays of 32 - * DWORD. + * Description: This function loads the 32x32 cursor pattern.The shape + * and color is set by AND and XOR masking of arrays of 32 + * DWORD. * Parameters: - * pScrni: Screeen information pointer structure. - * src : Specifies cursor data. - * Returns : none + * pScrn: Screeen pointer structure. + * src: Specifies cursor data. + * + * Returns: none * *---------------------------------------------------------------------------- -*/ + */ void LXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src) { @@ -207,7 +223,26 @@ LXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src) ++rowp; ++mskp; } - (*pGeode->Rotation) (x, y, 32, 32, &newX, &newY); + + switch(pGeode->rotation) { + case RR_Rotate_0: + newX = x; + newY = y; + break; + case RR_Rotate_90: + newX = y; + newY = 31 - x; + break; + case RR_Rotate_180: + newX = 31 - x; + newY = 31 - y; + break; + case RR_Rotate_270: + newX = 31 - y; + newY = x; + break; + } + i = 7 - i; n = 31 - newX; andMask[newY] |= (((mskb >> i) & 1) << n); @@ -221,22 +256,21 @@ LXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src) } } - vg_set_mono_cursor_shape32(pGeode->CursorStartOffset, &andMask[0], - &xorMask[0], 31, 31); + vg_set_mono_cursor_shape32(pGeode->CursorStartOffset,&andMask[0],&xorMask[0],31,31); } /*---------------------------------------------------------------------------- - * LXHideCursor + * LXHideCursor. * - * Description :This function will disable the cursor. + * Description: This function will disable the cursor. * * Parameters: - * pScrni: Handles to the Screeen information pointer structure. + * pScrn: Handles to the Screeen pointer structure. * - * Returns: none. + * Returns: none. * - * Comments: gfx_set_cursor enable function is hardcoded to disable - * the cursor. + * Comments: _set_cursor enable function is hardcoded to disable + * the cursor. *---------------------------------------------------------------------------- */ void @@ -251,14 +285,14 @@ LXHideCursor(ScrnInfoPtr pScrni) * Description :This function will enable the cursor. * * Parameters: - * pScrni :Handles to the Screeen information pointer structure. + * pScrn :Handles to the Screeen pointer structure. * * Returns :none * * Comments :gfx_set_cursor enable function is hardcoded to enable the - * cursor + * cursor *---------------------------------------------------------------------------- -*/ + */ void LXShowCursor(ScrnInfoPtr pScrni) { @@ -269,23 +303,22 @@ LXShowCursor(ScrnInfoPtr pScrni) * LXUseHwCursor. * * Description :This function will sets the hardware cursor flag in - * pscreen structure. + * pscreen structure. * * Parameters. - * pScreen :Handles to the Screeen pointer structure. + * pScrn :Handles to the Screeen pointer structure. * * Returns :none * * Comments :none * *---------------------------------------------------------------------------- -*/ + */ static Bool LXUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs) { ScrnInfoPtr pScrni = XF86SCRNINFO(pScrn); + GeodeRec *pGeode = GEODEPTR(pScrni); - if (pScrni->currentMode->Flags & V_DBLSCAN) - return FALSE; - return TRUE; + return pGeode->HWCursor; } diff --git a/src/amd_lx_dga.c b/src/amd_lx_dga.c deleted file mode 100644 index 775d3f4..0000000 --- a/src/amd_lx_dga.c +++ /dev/null @@ -1,398 +0,0 @@ -/* - * Copyright (c) 2006 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Neither the name of the Advanced Micro Devices, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - */ - -/* - * File contents: DGA(Direct Acess Graphics mode) is feature of - * XFree86 that allows the program to access directly to video - * memory on the graphics card. DGA supports the double - * flickering. This file has the functions to support the DGA - * modes. - * - * Project: Geode Xfree Frame buffer device driver. - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "xf86.h" -#include "xf86_OSproc.h" -#include "xf86_ansic.h" -#include "xf86Pci.h" -#include "xf86PciInfo.h" -#include "xaa.h" -#include "xaalocal.h" -#include "amd.h" -#include "dgaproc.h" - -/* forward declarations */ -Bool LXDGAInit(ScreenPtr pScrn); -static Bool LX_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, - int *, int *, int *); -static void LX_CloseFramebuffer(ScrnInfoPtr pScrni); -static Bool LX_SetMode(ScrnInfoPtr, DGAModePtr); -static int LX_GetViewport(ScrnInfoPtr); -static void LX_SetViewport(ScrnInfoPtr, int, int, int); -static void LX_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); -static void LX_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); - -extern void LXAdjustFrame(int, int, int, int); -extern Bool LXSwitchMode(int, DisplayModePtr, int); -extern void LXAccelSync(ScrnInfoPtr pScrni); - -static DGAFunctionRec LXDGAFuncs = { - LX_OpenFramebuffer, - LX_CloseFramebuffer, - LX_SetMode, - LX_SetViewport, - LX_GetViewport, - LXAccelSync, - LX_FillRect, - LX_BlitRect, - NULL -}; - -/*---------------------------------------------------------------------------- - * LXDGAInit. - * - * Description :This function is used to initialize the DGA modes and sets - * the viewport based on the screen mode. - * Parameters. - * pScreeen :Pointer to screen info structure. - * - * Returns :TRUE on success and FALSE on failure. - * - * Comments :This function prepares the DGA mode settings for - * other func reference. - * -*---------------------------------------------------------------------------- -*/ -Bool -LXDGAInit(ScreenPtr pScrn) -{ - ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; - GeodeRec *pGeode = GEODEPTR(pScrni); - DGAModePtr modes = NULL, newmodes = NULL, currentMode; - DisplayModePtr pMode, firstMode; - int Bpp = pScrni->bitsPerPixel >> 3; - int num = 0; - Bool oneMore; - - pMode = firstMode = pScrni->modes; - DEBUGMSG(0, (0, X_NONE, "LXDGAInit %d\n", Bpp)); - while (pMode) { - /* one record is allocated here */ - newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec)); - oneMore = FALSE; - - if (!newmodes) { - xfree(modes); - return FALSE; - } - - modes = newmodes; - - SECOND_PASS: /* DGA mode flgas and viewport parametrs are set here. */ - currentMode = modes + num; - num++; - currentMode->mode = pMode; - currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; - currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; - if (pMode->Flags & V_DBLSCAN) - currentMode->flags |= DGA_DOUBLESCAN; - if (pMode->Flags & V_INTERLACE) - currentMode->flags |= DGA_INTERLACED; - currentMode->byteOrder = pScrni->imageByteOrder; - currentMode->depth = pScrni->depth; - currentMode->bitsPerPixel = pScrni->bitsPerPixel; - currentMode->red_mask = pScrni->mask.red; - currentMode->green_mask = pScrni->mask.green; - currentMode->blue_mask = pScrni->mask.blue; - currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; - currentMode->viewportWidth = pMode->HDisplay; - currentMode->viewportHeight = pMode->VDisplay; - currentMode->xViewportStep = 1; - currentMode->yViewportStep = 1; - currentMode->viewportFlags = DGA_FLIP_RETRACE; - currentMode->offset = 0; - currentMode->address = pGeode->FBBase; - if (oneMore) { /* first one is narrow width */ - currentMode->bytesPerScanline = - ((pMode->HDisplay * Bpp) + 3) & ~3L; - currentMode->imageWidth = pMode->HDisplay; - currentMode->imageHeight = pMode->VDisplay; - currentMode->pixmapWidth = currentMode->imageWidth; - currentMode->pixmapHeight = currentMode->imageHeight; - currentMode->maxViewportX = currentMode->imageWidth - - currentMode->viewportWidth; - /* this might need to get clamped to some maximum */ - currentMode->maxViewportY = currentMode->imageHeight - - currentMode->viewportHeight; - oneMore = FALSE; - goto SECOND_PASS; - } else { - currentMode->bytesPerScanline = - ((pScrni->displayWidth * Bpp) + 3) & ~3L; - currentMode->imageWidth = pScrni->displayWidth; - currentMode->imageHeight = pMode->VDisplay; - currentMode->pixmapWidth = currentMode->imageWidth; - currentMode->pixmapHeight = currentMode->imageHeight; - currentMode->maxViewportX = currentMode->imageWidth - - currentMode->viewportWidth; - /* this might need to get clamped to some maximum */ - currentMode->maxViewportY = currentMode->imageHeight - - currentMode->viewportHeight; - } - pMode = pMode->next; - if (pMode == firstMode) - break; - } - pGeode->numDGAModes = num; - pGeode->DGAModes = modes; - - return DGAInit(pScrn, &LXDGAFuncs, modes, num); -} - -/*---------------------------------------------------------------------------- - * LX_SetMode. - * - * Description :This function is sets into the DGA mode. - *. - * Parameters. - * pScreeen :Pointer to screen info structure. - * pMode :Points to the DGAmode ptr data - * Returns :TRUE on success and FALSE on failure. - * - * Comments :none. - * - * -*---------------------------------------------------------------------------- -*/ -static Bool -LX_SetMode(ScrnInfoPtr pScrni, DGAModePtr pMode) -{ - static int OldDisplayWidth[MAXSCREENS]; - int index = pScrni->pScreen->myNum; - GeodeRec *pGeode = GEODEPTR(pScrni); - - DEBUGMSG(0, (0, X_NONE, "LX_SetMode\n")); - - if (!pMode) { - /* restore the original mode - * put the ScreenParameters back - */ - pScrni->displayWidth = OldDisplayWidth[index]; - DEBUGMSG(0, - (0, X_NONE, "LX_SetMode !pMode %d\n", pScrni->displayWidth)); - LXSwitchMode(index, pScrni->currentMode, 0); - pGeode->DGAactive = FALSE; - } else { - if (!pGeode->DGAactive) { /* save the old parameters */ - OldDisplayWidth[index] = pScrni->displayWidth; - pGeode->DGAactive = TRUE; - DEBUGMSG(0, (0, X_NONE, "LX_SetMode pMode+ NA %d\n", - pScrni->displayWidth)); - } - pGeode->PrevDisplayOffset = vg_get_display_offset(); - - pScrni->displayWidth = pMode->bytesPerScanline / - (pMode->bitsPerPixel >> 3); - DEBUGMSG(0, (0, X_NONE, - "LX_SetMode pMode+ %d\n", pScrni->displayWidth)); - LXSwitchMode(index, pMode->mode, 0); - } - /* enable/disable Compression */ - if (pGeode->Compression) { - vg_set_compression_enable(!pGeode->DGAactive); - } - - /* enable/disable cursor */ - if (pGeode->HWCursor) { - vg_set_cursor_enable(!pGeode->DGAactive); - } - - return TRUE; -} - -/*---------------------------------------------------------------------------- - * LX_GetViewPort. - * - * Description :This function is Gets the viewport window memory. - *. - * Parameters. - * pScrni :Pointer to screen info structure. - * - * Returns :returns the viewport status. - * - * Comments :none. - * - * -*---------------------------------------------------------------------------- -*/ -static int -LX_GetViewport(ScrnInfoPtr pScrni) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - return pGeode->DGAViewportStatus; -} - -/*---------------------------------------------------------------------------- - * LX_SetViewPort. - * - * Description :This function is Gets the viewport window memory. - * - * Parameters. - * pScrni :Pointer to screen info structure. - x :x-cordinate of viewport window - * y :y-codinate of the viewport window. - * flags :indicates the viewport to be flipped or not. - * Returns :returns the viewport status as zero. - * - * Comments :none. - * -*---------------------------------------------------------------------------- -*/ -static void -LX_SetViewport(ScrnInfoPtr pScrni, int x, int y, int flags) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - LXAdjustFrame(pScrni->pScreen->myNum, x, y, flags); - pGeode->DGAViewportStatus = 0; /* LXAdjustFrame loops until finished */ -} - -/*---------------------------------------------------------------------------- - * LX_FillRect. - * - * Description :This function is Gets the viewport window memory. - *. - * Parameters. - * pScrni :Pointer to screen info structure. - * x :x-cordinate of viewport window - * y :y-codinate of the viewport window. - * w :width of the rectangle - * h :height of the rectangle. - * color :color to be filled in rectangle. - * - * Returns :returns the viewport status as zero. - * - * Comments :This function is implemented by solidfill routines.. - * -*---------------------------------------------------------------------------- -*/ -static void -LX_FillRect(ScrnInfoPtr pScrni, int x, int y, - int w, int h, unsigned long color) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - if (pGeode->AccelInfoRec) { - (*pGeode->AccelInfoRec->SetupForSolidFill) (pScrni, color, GXcopy, - ~0); - (*pGeode->AccelInfoRec->SubsequentSolidFillRect) (pScrni, x, y, w, h); - SET_SYNC_FLAG(pGeode->AccelInfoRec); - } -} - -/*---------------------------------------------------------------------------- - * LX_BlitRect. - * - * Description :This function implementing Blit and it moves a - * Rectangular block of data from one location to other - * Location. - * - * Parameters. - * pScrni :Pointer to screen info structure. - * srcx :x-cordinate of the src rectangle - * srcy :y-codinate of src rectangle. - * w :width of the rectangle - * h :height of the rectangle. - * dstx :x-cordinate of the dst rectangle. - * dsty :y -coordinates of the dst rectangle. - * Returns :none. - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ -static void -LX_BlitRect(ScrnInfoPtr pScrni, - int srcx, int srcy, int w, int h, int dstx, int dsty) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - if (pGeode->AccelInfoRec) { - int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; - int ydir = (srcy < dsty) ? -1 : 1; - - (*pGeode->AccelInfoRec->SetupForScreenToScreenCopy) - (pScrni, xdir, ydir, GXcopy, ~0, -1); - (*pGeode->AccelInfoRec->SubsequentScreenToScreenCopy) - (pScrni, srcx, srcy, dstx, dsty, w, h); - SET_SYNC_FLAG(pGeode->AccelInfoRec); - } -} - -/*---------------------------------------------------------------------------- - * LX_OpenFramebuffer. - * - * Description :This function open the framebuffer driver for DGA. - * - * Parameters. - * pScrni :Pointer to screen info structure. - * srcx :x-cordinate of the src rectangle - * srcy :y-codinate of src rectangle. - * w :width of the rectangle - * h :height of the rectangle. - * dstx :x-cordinate of the dst rectangle. - * dsty :y -coordinates of the dst rectangle. - * Returns :none. - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ -static Bool -LX_OpenFramebuffer(ScrnInfoPtr pScrni, - char **name, unsigned char **mem, int *size, int *offset, int *flags) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - *name = NULL; /* no special device */ - *mem = (unsigned char *)pGeode->FBLinearAddr; - *size = pGeode->FBAvail; - *offset = 0; - *flags = DGA_NEED_ROOT; - - return TRUE; -} - -static void -LX_CloseFramebuffer(ScrnInfoPtr pScrni) -{ -} diff --git a/src/amd_lx_driver.c b/src/amd_lx_driver.c index 9a2146a..d8cfaa7 100644 --- a/src/amd_lx_driver.c +++ b/src/amd_lx_driver.c @@ -1,12 +1,15 @@ -/* - * Copyright (c) 2006 Advanced Micro Devices, Inc. +/* Copyright (c) 2003-2007 Advanced Micro Devices, Inc. * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: + * Portioned modeled from xf86-video-intel/src/i830_driver.c + * Copyright 2001 VA Linux Systems Inc., Fremont, California. + * Copyright \ufffd 2002 by David Dawes + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. @@ -16,2201 +19,1084 @@ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. * * Neither the name of the Advanced Micro Devices, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. */ -/* - * File Contents: This is the main module configures the interfacing - * with the X server. The individual modules will be - * loaded based upon the options selected from the - * XF86Config. This file also has modules for finding - * supported modes, turning on the modes based on options. - * - * Project: Geode Xfree Frame buffer device driver. - * - */ +/* TODO: + TV out support + Detect panels better + Better VGA support + GX: cursor position needs to be correctly set + use CB data wrapper to save a variable + consolidate the saved timings + implement panning +*/ + +/* The effort to make things common: + define CmdBfrSize in the GX + add the output flag to GX +*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif -/* Includes that are used by all drivers */ +#include <stdio.h> + #include "xf86.h" #include "xf86_OSproc.h" -#include "xf86_ansic.h" -#include "xf86_libc.h" #include "xf86Resources.h" -#include "compiler.h" -#include "xf86PciInfo.h" -#include "xf86Pci.h" #include "xf86cmap.h" - -#define RC_MAX_DEPTH 24 - -#include "amd.h" -#include "cim_defs.h" -#include "cim_regs.h" -#include "cim_dev.h" - -/* Frame buffer stuff */ -#if CFB -/* - * If using cfb, cfb.h is required. Select the others for the bpp values - * the driver supports. - */ -#define PSZ 8 /* needed for cfb.h */ -#include "cfb.h" -#undef PSZ -#include "cfb16.h" -#include "cfb24.h" -#include "cfb32.h" -#else -#include "fb.h" -#endif - -#include "shadowfb.h" - -/* Machine independent stuff */ +#include "compiler.h" #include "mipointer.h" -#include "mibank.h" +#include <X11/extensions/randr.h> +#include "fb.h" +#include "miscstruct.h" #include "micmap.h" -#include "mibstore.h" -#include "vgaHW.h" #include "vbe.h" +#include "fb.h" +#include "randrstr.h" +#include "cim_defs.h" +#include "cim_regs.h" +#include "amd.h" -/* Check for some extensions */ -#ifdef XFreeXDGA -#define _XF86_DGA_SERVER_ -#include <X11/extensions/xf86dgastr.h> -#endif /* XFreeXDGA */ - -#ifdef DPMSExtension -#include "globals.h" -#include "opaque.h" -#define DPMS_SERVER -#include <X11/extensions/dpms.h> -#endif /* DPMSExtension */ - +/* Bring in VGA functions */ #include "amd_lx_vga.c" -extern SymTabRec GeodeChipsets[]; -extern OptionInfoRec LX_GeodeOptions[]; +/* Chipset types */ -/* Forward definitions */ -static Bool LXPreInit(ScrnInfoPtr, int); -static Bool LXScreenInit(int, ScreenPtr, int, char **); -static Bool LXEnterVT(int, int); -static void LXLeaveVT(int, int); -static void LXFreeScreen(int, int); -void LXAdjustFrame(int, int, int, int); -Bool LXSwitchMode(int, DisplayModePtr, int); -static int LXValidMode(int, DisplayModePtr, Bool, int); -static void LXLoadPalette(ScrnInfoPtr pScrni, - int numColors, int *indizes, LOCO * colors, VisualPtr pVisual); -static Bool LXMapMem(ScrnInfoPtr); -static Bool LXUnmapMem(ScrnInfoPtr); - -extern Bool LXAccelInit(ScreenPtr pScrn); -extern Bool LXHWCursorInit(ScreenPtr pScrn); -extern void LXHideCursor(ScrnInfoPtr pScrni); -extern void LXShowCursor(ScrnInfoPtr pScrni); -extern void LXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src); -extern void LXPointerMoved(int index, int x, int y); -extern void LXRotationInit(ScrnInfoPtr pScrni); -extern void LXShadowFBInit(ScreenPtr pScrn, GeodeRec *pGeode, int bytpp); -extern void LXInitVideo(ScreenPtr pScrn); -extern Bool LXDGAInit(ScreenPtr pScrn); +#define LX_MIN_PITCH 1024 +#define LX_MAX_PITCH 8192 +#define LX_MAX_WIDTH 1940 +#define LX_MIN_HEIGHT 400 +#define LX_MAX_HEIGHT 1600 +#define LX_CB_PITCH 544 +#define LX_CB_SIZE 544 -unsigned char *XpressROMPtr; -unsigned long fb; +#define LX_GP_REG_SIZE 0x4000 +#define LX_VG_REG_SIZE 0x4000 +#define LX_VID_REG_SIZE 0x4000 +#define LX_VIP_REG_SIZE 0x4000 + +extern OptionInfoRec LX_GeodeOptions[]; extern const char *amdVgahwSymbols[]; extern const char *amdVbeSymbols[]; extern const char *amdInt10Symbols[]; - -#if CFB -extern const char *amdCfbSymbols[]; -#else extern const char *amdFbSymbols[]; -#endif -extern const char *amdXaaSymbols[]; +extern const char *amdExaSymbols[]; extern const char *amdRamdacSymbols[]; -extern const char *amdShadowSymbols[]; - -void LXSetupChipsetFPtr(ScrnInfoPtr pScrni); -GeodeRec *LXGetRec(ScrnInfoPtr pScrni); -void lx_clear_screen(ScrnInfoPtr pScrni, int width, int height, int bpp); -void lx_clear_fb(ScrnInfoPtr pScrni); -void lx_disable_dac_power(ScrnInfoPtr pScrni, int option); -void lx_enable_dac_power(ScrnInfoPtr pScrni, int option); -#if DEBUGLVL>0 -FILE *zdfp = NULL; -#endif +unsigned char *XpressROMPtr; /* Reference: Video Graphics Suite Specification: * VG Config Register (0x00) page 16 - * VG FP Register (0x02) page 18 */ - -#define LX_READ_VG(reg) \ - (outw(0xAC1C,0xFC53), outw(0xAC1C,0x0200|(reg)), inw(0xAC1E)) + * VG FP Register (0x02) page 18 + */ -/* panel resolutiosn decode of FP config reg */ +#define LX_READ_VG(reg) \ + (outw(0xAC1C,0xFC53), outw(0xAC1C,0x0200|(reg)), inw(0xAC1E)) -static struct sLXFpResolution +static inline void +lx_enable_dac_power(ScrnInfoPtr pScrni, int option) { - int xres, yres; -} lx_fp_resolution[] = { - { - 320, 240}, { - 640, 480}, { - 800, 600}, { - 1024, 768}, { - 1152, 864}, { - 1280, 1024}, { - 1600, 1200}, { - 0, 0} -}; - -/* Get the information from the BIOS regarding the panel */ + GeodeRec *pGeode = GEODEPTR(pScrni); -static int -lx_get_panel_info(int *xres, int *yres) + df_set_crt_enable(DF_CRT_ENABLE); + + /* Turn off the DAC if we don't need the CRT */ + + if (option && (!(pGeode->Output & OUTPUT_CRT))) { + unsigned int misc = READ_VID32(DF_VID_MISC); + misc |= DF_DAC_POWER_DOWN; + WRITE_VID32(DF_VID_MISC, misc); + } + + if (pGeode->Output & OUTPUT_PANEL) + df_set_panel_enable(1); +} + +static inline void +lx_disable_dac_power(ScrnInfoPtr pScrni, int option) { - unsigned short reg = LX_READ_VG(0x02); + GeodeRec *pGeode = GEODEPTR(pScrni); + + if (pGeode->Output & OUTPUT_PANEL) + df_set_panel_enable(0); - *xres = lx_fp_resolution[(reg >> 3) & 0x07].xres; - *yres = lx_fp_resolution[(reg >> 3) & 0x07].yres; + if (pGeode->Output & OUTPUT_CRT) { - return 0; + /* Wait for the panel to finish its procedure */ + + if (pGeode->Output & OUTPUT_PANEL) + while ((READ_VID32(DF_POWER_MANAGEMENT) & 2) == 0); + df_set_crt_enable(option); + } } static int -lx_panel_configured(void) +lx_get_panel(int *xres, int *yres) { - unsigned short reg = LX_READ_VG(0x00); - unsigned char ret = (reg >> 8) & 0x7; + static struct { + int xres, yres; + } fpres[] = { + { 320, 240 }, { 640, 480 }, { 800, 600 }, { 1024, 768 }, + { 1152, 864 }, { 1280, 1024 }, { 1600, 1200 } }; + + unsigned short reg = LX_READ_VG(0x00); + unsigned char ret = (reg >> 8) & 0x07; + + if ((ret == 1 || ret == 5)) { + + reg = LX_READ_VG(0x02); + ret = (reg >> 3) & 0x07; + + /* 7 is a "reserved" value - if we get it, we can only assume that + a panel doesn't exist (or it hasn't been configured in the BIOS) + */ + + if (ret < 7) { + *xres = fpres[ret].xres; + *yres = fpres[ret].yres; + + return TRUE; + } + } + + return FALSE; +} - return (ret == 1) || (ret == 5) ? 1 : 0; +static int +lx_set_custom_mode(GeodeRec *pGeode, DisplayModePtr pMode, int bpp) +{ + VG_DISPLAY_MODE mode; + int flags = 0; + + memset(&mode, 0, sizeof(mode)); + + if (pMode->Flags & V_NHSYNC) + mode.flags |= VG_MODEFLAG_NEG_HSYNC; + if (pMode->Flags & V_NVSYNC) + mode.flags |= VG_MODEFLAG_NEG_VSYNC; + + mode.flags |= pGeode->Output & OUTPUT_CRT ? VG_MODEFLAG_CRT_AND_FP : 0; + + if (pGeode->Output & OUTPUT_PANEL) { + mode.panel_width = mode.mode_width = pGeode->PanelX; + mode.panel_height = mode.mode_height = pGeode->PanelY; + + mode.flags |= VG_MODEFLAG_PANELOUT; + mode.flags |= pGeode->Output & OUTPUT_CRT ? VG_MODEFLAG_CRT_AND_FP : 0; + } + else { + mode.mode_width = pMode->CrtcHDisplay; + mode.mode_height = pMode->CrtcVDisplay; + } + + mode.src_width = pMode->CrtcHDisplay; + mode.src_height = pMode->CrtcVDisplay; + + mode.hactive = pMode->CrtcHDisplay; + mode.hblankstart = pMode->CrtcHBlankStart; + mode.hsyncstart = pMode->CrtcHSyncStart; + mode.hsyncend = pMode->CrtcHSyncEnd; + mode.hblankend = pMode->CrtcHBlankEnd; + mode.htotal = pMode->CrtcHTotal; + + mode.vactive = pMode->CrtcVDisplay; + mode.vblankstart = pMode->CrtcVBlankStart; + mode.vsyncstart = pMode->CrtcVSyncStart; + mode.vsyncend = pMode->CrtcVSyncEnd; + mode.vblankend = pMode->CrtcVBlankEnd; + mode.vtotal = pMode->CrtcVTotal; + + mode.vactive_even = pMode->CrtcVDisplay; + mode.vblankstart_even = pMode->CrtcVBlankStart; + mode.vsyncstart_even = pMode->CrtcVSyncStart; + mode.vsyncend_even = pMode->CrtcVSyncEnd; + mode.vblankend_even = pMode->CrtcVBlankEnd; + mode.vtotal_even = pMode->CrtcVTotal; + + mode.frequency = (int)((pMode->SynthClock / 1000.0) * 0x10000); + + return vg_set_custom_mode(&mode, bpp); } -void -LXSetupChipsetFPtr(ScrnInfoPtr pScrni) +void LXGetOutputs(GeodeRec *pGeode) { -#if DEBUGLVL>0 - if (zdfp == NULL) { - zdfp = fopen("/tmp/xwin.log", "w"); - setbuf(zdfp, NULL); - } -#endif - DEBUGMSG(1, (0, X_INFO, "LXSetupChipsetFPtr!\n")); - pScrni->PreInit = LXPreInit; - pScrni->ScreenInit = LXScreenInit; - pScrni->SwitchMode = LXSwitchMode; - pScrni->AdjustFrame = LXAdjustFrame; - pScrni->EnterVT = LXEnterVT; - pScrni->LeaveVT = LXLeaveVT; - pScrni->FreeScreen = LXFreeScreen; - pScrni->ValidMode = LXValidMode; + Q_WORD msr; + + msr_read64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr); + + /* XXX: VOP is always on? */ + + pGeode->Output = OUTPUT_VOP; + + switch((msr.low >> 3) & 0x07) { + case 4: + case 2: + case 0: + pGeode->Output = OUTPUT_CRT; + break; + case 1: + case 3: + case 5: + pGeode->Output = OUTPUT_PANEL; + + if ((msr.low & 0x8000) != 0) + pGeode->Output |= OUTPUT_CRT; + break; + + case 6: + /* VOP */ + break; + + default: + ErrorF("Geode LX - unusual output strap %x\'n", msr.low); + break; + } } -#ifdef AMD_V4L2_VIDEO -void -LXInitVideo(ScreenPtr pScrn) +static Bool +LXAllocateMemory(ScreenPtr pScrn, ScrnInfoPtr pScrni, int rotate) { - GeodeRec *pGeode; - int num_adaptors; - XF86VideoAdaptorPtr *adaptors; - ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; + GeodePtr pGeode = GEODEPTR(pScrni); + + unsigned int fboffset, fbavail; + unsigned int size; + unsigned int bytpp = (pScrni->bitsPerPixel + 7) / 8; + BOOL ret = TRUE; + + if (pGeode->tryCompression) + pGeode->displayPitch = + GeodeCalculatePitchBytes(pScrni->virtualX, pScrni->bitsPerPixel); + else + pGeode->displayPitch = + ((pScrni->virtualX + 3) & ~3) * (pScrni->bitsPerPixel >> 3); + + pGeode->Pitch = pGeode->displayPitch; + pGeode->displayWidth = pGeode->displayPitch / bytpp; + pScrni->displayWidth = pGeode->displayWidth; + + fbavail = pGeode->FBAvail - GP3_SCRATCH_BUFFER_SIZE; + + pGeode->displayOffset = fboffset = 0; + pGeode->displaySize = pScrni->virtualY * pGeode->displayPitch; + + fbavail -= pGeode->displaySize; + fboffset += pGeode->displaySize; + + if (pGeode->tryCompression) { + size = pScrni->virtualY * LX_CB_PITCH; + + if (size <= fbavail) { + pGeode->CBData.compression_offset = fboffset; + + fboffset += size; + fbavail -= size; + + pGeode->Compression = TRUE; + } else { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Not enough memory for compression\n"); + pGeode->Compression = FALSE; + } + } + + if (pGeode->tryHWCursor) { + pGeode->CursorSize = 1024; + + if (pGeode->CursorSize <= fbavail) { + pGeode->CursorStartOffset = fboffset; + fboffset += pGeode->CursorSize; + fbavail -= pGeode->CursorSize; + pGeode->HWCursor = TRUE; + } else { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Not enough memory for the hardware cursor\n"); + pGeode->HWCursor = FALSE; + } + } + + /* Try to set up some EXA scratch memory for blending */ - pGeode = GEODEPTR(pScrni); if (!pGeode->NoAccel) { - num_adaptors = xf86XVListGenericAdaptors(pScrni, &adaptors); - if (num_adaptors > 0) - xf86XVScreenInit(pScrn, adaptors, num_adaptors); + if (pGeode->exaBfrSz > 0 && pGeode->exaBfrSz <= fbavail) { + pGeode->exaBfrOffset = fboffset; + fboffset += pGeode->exaBfrOffset; + fbavail -= pGeode->exaBfrOffset; + } } -} -#else -extern void LXInitVideo(ScreenPtr pScrn); -#endif -/*---------------------------------------------------------------------------- - * LXGetRec. - * - * Description :This function allocate an GeodeRec and hooked into - * pScrni str driverPrivate member of ScreeenInfo - * structure. - * Parameters. - * pScrni :Pointer handle to the screenonfo structure. - * - * Returns :allocated driver structure. - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ -GeodeRec * -LXGetRec(ScrnInfoPtr pScrni) -{ - if (!pScrni->driverPrivate) { - GeodeRec *pGeode; + pGeode->shadowSize = 0; - pGeode = pScrni->driverPrivate = xnfcalloc(sizeof(GeodeRec), 1); -#if INT10_SUPPORT - pGeode->vesa = xcalloc(sizeof(VESARec), 1); -#endif + if (rotate != RR_Rotate_0) { + if (rotate & (RR_Rotate_90 | RR_Rotate_270)) + size = pGeode->displayPitch * pScrni->virtualX; + else + size = pGeode->displayPitch * pScrni->virtualY; + + if (size <= fbavail) { + pGeode->shadowOffset = fboffset; + pGeode->shadowSize = size; + + fboffset += size; + fbavail -= size; + } else { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Not enough memory for the shadow framebuffer\n"); + ret = FALSE; + } } - return GEODEPTR(pScrni); -} + /* Adjust the available EXA offscreen space to account for the buffer */ -/*---------------------------------------------------------------------------- - * LXFreeRec. - * - * Description :This function deallocate an GeodeRec and freed from - * pScrni str driverPrivate member of ScreeenInfo - * structure. - * Parameters. - * pScrni :Pointer handle to the screenonfo structure. - * - * Returns :none - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ -static void -LXFreeRec(ScrnInfoPtr pScrni) -{ - if (pScrni->driverPrivate == NULL) { - return; + if (!pGeode->NoAccel && pGeode->pExa) { + pGeode->pExa->offScreenBase = fboffset; + pGeode->pExa->memorySize = fboffset + fbavail; } - xfree(pScrni->driverPrivate); - pScrni->driverPrivate = NULL; } -/*---------------------------------------------------------------------------- - * LXSaveScreen. - * - * Description :This is to do the screen blanking - * - * Parameters. - * pScrn :Handle to ScreenPtr structure. - * mode :mode is used by vgaHWSaveScren to check blnak os on. - * - * Returns :TRUE on success and FALSE on failure. - * - * Comments :none -*---------------------------------------------------------------------------- -*/ static Bool LXSaveScreen(ScreenPtr pScrn, int mode) { ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; + GeodePtr pGeode = GEODEPTR(pScrni); - DEBUGMSG(0, (0, X_INFO, "LXSaveScreen!\n")); - - if (!pScrni->vtSema) - return vgaHWSaveScreen(pScrn, mode); + if (pGeode->useVGA && !pScrni->vtSema) + return vgaHWSaveScreen(pScrn, mode); return TRUE; } -static xf86MonPtr -LXProbeDDC(ScrnInfoPtr pScrni, int index) +static Bool +LXMapMem(ScrnInfoPtr pScrni) { - vbeInfoPtr pVbe; - xf86MonPtr ddc = NULL; + GeodeRec *pGeode = GEODEPTR(pScrni); + int index = pScrni->scrnIndex; + unsigned long cmd_bfr_phys; + PCITAG tag; - if (xf86LoadSubModule(pScrni, "vbe")) { - pVbe = VBEInit(NULL, index); - ddc = vbeDoEDID(pVbe, NULL); - vbeFree(pVbe); - } + pciVideoRec *pci = xf86GetPciInfoForEntity(pGeode->pEnt->index); + tag = pciTag(pci->bus, pci->device, pci->func); - return ddc; -} + cim_gp_ptr = (unsigned char *)xf86MapPciMem(index, VIDMEM_MMIO, + tag, pci->memBase[1], LX_GP_REG_SIZE); -static void -LXDecodeDDC(ScrnInfoPtr pScrni, xf86MonPtr ddc) -{ - int i; - - DEBUGMSG(1, (0, X_INFO, - "Detected monitor DDC (%4s) id %d serno %d week %d year %d " - "nsects %d\n", &ddc->vendor.name[0], ddc->vendor.prod_id, - ddc->vendor.serial, ddc->vendor.week, ddc->vendor.year, - ddc->no_sections)); - for (i = 0; i < DET_TIMINGS; ++i) { - struct detailed_monitor_section *dp = &ddc->det_mon[i]; - - switch (dp->type) { - case DT:{ - struct detailed_timings *r = &dp->section.d_timings; - - DEBUGMSG(1, (0, X_INFO, " mon det timing %0.3f %dx%d\n", - r->clock / 1000000.0, r->h_active, r->v_active)); - DEBUGMSG(1, (0, X_INFO, - " mon border %d,%d laced %d stereo %d sync %d, misc %d\n", - r->h_border, r->v_border, r->interlaced, r->stereo, - r->sync, r->misc)); - } - break; - - case DS_SERIAL:{ - char *serial_no = (char *)&dp->section.serial[0]; - - DEBUGMSG(1, (0, X_INFO, " mon serial %13s\n", serial_no)); - } - break; - - case DS_ASCII_STR:{ - char *ascii = (char *)&dp->section.ascii_data[0]; - - DEBUGMSG(1, (0, X_INFO, " mon ascii_str %13s\n", ascii)); - } - break; - - case DS_NAME:{ - char *name = (char *)&dp->section.name[0]; - - DEBUGMSG(1, (0, X_INFO, " mon name %13s\n", name)); - } break; - - case DS_RANGES:{ - struct monitor_ranges *r = &dp->section.ranges; - - DEBUGMSG(1, (0, X_INFO, - " mon ranges v %d-%d h %d-%d clk %d\n", r->min_v, - r->max_v, r->min_h, r->max_h, r->max_clock)); - } - break; - - case DS_WHITE_P:{ - struct whitePoints *wp = &dp->section.wp[0]; - - DEBUGMSG(1, (0, X_INFO, - " mon whitept %f,%f %f,%f idx %d,%d gamma %f,%f\n", - wp[1].white_x, wp[1].white_y, wp[2].white_x, - wp[2].white_y, wp[1].index, wp[2].index, - wp[1].white_gamma, wp[2].white_gamma)); - } - break; - - case DS_STD_TIMINGS:{ - struct std_timings *t = &dp->section.std_t[0]; - - DEBUGMSG(1, (0, X_INFO, - " mon std_timing no size @rate, id\n")); - for (i = 0; i < 5; ++i) - DEBUGMSG(1, (0, X_INFO, - " %d %5dx%-5d @%-4d %d\n", i, - t[i].hsize, t[i].vsize, t[i].refresh, t[i].id)); - } - break; - } - } -} + cim_vg_ptr = (unsigned char *)xf86MapPciMem(index, VIDMEM_MMIO, + tag, pci->memBase[2], LX_VG_REG_SIZE); -static void -LXFBAlloc(int fd, unsigned int offset, unsigned int size) -{ - cim_mem_req_t req; - - memset(&req, 0, sizeof(req)); - strcpy(&req.owner[0], "XFree86"); - sprintf(&req.name[0], "%08lx", offset); - req.flags = CIM_F_PUBLIC; - req.size = size; - ioctl(fd, CIM_RESERVE_MEM, &req); -} + cim_vid_ptr = (unsigned char *)xf86MapPciMem(index, VIDMEM_MMIO, + tag, pci->memBase[3], LX_VID_REG_SIZE); + + cim_vip_ptr = (unsigned char *)xf86MapPciMem(index, VIDMEM_MMIO, + tag, pci->memBase[4], LX_VIP_REG_SIZE); -/* check for "tv-" or "pnl-" in mode name, decode suffix */ -/* return -1 if mode name is not a known tv/pnl mode */ -static int -lx_tv_mode(DisplayModePtr pMode) -{ - int tv_mode = -1; - char *bp, *cp; - - cp = pMode->name; - if ((*(bp = cp) == 't' && *++bp == 'v') || - (*(bp = cp) == 'p' && *++bp == 'n' && *++bp == 'l')) { - if (*++bp == '-') { - if (xf86NameCmp("ntsc", ++bp) == 0) - tv_mode = VG_TVMODE_NTSC; - else if (xf86NameCmp("pal", bp) == 0) - tv_mode = VG_TVMODE_PAL; - else if (xf86NameCmp("6x4_ntsc", bp) == 0) - tv_mode = VG_TVMODE_6X4_NTSC; - else if (xf86NameCmp("8x6_ntsc", bp) == 0) - tv_mode = VG_TVMODE_8X6_NTSC; - else if (xf86NameCmp("10x7_ntsc", bp) == 0) - tv_mode = VG_TVMODE_10X7_NTSC; - else if (xf86NameCmp("6x4_pal", bp) == 0) - tv_mode = VG_TVMODE_6X4_PAL; - else if (xf86NameCmp("8x6_pal", bp) == 0) - tv_mode = VG_TVMODE_8X6_PAL; - else if (xf86NameCmp("10x7_pal", bp) == 0) - tv_mode = VG_TVMODE_10X7_PAL; - else if (xf86NameCmp("480p", bp) == 0) - tv_mode = VG_TVMODE_480P; - else if (xf86NameCmp("720p", bp) == 0) - tv_mode = VG_TVMODE_720P; - else if (xf86NameCmp("1080i", bp) == 0) - tv_mode = VG_TVMODE_1080I; - } - } + cim_fb_ptr = (unsigned char *)xf86MapPciMem(index, VIDMEM_FRAMEBUFFER, + tag, pci->memBase[0], pGeode->FBAvail + CIM_CMD_BFR_SZ); - return tv_mode; -} + cmd_bfr_phys = pci->memBase[0] + pGeode->CmdBfrOffset; + cim_cmd_base_ptr = cim_fb_ptr + pGeode->CmdBfrOffset; -static int -lx_tv_mode_interlaced(int tv_mode) -{ - switch (tv_mode) { - case VG_TVMODE_NTSC: - case VG_TVMODE_PAL: - case VG_TVMODE_1080I: - return 1; - } + if (!cim_gp_ptr || !cim_vg_ptr || !cim_vid_ptr || !cim_fb_ptr || + !cim_vip_ptr) + return FALSE; + + /* FIXME: Temporary */ + WRITE_GP32(GP3_BLT_STATUS, 0x690000); + + gp_set_frame_buffer_base(pci->memBase[0], pGeode->FBAvail); + gp_set_command_buffer_base(cmd_bfr_phys, 0, pGeode->CmdBfrSize); + + XpressROMPtr = xf86MapVidMem(index, VIDMEM_FRAMEBUFFER, 0xF0000, 0x10000); - return 0; + pGeode->FBBase = cim_fb_ptr; + + if (!pGeode->NoAccel) + pGeode->pExa->memoryBase = pGeode->FBBase; + + xf86DrvMsg(index, X_INFO, "Geode LX video memory %lx bytes at %p\n", + pGeode->FBAvail, pGeode->FBBase); + + return TRUE; } -/*---------------------------------------------------------------------------- - * LXPreInit. - * - * Description :This function is called only once ate teh server startup - * - * Parameters. - * pScrni :Handle to ScreenPtr structure. - * options :may be used to check the probeed one with config. - * - * Returns :TRUE on success and FALSE on failure. - * - * Comments :none. - *---------------------------------------------------------------------------- - */ +/* Check to see if VGA exists - we map the space and look for a + signature - if it doesn't match exactly, then we assume no VGA. +*/ + static Bool -LXPreInit(ScrnInfoPtr pScrni, int options) -{ - ClockRangePtr GeodeClockRange; - MessageType from; - int i = 0; - GeodeRec *pGeode; - char *mod = NULL; - xf86MonPtr ddc = NULL; - Q_WORD msrValue; - -#if CFB - char *reqSymbol = NULL; -#endif /* CFB */ - unsigned long offset, length, fb_top; - char dev_name[64], dev_owner[64]; - FILE *fp; - int fd; - -#if INT10_SUPPORT - VESARec *pVesa; -#endif - unsigned int PitchInc, minPitch, maxPitch; - unsigned int minHeight, maxHeight; - unsigned int flags, fmt, high, low; - int tv_encoder, tv_bus_fmt, tv_601_fmt; - int tv_conversion, tvox, tvoy, tv_flags; - int tv_601_flags, tv_vsync_shift, tv_vsync_select; - int tv_vsync_shift_count; - const char *s; - char **modes; - OptionInfoRec *GeodeOptions = &LX_GeodeOptions[0]; +LXCheckVGA(ScrnInfoPtr pScrni) { - /* - * Setup the ClockRanges, which describe what clock ranges are - * available, and what sort of modes they can be used for. - */ - GeodeClockRange = (ClockRangePtr) xnfcalloc(sizeof(ClockRange), 1); - GeodeClockRange->next = NULL; - GeodeClockRange->minClock = 25175; - GeodeClockRange->maxClock = 341350; - GeodeClockRange->clockIndex = -1; /* programmable */ - GeodeClockRange->interlaceAllowed = TRUE; - GeodeClockRange->doubleScanAllowed = FALSE; /* XXX check this */ - - /* Select valid modes from those available */ - minPitch = 1024; - maxPitch = 8192; /* Can support upto 1920x1440 32Bpp */ - minHeight = 400; - maxHeight = 2048; /* Can support upto 1920x1440 32Bpp */ - /* need height >= maxWidth for rotate */ - - DEBUGMSG(1, (0, X_INFO, "LXPreInit!\n")); - /* Allocate driver private structure */ - if (!(pGeode = LXGetRec(pScrni))) - return FALSE; - - DEBUGMSG(1, (0, X_NONE, "pGeode = %p\n", (void *)pGeode)); - - /* This is the general case */ - for (i = 0; i < pScrni->numEntities; i++) { - pGeode->pEnt = xf86GetEntityInfo(pScrni->entityList[i]); - if (pGeode->pEnt->resources) - return FALSE; - pGeode->Chipset = pGeode->pEnt->chipset; - pScrni->chipset = (char *)xf86TokenToString(GeodeChipsets, - pGeode->pEnt->chipset); - } + char bfr[19]; - if ((options & PROBE_DETECT) != 0) { - ConfiguredMonitor = LXProbeDDC(pScrni, pGeode->pEnt->index); - return TRUE; - } -#if INT10_SUPPORT - if (!xf86LoadSubModule(pScrni, "int10")) - return FALSE; - xf86LoaderReqSymLists(amdInt10Symbols, NULL); -#endif + char *vgasig = "IBM VGA Compatible"; + vgaHWPtr pvgaHW = VGAHWPTR(pScrni); + int ret; - /* If the vgahw module would be needed it would be loaded here */ - if (!xf86LoadSubModule(pScrni, "vgahw")) { - return FALSE; - } - xf86LoaderReqSymLists(amdVgahwSymbols, NULL); - /* Do the cimarron hardware detection */ - init_detect_cpu(&pGeode->cpu_version, &pGeode->cpu_revision); + if (!vgaHWMapMem(pScrni)) + return FALSE; - /* find the base chipset core. Currently there can be only one - * chip active at any time. - */ - if ((pGeode->cpu_version & 0xFF) != CIM_CPU_GEODELX) { - ErrorF("Chipset not GEODELX !!!\n"); - return FALSE; - } - pGeode->DetectedChipSet = LX; - DEBUGMSG(1, (0, X_INFO, "Detected BaseChip (%d)\n", - pGeode->DetectedChipSet)); - - /* LX : Can have CRT or PANEL/TVO only */ - msr_read64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msrValue); - - fmt = (msrValue.low >> 3) & 0x07; - switch (fmt) { - case 4: - case 2: - case 0: - flags = LX_OT_CRT; - break; - case 1: - case 3: - case 5: - flags = LX_OT_FP; - if ((msrValue.low & 0x8000) != 0) - flags |= LX_OT_CRT; - break; - case 6: - flags = LX_OT_VOP; - break; - case 7: - flags = LX_OT_DRGB; - break; - } + ret = memcmp(pvgaHW->Base + 0x1E, "IBM VGA Compatible", 18); + memcpy(bfr, pvgaHW->Base + 0x1E, 18); + vgaHWUnmapMem(pScrni); - /* currently supported formats */ - flags &= (LX_OT_FP | LX_OT_CRT | LX_OT_VOP); - /* can switch from crt/pnl vop, but not the other way */ - flags |= LX_OT_VOP; - pGeode->EnabledOutput = flags; + bfr[18] = 0; - xf86DrvMsg(0, X_INFO, "AMD LX Output Formats -%sCRT,%sVOP,%sFP,%sDRGB\n", - ((flags & LX_OT_CRT) ? " " : " No "), - ((flags & LX_OT_VOP) ? " " : " No "), - ((flags & LX_OT_FP) ? " " : " No "), - ((flags & LX_OT_DRGB) ? " " : " No ")); + return ret ? FALSE : TRUE; +} + +static Bool +LXPreInit(ScrnInfoPtr pScrni, int flags) +{ + GeodePtr pGeode; + ClockRangePtr GeodeClockRange; + OptionInfoRec *GeodeOptions = &LX_GeodeOptions[0]; + INIT_BASE_ADDRESSES addr; + int ret; + unsigned long cpuver, cpurev; + QQ_WORD msrValue; + rgb defaultWeight = { 0, 0, 0 }; + int modecnt; + int maj, min; + char *s, *panelgeo = NULL; + char **modes; - pGeode->vid_version = CIM_CPU_GEODELX; - init_read_base_addresses(&(pGeode->InitBaseAddress)); + pGeode = pScrni->driverPrivate = xnfcalloc(sizeof(GeodeRec), 1); - pGeode->FBLinearAddr = pGeode->InitBaseAddress.framebuffer_base; - fb_top = pGeode->InitBaseAddress.framebuffer_size; + if (pGeode == NULL) + return FALSE; - if (pGeode->pEnt->device->videoRam == 0) { - from = X_PROBED; - pScrni->videoRam = fb_top / 1024; - } else { - pScrni->videoRam = pGeode->pEnt->device->videoRam; - from = X_CONFIG; - fb_top = pScrni->videoRam << 10; + /* Probe for VGA */ + pGeode->useVGA = TRUE; + pGeode->VGAActive = FALSE; + + if (xf86LoadSubModule(pScrni, "vgahw")) { + if (vgaHWGetHWRec(pScrni)) { + + pGeode->useVGA = LXCheckVGA(pScrni); + } } - DEBUGMSG(1, (pScrni->scrnIndex, from, "VideoRam: %lu kByte\n", - (unsigned long)pScrni->videoRam)); + pGeode->useVGA = TRUE; - pGeode->CmdBfrOffset = 0; - pGeode->CmdBfrSize = 0; + if (pGeode->useVGA) + pGeode->vesa = xcalloc(sizeof(VESARec), 1); - /* - * Force modules to load now, to reserve fb mem for other drivers - */ + if (pScrni->numEntities != 1) + return FALSE; - pGeode->cimFd = open("/dev/cimarron", O_RDONLY); - if (pGeode->cimFd < 0) - pGeode->cimFd = open("/dev/cim", O_RDONLY); - DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "/dev/cimarron: fd=%d\n", - pGeode->cimFd)); - if ((fd = open("/dev/video", O_RDONLY)) >= 0) - close(fd); - if ((fd = open("/dev/video0", O_RDONLY)) >= 0) - close(fd); - if ((fd = open("/dev/video1", O_RDONLY)) >= 0) - close(fd); - if ((fd = open("/dev/video2", O_RDONLY)) >= 0) - close(fd); - if ((fd = open("/dev/video3", O_RDONLY)) >= 0) - close(fd); - if ((fd = open("/dev/video/video0", O_RDONLY)) >= 0) - close(fd); - if ((fd = open("/dev/video/video1", O_RDONLY)) >= 0) - close(fd); - if ((fd = open("/dev/video/video2", O_RDONLY)) >= 0) - close(fd); - if ((fd = open("/dev/video/video3", O_RDONLY)) >= 0) - close(fd); - - DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "open cim map\n")); - if ((fp = fopen("/proc/driver/cimarron/map", "r")) != NULL) { - low = 0; - high = fb_top; - - DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "scan cim map\n")); - while (fscanf(fp, "%63s %63s %x %lx %lx\n", - &dev_owner[0], &dev_name[0], &flags, &offset, &length) == 5) { - if (offset < pGeode->FBLinearAddr) - continue; - offset -= pGeode->FBLinearAddr; - if ((flags & CIM_F_CMDBUF) != 0) { - pGeode->CmdBfrOffset = offset; - pGeode->CmdBfrSize = length; - } - if (offset >= fb_top) - continue; - if ((flags & CIM_F_PRIVATE) != 0) - if (offset < high) - high = offset; - if (offset + length >= fb_top) - length = fb_top - offset; - if ((flags & CIM_F_PUBLIC) != 0 || (flags & CIM_F_FREE) != 0) - if (offset + length > low) - low = offset + length; - } - fclose(fp); - fb_top = high < low ? high : low; - } + pGeode->pEnt = xf86GetEntityInfo(pScrni->entityList[0]); - DEBUGMSG(1, (0, X_INFO, "fb_top = %08lx\n", fb_top)); - DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, - "cmd bfr (map) %08lx/%08lx\n", pGeode->CmdBfrOffset, - pGeode->CmdBfrSize)); - - /* if cimarron module not reporting, use default buffer parameters */ - if (pGeode->CmdBfrSize == 0) { - if (fb_top < CIM_CMD_BFR_SZ) { - ErrorF("No memory for CMD_BFR !!!\n"); - return FALSE; - } - pGeode->CmdBfrSize = CIM_CMD_BFR_SZ; - fb_top -= pGeode->CmdBfrSize; - pGeode->CmdBfrOffset = fb_top; - } + if (pGeode->pEnt->resources) + return FALSE; - if (pGeode->CmdBfrSize < CIM_CMD_BFR_MIN) { - ErrorF("Not enough memory for CMD_BFR !!!\n"); - return FALSE; - } - DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, - "cmd bfr (actual) %08lx/%08lx\n", pGeode->CmdBfrOffset, - pGeode->CmdBfrSize)); - - /* now soak up all of the usable framebuffer memory */ - if (pGeode->cimFd >= 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "alloc cim map\n")); - for (;;) { - if ((fp = fopen("/proc/driver/cimarron/map", "r")) == NULL) - break; - low = fb_top; - high = 0; - while (fscanf(fp, "%63s %63s %x %lx %lx\n", - &dev_owner[0], &dev_name[0], &flags, &offset, - &length) == 5) { - if (offset < pGeode->FBLinearAddr) - continue; - offset -= pGeode->FBLinearAddr; - if (offset >= fb_top) - continue; - if ((flags & CIM_F_FREE) == 0) - continue; - if (low < offset) - continue; - low = offset; - if (offset + length > fb_top) - length = fb_top - offset; - high = length; - } - fclose(fp); - if (high == 0) - break; - LXFBAlloc(pGeode->cimFd, low, high); - } - DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "check cim map\n")); - /* only shared memory allowed below fb_top */ - if ((fp = fopen("/proc/driver/cimarron/map", "r")) != NULL) { - low = 0; - while (fscanf(fp, "%63s %63s %x %lx %lx\n", - &dev_owner[0], &dev_name[0], &flags, &offset, - &length) == 5) { - if (offset < pGeode->FBLinearAddr) - continue; - offset -= pGeode->FBLinearAddr; - if (offset >= fb_top) - continue; - if ((flags & CIM_F_PUBLIC) == 0) { - low = 1; - break; - } - } - fclose(fp); - if (low != 0) { - ErrorF("Not able to claim free FB memory !!!\n"); - return FALSE; - } - } + if (pGeode->useVGA && (flags & PROBE_DETECT)) { + GeodeProbeDDC(pScrni, pGeode->pEnt->index); + return TRUE; } - pGeode->FBTop = fb_top; - if (fb_top < GP3_SCRATCH_BUFFER_SIZE) { - ErrorF("No available FB memory !!!\n"); - return FALSE; - } + /* Detect the chipset with Cimarron */ - /* must remove cimarron scratch buffer from FB */ - pGeode->FBAvail = fb_top - GP3_SCRATCH_BUFFER_SIZE; - - DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "FBAvail = %08lx\n", - pGeode->FBAvail)); - if (pGeode->DetectedChipSet & LX) { - pGeode->cpu_reg_size = 0x4000; - pGeode->gp_reg_size = 0x4000; - pGeode->vg_reg_size = 0x4000; - pGeode->vid_reg_size = 0x4000; - pGeode->vip_reg_size = 0x4000; - } else { - pGeode->cpu_reg_size = 0x9000; - pGeode->vid_reg_size = 0x1000; - } + init_detect_cpu(&cpuver, &cpurev); + + if (cpuver & 0xFF != CIM_CPU_GEODELX) + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "No Geode LX chipset was detected.\n"); - if (!LXMapMem(pScrni)) - return FALSE; - /* KFB will Knock off VGA */ - /* check if VGA is active */ - pGeode->FBVGAActive = gu3_get_vga_active(); + /* Check the straps to figure out what is attached - these can be changed by + config options */ - DEBUGMSG(1, (0, X_PROBED, "VGA = %d\n", pGeode->FBVGAActive)); + LXGetOutputs(pGeode); - /* Fill in the monitor field */ + /* Fill in the monitor information */ pScrni->monitor = pScrni->confScreen->monitor; - /* Determine depth, bpp, etc. */ + if (!xf86SetDepthBpp(pScrni, 8, 8, 8, Support24bppFb | Support32bppFb)) - return FALSE; - - if (!((pScrni->depth == 8) || (pScrni->depth == 16) || - (pScrni->depth == 24) || (pScrni->depth == 32))) { - DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR, - "Given depth (%d bpp) is not supported by this driver\n", - pScrni->depth)); - return FALSE; - } + return FALSE; - /* - * This must happen after pScrni->display has been set - * because xf86SetWeight references it. - */ - if (pScrni->depth > 8) { - /* The defaults are OK for us */ - rgb BitsPerComponent = { 0, 0, 0 }; - rgb BitMask = { 0, 0, 0 }; - - if (pScrni->depth > 16) { - /* we are operating in 24 bpp, Redcloud */ - BitsPerComponent.red = 8; - BitsPerComponent.green = 8; - BitsPerComponent.blue = 8; - - BitMask.red = 0xFF0000; - BitMask.green = 0x00FF00; - BitMask.blue = 0x0000FF; - } - if (xf86SetWeight(pScrni, BitsPerComponent, BitMask) == 0) - return FALSE; + switch (pScrni->depth) { + case 8: + pScrni->rgbBits = 8; + case 16: + case 24: + case 32: + break; + default: + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "The driver does not support %d as a depth.\n", pScrni->depth); + return FALSE; } xf86PrintDepthBpp(pScrni); + if (!xf86SetWeight(pScrni, defaultWeight, defaultWeight)) + return FALSE; + if (!xf86SetDefaultVisual(pScrni, -1)) - return FALSE; + return FALSE; - /* The new cmap layer needs this to be initialized */ - if (pScrni->depth > 1) { - Gamma zeros = { 0.0, 0.0, 0.0 }; + pScrni->progClock = TRUE; + xf86CollectOptions(pScrni, NULL); + xf86ProcessOptions(pScrni->scrnIndex, pScrni->options, GeodeOptions); - if (!xf86SetGamma(pScrni, zeros)) { - return FALSE; - } - } + /* Set up our various options that may get reversed as we go on */ - /* We use a programmable clock */ - pScrni->progClock = TRUE; + pGeode->tryHWCursor = TRUE; + pGeode->tryCompression = TRUE; - /* - * Collect all of the relevant option flags - * (fill in pScrni->options) - */ - xf86CollectOptions(pScrni, NULL); + pGeode->NoAccel = FALSE; - /* Process the options */ - xf86ProcessOptions(pScrni->scrnIndex, pScrni->options, GeodeOptions); + pGeode->NoOfImgBuffers = DEFAULT_IMG_LINE_BUFS; + pGeode->NoOfColorExpandLines = DEFAULT_CLR_LINE_BUFS; + pGeode->exaBfrSz = DEFAULT_EXA_SCRATCH_BFRSZ; -#if INT10_SUPPORT - pVesa = pGeode->vesa; - /* Initialize Vesa record */ + xf86GetOptValBool(GeodeOptions, LX_OPTION_HW_CURSOR, + &pGeode->tryHWCursor); - if ((pVesa->pInt = xf86InitInt10(pGeode->pEnt->index)) == NULL) { - xf86DrvMsg(0, X_ERROR, "Int10 initialization failed.\n"); - return (FALSE); - } -#endif + if (!xf86GetOptValInteger(GeodeOptions, LX_OPTION_FBSIZE, + &(pGeode->FBAvail))) + pGeode->FBAvail = 0; - if (pScrni->depth == 8) { - /* Default to 8 */ - pScrni->rgbBits = 8; - } - from = X_DEFAULT; - - pGeode->FPGeomDstSet = 0; - if ((s = xf86GetOptValString(GeodeOptions, - LX_OPTION_FP_DEST_GEOM)) != NULL) { - char *sp; - int xres = strtoul(s, &sp, 0); - - if (sp != NULL && *sp == 'x') { - int yres = strtoul(sp + 1, &sp, 0); - - if (sp != NULL && *sp == 0) { - if (xres > 0 && xres <= maxPitch && - yres >= minHeight && yres <= maxHeight) { - pGeode->FPGeomDstSet = 1; - pGeode->FPGeomDstX = xres; - pGeode->FPGeomDstY = yres; - } else - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "FP_DEST_GEOM \"%dx%d\" out of range\n", xres, - yres)); - } - } - - if (pGeode->FPGeomDstSet == 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "FP_DEST_GEOM \"%s\" not recognized\n", s)); - return FALSE; - } - pGeode->EnabledOutput |= LX_OT_FP; - } + /* For compatability - allow SWCursor too */ - pGeode->FPGeomActSet = 0; - if ((s = xf86GetOptValString(GeodeOptions, - LX_OPTION_FP_ACTIVE_GEOM)) != NULL) { - char *sp; - int xres = strtoul(s, &sp, 0); - - if (sp != NULL && *sp == 'x') { - int yres = strtoul(sp + 1, &sp, 0); - - if (sp != NULL && *sp == 0) { - if (xres > 0 && xres <= maxPitch && - yres >= minHeight && yres <= maxHeight) { - pGeode->FPGeomActSet = 1; - pGeode->FPGeomActX = xres; - pGeode->FPGeomActY = yres; - } else - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "FP_ACTIVE_GEOM \"%s\" out of range\n", s)); - } - } - if (pGeode->FPGeomActSet == 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "FP_ACTIVE_GEOM \"%s\" not recognized\n", s)); - return FALSE; - } - pGeode->EnabledOutput |= LX_OT_FP; - } + if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_SW_CURSOR, FALSE)) + pGeode->tryHWCursor = FALSE; + + if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_NOCOMPRESSION, FALSE)) + pGeode->tryCompression = FALSE; + + if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_NOACCEL, FALSE)) + pGeode->NoAccel = TRUE; + + pGeode->rotation = RR_Rotate_0; - if ((pGeode->EnabledOutput & LX_OT_FP) != 0) { - if (pGeode->FPGeomDstSet == 0) { - if (lx_panel_configured() == 0) { - ErrorF("Panel configured and enabled but not configured " - "in BIOS !!!\n"); - return FALSE; - } - lx_get_panel_info(&pGeode->FPBiosResX, &pGeode->FPBiosResY); - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "FP Bios panel configuation used\n")); - pGeode->FPGeomDstX = pGeode->FPBiosResX; - pGeode->FPGeomDstY = pGeode->FPBiosResY; - } - if (pGeode->FPGeomActSet == 0) { - pGeode->FPGeomActX = pGeode->FPGeomDstX; - pGeode->FPGeomActY = pGeode->FPGeomDstY; - } - if (pGeode->FPGeomActX > pGeode->FPGeomDstX || - pGeode->FPGeomActY > pGeode->FPGeomDstY) { - ErrorF("FP Geom params Active %dx%d bigger than Dest %dx%d\n", - pGeode->FPGeomActX, pGeode->FPGeomActY, - pGeode->FPGeomDstX, pGeode->FPGeomDstY); - return FALSE; - } - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "FP Geom params Dest %dx%d, Active %dx%d\n", - pGeode->FPGeomDstX, pGeode->FPGeomDstY, - pGeode->FPGeomActX, pGeode->FPGeomActY)); + if ((s = xf86GetOptValString(GeodeOptions, LX_OPTION_ROTATE))) { + + if (!xf86NameCmp(s, "LEFT")) + pGeode->rotation = RR_Rotate_90; + else if (!xf86NameCmp(s, "INVERT")) + pGeode->rotation = RR_Rotate_180; + else if (!xf86NameCmp(s, "CCW")) + pGeode->rotation = RR_Rotate_270; + else + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Invalid rotation %s.\n", s); } - if (xf86IsOptionSet(GeodeOptions, LX_OPTION_FLATPANEL)) { - if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_FLATPANEL, TRUE)) { - if ((pGeode->EnabledOutput & LX_OT_FP) != 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "FlatPanel Selected\n")); - } else - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "FlatPanel Selected, but not available - ignored\n")); - } else { - if ((pGeode->EnabledOutput & LX_OT_FP) != 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "FlatPanel configured, but not enabled\n")); - pGeode->EnabledOutput &= ~LX_OT_FP; - } - } + xf86GetOptValInteger(GeodeOptions, LX_OPTION_EXA_SCRATCH_BFRSZ, + &(pGeode->exaBfrSz)); + + if (pGeode->exaBfrSz <= 0) + pGeode->exaBfrSz = 0; + + if (pGeode->Output & OUTPUT_PANEL) { + if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_NOPANEL, FALSE)) + pGeode->Output &= ~OUTPUT_PANEL; } - /* - * The preferred method is to use the "hw cursor" option as a tri-state - * option, with the default set above. + panelgeo = xf86GetOptValString(GeodeOptions, LX_OPTION_PANEL_GEOMETRY); + + /* Get the panel information - if it is specified on the command line, + * then go with that - otherwise try to determine it by probing the + * BIOS - the BIOS may tell us that the panel doesn't exist, so the + * value of the output bitmask may change */ - pGeode->HWCursor = TRUE; - if (xf86GetOptValBool(GeodeOptions, LX_OPTION_HW_CURSOR, - &pGeode->HWCursor)) { - from = X_CONFIG; - } - /* For compatibility, accept this too (as an override) */ - if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_SW_CURSOR, FALSE)) { - from = X_CONFIG; - pGeode->HWCursor = FALSE; - } - DEBUGMSG(1, (pScrni->scrnIndex, from, "Using %s cursor\n", - pGeode->HWCursor ? "HW" : "SW")); - pGeode->Compression = TRUE; - if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_NOCOMPRESSION, FALSE)) { - pGeode->Compression = FALSE; - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "NoCompression\n")); + if (pGeode->Output & OUTPUT_PANEL) { + if (panelgeo != NULL) + GeodeGetFPGeometry(panelgeo, &pGeode->PanelX, &pGeode->PanelY); + else { + Bool ret = lx_get_panel(&pGeode->PanelX, &pGeode->PanelY); + if (ret == FALSE) + pGeode->Output &= ~OUTPUT_PANEL; + } } - pGeode->NoAccel = FALSE; - if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_NOACCEL, FALSE)) { - pGeode->NoAccel = TRUE; - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "Acceleration disabled\n")); - } + xf86DrvMsg(pScrni->scrnIndex, X_INFO, "LX output options:\n"); + xf86DrvMsg(pScrni->scrnIndex, X_INFO, " CRT: %s\n", + pGeode->Output & OUTPUT_CRT ? "YES" : "NO"); - if (!xf86GetOptValInteger(GeodeOptions, LX_OPTION_OSM_IMG_BUFS, - &(pGeode->NoOfImgBuffers))) - pGeode->NoOfImgBuffers = DEFAULT_IMG_LINE_BUFS; - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "NoOfImgBuffers = %d\n", pGeode->NoOfImgBuffers)); - if (!xf86GetOptValInteger(GeodeOptions, LX_OPTION_OSM_CLR_BUFS, - &(pGeode->NoOfColorExpandLines))) - pGeode->NoOfColorExpandLines = DEFAULT_CLR_LINE_BUFS; - if (pGeode->NoOfColorExpandLines <= 0) - pGeode->NoOfColorExpandLines = 0; - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "NoOfColorExpandLines = %d\n", pGeode->NoOfColorExpandLines)); - - pGeode->CustomMode = FALSE; - if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_CUSTOM_MODE, FALSE)) { - pGeode->CustomMode = TRUE; - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "Custom mode enabled\n")); - } + xf86DrvMsg(pScrni->scrnIndex, X_INFO, " PANEL: %s\n", + pGeode->Output & OUTPUT_PANEL ? "YES" : "NO"); - if (xf86IsOptionSet(GeodeOptions, LX_OPTION_CRTENABLE)) { - if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_CRTENABLE, TRUE)) { - if ((pGeode->EnabledOutput & LX_OT_FP) != 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "CRT Output Selected\n")); - } else - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "CRT Output Selected, but not available " - "- ignored\n")); - } else { - if ((pGeode->EnabledOutput & LX_OT_CRT) != 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "CRT output configured, but not enabled\n")); - pGeode->EnabledOutput &= ~LX_OT_CRT; - } - } - } + /* Set up VGA */ + if (pGeode->useVGA) { + xf86LoaderReqSymLists(amdVgahwSymbols, NULL); - pGeode->TVSupport = FALSE; - if ((s = xf86GetOptValString(GeodeOptions, LX_OPTION_TV_ENCODER)) - != NULL) { - tv_encoder = -1; - if (xf86NameCmp(s, "ADV7171") == 0) - tv_encoder = VG_ENCODER_ADV7171; - else if (xf86NameCmp(s, "SAA7127") == 0) - tv_encoder = VG_ENCODER_SAA7127; - else if (xf86NameCmp(s, "FS454") == 0) - tv_encoder = VG_ENCODER_FS454; - else if (xf86NameCmp(s, "ADV7300") == 0) - tv_encoder = VG_ENCODER_ADV7300; - if (tv_encoder < 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "VOP output configured, but no encoder specified, " - "VOP diabled\n")); - pGeode->EnabledOutput &= ~LX_OT_VOP; - } else - pGeode->TVSupport = TRUE; - pGeode->tv_encoder = tv_encoder; - } + VESARec *pVesa; + + if (!xf86LoadSubModule(pScrni, "int10")) + return FALSE; + + xf86LoaderReqSymLists(amdInt10Symbols, NULL); + + pVesa = pGeode->vesa; - /* If TV Supported then check for TVO support */ - if (pGeode->TVSupport != FALSE) { - tv_bus_fmt = -1; - tv_601_fmt = -1; - if ((s = xf86GetOptValString(GeodeOptions, - LX_OPTION_TV_BUS_FMT)) != NULL) { - if (xf86NameCmp(s, "disabled") == 0) - tv_bus_fmt = VOP_MODE_DISABLED; - else if (xf86NameCmp(s, "vip11") == 0) - tv_bus_fmt = VOP_MODE_VIP11; - else if (xf86NameCmp(s, "ccir656") == 0) - tv_bus_fmt = VOP_MODE_CCIR656; - else if (xf86NameCmp(s, "vip20_8bit") == 0) - tv_bus_fmt = VOP_MODE_VIP20_8BIT; - else if (xf86NameCmp(s, "vip20_16bit") == 0) - tv_bus_fmt = VOP_MODE_VIP20_16BIT; - else if (xf86NameCmp(s, "601_yuv_8bit") == 0) { - tv_601_fmt = VOP_601_YUV_8BIT; - tv_bus_fmt = VOP_MODE_601; - } else if (xf86NameCmp(s, "601_yuv_16bit") == 0) { - tv_601_fmt = VOP_601_YUV_16BIT; - tv_bus_fmt = VOP_MODE_601; - } else if (xf86NameCmp(s, "601_rgb_8_8_8") == 0) { - tv_601_fmt = VOP_601_RGB_8_8_8; - tv_bus_fmt = VOP_MODE_601; - } else if (xf86NameCmp(s, "601_yuv_4_4_4") == 0) { - tv_601_fmt = VOP_601_YUV_4_4_4; - tv_bus_fmt = VOP_MODE_601; - } - } - if (tv_bus_fmt < 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "VOP output configured, but no bus format specified,\n" - "VOP bus format will depend on SD/HD mode\n")); - } - pGeode->tv_bus_fmt = tv_bus_fmt; - pGeode->tv_601_fmt = tv_601_fmt; - tv_flags = 0; - if ((s = xf86GetOptValString(GeodeOptions, - LX_OPTION_TV_FLAGS)) != NULL) { - char *opt, *sp = strdup(s); - - if (sp != NULL) { - for (opt = strtok(sp, ":"); opt != NULL; - opt = strtok(NULL, ":")) { - if (xf86NameCmp(opt, "singlechipcompat") == 0) - tv_flags |= VOP_FLAG_SINGLECHIPCOMPAT; - else if (xf86NameCmp(opt, "extendedsav") == 0) - tv_flags |= VOP_FLAG_EXTENDEDSAV; - else if (xf86NameCmp(opt, "vbi") == 0) - tv_flags |= VOP_FLAG_VBI; - else if (xf86NameCmp(opt, "task") == 0) - tv_flags |= VOP_FLAG_TASK; - else if (xf86NameCmp(opt, "swap_uv") == 0) - tv_flags |= VOP_FLAG_SWAP_UV; - else if (xf86NameCmp(opt, "swap_vbi") == 0) - tv_flags |= VOP_FLAG_SWAP_VBI; - else - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "VOP flag \"%s\" not recognized\n", opt)); - } - free(sp); - } - } - tv_vsync_shift_count = 0; - tv_601_flags = 0; - tv_vsync_shift = VOP_VSYNC_NOSHIFT; - if ((s = xf86GetOptValString(GeodeOptions, - LX_OPTION_TV_601_FLAGS)) != NULL) { - char *opt, *sp = strdup(s); - - if (sp != NULL) { - for (opt = strtok(sp, ":"); opt != NULL; - opt = strtok(NULL, ":")) { - if (xf86NameCmp(opt, "inv_de_pol") == 0) - tv_601_flags |= VOP_601_INVERT_DISPE; - else if (xf86NameCmp(opt, "inv_hs_pol") == 0) - tv_601_flags |= VOP_601_INVERT_HSYNC; - else if (xf86NameCmp(opt, "inv_vs_pol") == 0) - tv_601_flags |= VOP_601_INVERT_VSYNC; - else if (xf86NameCmp(opt, "vsync-4") == 0) - tv_vsync_shift = VOP_VSYNC_EARLIER_BY4; - else if (xf86NameCmp(opt, "vsync-2") == 0) - tv_vsync_shift = VOP_VSYNC_EARLIER_BY2; - else if (xf86NameCmp(opt, "vsync+0") == 0) - tv_vsync_shift = VOP_VSYNC_NOSHIFT; - else if (xf86NameCmp(opt, "vsync+2") == 0) { - tv_vsync_shift = VOP_VSYNC_LATER_BY_X; - tv_vsync_shift_count = 2; - } else if (xf86NameCmp(opt, "vsync+4") == 0) { - tv_vsync_shift = VOP_VSYNC_LATER_BY_X; - tv_vsync_shift_count = 4; - } else - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "VOP 601_flag \"%s\" not recognized\n", opt)); - } - free(sp); - } - } - tv_vsync_select = VOP_MB_SYNCSEL_DISABLED; - if ((s = xf86GetOptValString(GeodeOptions, - LX_OPTION_TV_VSYNC_SELECT)) != NULL) { - char *opt, *sp = strdup(s); - - if (sp != NULL) { - for (opt = strtok(sp, ":"); opt != NULL; - opt = strtok(NULL, ":")) { - if (xf86NameCmp(opt, "disabled") == 0) - tv_vsync_select = VOP_MB_SYNCSEL_DISABLED; - else if (xf86NameCmp(opt, "vg") == 0) - tv_vsync_select = VOP_MB_SYNCSEL_VG; - else if (xf86NameCmp(opt, "vg_inv") == 0) - tv_vsync_select = VOP_MB_SYNCSEL_VG_INV; - else if (xf86NameCmp(opt, "statreg17") == 0) - tv_vsync_select = VOP_MB_SYNCSEL_STATREG17; - else if (xf86NameCmp(opt, "statreg17_inv") == 0) - tv_vsync_select = VOP_MB_SYNCSEL_STATREG17_INV; - else - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "VOP vsync_select \"%s\" not " - "recognized\n", opt)); - } - free(sp); - } - } - pGeode->tv_flags = tv_flags; - pGeode->tv_601_flags = tv_601_flags; - pGeode->tv_vsync_shift = tv_vsync_shift; - pGeode->tv_vsync_shift_count = tv_vsync_shift_count; - pGeode->tv_vsync_select = tv_vsync_select; - tv_conversion = -1; - if ((s = xf86GetOptValString(GeodeOptions, - LX_OPTION_TV_CONVERSION)) != NULL) { - if (xf86NameCmp(s, "cosited") == 0) - tv_conversion = VOP_422MODE_COSITED; - else if (xf86NameCmp(s, "interspersed") == 0) - tv_conversion = VOP_422MODE_INTERSPERSED; - else if (xf86NameCmp(s, "alternating") == 0) - tv_conversion = VOP_422MODE_ALTERNATING; - else { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "VOP conversion \"%s\" not recognized\n", s)); - } - } - if (tv_conversion < 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "VOP output configured, but no conversion specified,\n" - "VOP conversion will defaults to \"cosited\"\n")); - tv_conversion = VOP_422MODE_COSITED; - } - pGeode->tv_conversion = tv_conversion; - tvox = tvoy = 0; - if ((s = xf86GetOptValString(GeodeOptions, - LX_OPTION_TV_OVERSCAN)) != NULL) { - char *opt, *sp = strdup(s); - - if (sp != NULL) { - if ((opt = strtok(sp, ":")) != NULL) - tvox = strtol(opt, NULL, 0); - if ((opt = strtok(NULL, ":")) != NULL) - tvoy = strtol(opt, NULL, 0); - free(sp); - } - DEBUGMSG(1, (0, X_CONFIG, "TVO %d %d\n", tvox, tvoy)); - } - pGeode->tvox = tvox; - pGeode->tvoy = tvoy; - } else if ((pGeode->EnabledOutput & LX_OT_VOP) != 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "VOP output enabled, but not configured, VOP diabled\n")); - pGeode->EnabledOutput &= ~LX_OT_VOP; + if ((pVesa->pInt = xf86InitInt10(pGeode->pEnt->index)) == NULL) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Unable to initialize 1NT10 support\n"); + pGeode->useVGA = FALSE; + } } - if ((pGeode->EnabledOutput & LX_OT_CRT) != 0) { - ddc = LXProbeDDC(pScrni, pGeode->pEnt->index); - } + init_read_base_addresses(&addr); - flags = pGeode->EnabledOutput; - xf86DrvMsg(0, X_INFO, "AMD LX Active Formats -%sCRT,%sVOP,%sFP,%sDRGB\n", - ((flags & LX_OT_CRT) ? " " : " No "), - ((flags & LX_OT_VOP) ? " " : " No "), - ((flags & LX_OT_FP) ? " " : " No "), - ((flags & LX_OT_DRGB) ? " " : " No ")); + if (pGeode->FBAvail == 0) + pGeode->FBAvail = addr.framebuffer_size; - if ((pGeode->EnabledOutput & (LX_OT_CRT | LX_OT_FP | LX_OT_VOP)) == 0) { - ErrorF("No output enabled !!!\n"); - return FALSE; - } + if (pScrni->memPhysBase == 0) + pScrni->memPhysBase = addr.framebuffer_base; - pGeode->ShadowFB = FALSE; - if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_SHADOW_FB, FALSE)) { - pGeode->ShadowFB = TRUE; - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "Using \"Shadow Framebuffer\"\n")); - } + pScrni->fbOffset = 0; - pGeode->Rotate = 0; - if ((s = xf86GetOptValString(GeodeOptions, LX_OPTION_ROTATE))) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "Rotating - %s\n", s)); - if (!xf86NameCmp(s, "CW")) { - pGeode->Rotate = 1; - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "Rotating screen clockwise\n")); - } else if (!xf86NameCmp(s, "INVERT")) { - pGeode->Rotate = 2; - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "Rotating screen inverted\n")); - } else if (!xf86NameCmp(s, "CCW")) { - pGeode->Rotate = 3; - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "Rotating screen counter clockwise\n")); - } - if (pGeode->Rotate != 0) { - pGeode->ShadowFB = TRUE; - } else { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "\"%s\" is not a valid value for Option \"Rotate\"\n", - s)); - DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, - "Valid options are \"CW\", \"INVERT\", or \"CCW\"\n")); - } + if (pGeode->pEnt->device->videoRam == 0) + pScrni->videoRam = pGeode->FBAvail / 1024; + else { + pScrni->videoRam = pGeode->pEnt->device->videoRam; + pGeode->FBAvail = pScrni->videoRam << 10; } - /* - * This shouldn't happen because such problems should be caught in - * GeodeProbe(), but check it just in case. - */ - if (pScrni->chipset == NULL) { - DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR, - "ChipID 0x%04X is not recognised\n", pGeode->Chipset)); - return FALSE; - } - if (pGeode->Chipset < 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR, - "Chipset \"%s\" is not recognised\n", pScrni->chipset)); - return FALSE; - } + /* Carve out some memory for the command buffer */ - /* - * Init the screen with some values - */ - DEBUGMSG(1, (pScrni->scrnIndex, from, - "Video I/O registers at 0x%08lX\n", - (unsigned long)VGAHW_GET_IOBASE())); + pGeode->CmdBfrSize = CIM_CMD_BFR_SZ; + pGeode->FBAvail -= CIM_CMD_BFR_SZ; - if (pScrni->memPhysBase == 0) { - from = X_PROBED; - pScrni->memPhysBase = pGeode->FBLinearAddr; - } - pScrni->fbOffset = 0; + pGeode->CmdBfrOffset = pGeode->FBAvail; + + pGeode->maxWidth = LX_MAX_WIDTH; + pGeode->maxHeight = LX_MAX_HEIGHT; - DEBUGMSG(1, (pScrni->scrnIndex, from, - "Linear framebuffer at 0x%08lX\n", - (unsigned long)pScrni->memPhysBase)); + GeodeClockRange = (ClockRangePtr) xnfcalloc(sizeof(ClockRange), 1); + GeodeClockRange->next = NULL; + GeodeClockRange->minClock = 25175; + GeodeClockRange->maxClock = 229500; + GeodeClockRange->clockIndex = -1; + GeodeClockRange->interlaceAllowed = TRUE; + GeodeClockRange->doubleScanAllowed = FALSE; - /* - * xf86ValidateModes will check that the mode HTotal and VTotal values - * don't exceed the chipset's limit if pScrni->maxHValue adn - * pScrni->maxVValue are set. Since our LXValidMode() - * already takes care of this, we don't worry about setting them here. - */ - if (pScrni->depth > 16) { - PitchInc = 4096; - } else if (pScrni->depth == 16) { - PitchInc = 2048; - } else { - PitchInc = 1024; - } - PitchInc <<= 3; /* in bits */ + if (pGeode->useVGA && (pGeode->Output & OUTPUT_CRT)) + pScrni->monitor->DDC = GeodeDoDDC(pScrni, pGeode->pEnt->index); + else + pScrni->monitor->DDC = NULL; - /* by default use what user sets in the XF86Config file */ - modes = pScrni->display->modes; + /* I'm still not 100% sure this uses the right values */ - if (ddc != NULL && pScrni->monitor != NULL - && pScrni->monitor->DDC == NULL) { - pScrni->monitor->DDC = ddc; - LXDecodeDDC(pScrni, ddc); - } + modecnt = xf86ValidateModes(pScrni, + pScrni->monitor->Modes, + pScrni->display->modes, + GeodeClockRange, + NULL, LX_MIN_PITCH, LX_MAX_PITCH, + 32, LX_MIN_HEIGHT, LX_MAX_HEIGHT, + pScrni->display->virtualX, + pScrni->display->virtualY, pGeode->FBAvail, LOOKUP_BEST_REFRESH); - i = xf86ValidateModes(pScrni, pScrni->monitor->Modes, modes, - GeodeClockRange, NULL, minPitch, maxPitch, - PitchInc, minHeight, maxHeight, - pScrni->display->virtualX, - pScrni->display->virtualY, pGeode->FBAvail, LOOKUP_BEST_REFRESH); - - DEBUGMSG(1, (pScrni->scrnIndex, from, "xf86ValidateModes:%d %d %d %d\n", - i, pScrni->virtualX, pScrni->virtualY, pScrni->displayWidth)); - if (i == -1) { - LXFreeRec(pScrni); - return FALSE; + if (modecnt <= 0) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes were found\n"); + return FALSE; } - /* Prune the modes marked as invalid */ xf86PruneDriverModes(pScrni); - if (i == 0 || pScrni->modes == NULL) { - DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR, "No valid modes found\n")); - LXFreeRec(pScrni); - return FALSE; + if (pScrni->modes == NULL) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes were found\n"); + return FALSE; } xf86SetCrtcForModes(pScrni, 0); - - /* Set the current mode to the first in the list */ pScrni->currentMode = pScrni->modes; - /* Print the list of modes being used */ xf86PrintModes(pScrni); - - /* Set the display resolution */ xf86SetDpi(pScrni, 0, 0); - /* Load bpp-specific modules */ - mod = NULL; - -#if CFB - /* Load bpp-specific modules */ - switch (pScrni->bitsPerPixel) { - case 8: - mod = "cfb"; - reqSymbol = "cfbScreenInit"; - break; - case 16: - mod = "cfb16"; - reqSymbol = "cfb16ScreenInit"; - break; - case 24: - mod = "cfb24"; - reqSymbol = "cfb24ScreenInit"; - break; - case 32: - mod = "cfb32"; - reqSymbol = "cfb32ScreenInit"; - break; - default: - return FALSE; - } - if (mod && xf86LoadSubModule(pScrni, mod) == NULL) { - LXFreeRec(pScrni); - return FALSE; - } + /* Load the modules we'll need */ - xf86LoaderReqSymbols(reqSymbol, NULL); -#else if (xf86LoadSubModule(pScrni, "fb") == NULL) { - LXFreeRec(pScrni); - return FALSE; + return FALSE; } xf86LoaderReqSymLists(amdFbSymbols, NULL); -#endif - if (pGeode->NoAccel == FALSE) { - if (!xf86LoadSubModule(pScrni, "xaa")) { - LXFreeRec(pScrni); - return FALSE; - } - xf86LoaderReqSymLists(amdXaaSymbols, NULL); - } - if (pGeode->HWCursor == TRUE) { - if (!xf86LoadSubModule(pScrni, "ramdac")) { - LXFreeRec(pScrni); - return FALSE; - } - xf86LoaderReqSymLists(amdRamdacSymbols, NULL); + + if (!pGeode->NoAccel) { + if (!xf86LoadSubModule(pScrni, "exa")) + return FALSE; + + xf86LoaderReqSymLists(&amdExaSymbols[0], NULL); } - /* Load shadowfb if needed */ - if (pGeode->ShadowFB) { - if (!xf86LoadSubModule(pScrni, "shadowfb")) { - LXFreeRec(pScrni); - return FALSE; - } - xf86LoaderReqSymLists(amdShadowSymbols, NULL); + + if (pGeode->tryHWCursor == TRUE) { + if (!xf86LoadSubModule(pScrni, "ramdac")) { + return FALSE; + } + + xf86LoaderReqSymLists(amdRamdacSymbols, NULL); } + if (xf86RegisterResources(pGeode->pEnt->index, NULL, ResExclusive)) { - DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR, - "xf86RegisterResources() found resource conflicts\n")); - LXFreeRec(pScrni); - return FALSE; + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Couldn't register the resources.\n"); + return FALSE; } - LXUnmapMem(pScrni); return TRUE; } -/*---------------------------------------------------------------------------- - * LXRestore. - * - * Description :This function restores the mode that was saved on server - entry - * Parameters. - * pScrni :Handle to ScreenPtr structure. - * Pmode :poits to screen mode - * - * Returns :none. - * - * Comments :none. -*---------------------------------------------------------------------------- -*/ static void LXRestore(ScrnInfoPtr pScrni) { GeodeRec *pGeode = GEODEPTR(pScrni); - DEBUGMSG(0, (0, X_INFO, "LXRestore\n")); - - if (pGeode->FBVGAActive) { - vgaHWPtr pvgaHW = VGAHWPTR(pScrni); - - vgaHWProtect(pScrni, TRUE); - vgaHWRestore(pScrni, &pvgaHW->SavedReg, VGA_SR_ALL); - vgaHWProtect(pScrni, FALSE); - } -} - -/*---------------------------------------------------------------------------- - * LXCalculatePitchBytes. - * - * Description :This function restores the mode that was saved on server - * - * Parameters. - * pScrni :Handle to ScreenPtr structure. - * Pmode :Points to screenmode - * - * Returns :none. - * - * Comments :none. -*---------------------------------------------------------------------------- -*/ -static int -LXCalculatePitchBytes(unsigned int width, unsigned int bpp) -{ - int lineDelta = width * (bpp >> 3); - - if (width < 640) { - /* low resolutions have both pixel and line doubling */ - DEBUGMSG(1, (0, X_PROBED, "lower resolution %d %d\n", - width, lineDelta)); - lineDelta <<= 1; - } - /* needed in Rotate mode when in accel is turned off */ - - if (lineDelta > 4096) - lineDelta = 8192; - else if (lineDelta > 2048) - lineDelta = 4096; - else if (lineDelta > 1024) - lineDelta = 2048; - else - lineDelta = 1024; - - DEBUGMSG(0, (0, X_INFO, "pitch %d %d\n", width, lineDelta)); - - return lineDelta; -} - -/*---------------------------------------------------------------------------- - * LXGetRefreshRate. - * - * Description :This function restores the mode that saved on server - * - * Parameters. - * Pmode :Pointer to the screen modes - * - * Returns :It returns the selected refresh rate. - * - * Comments :none. -*---------------------------------------------------------------------------- -*/ -static int -LXGetRefreshRate(DisplayModePtr pMode) -{ -#define THRESHOLD 2 - unsigned int i; - static int validRates[] = { 56, 60, 70, 72, 75, 85, 90, 100 }; /* Hz */ - unsigned long dotClock; - int refreshRate; - int selectedRate; - - dotClock = pMode->SynthClock * 1000; - refreshRate = dotClock / (pMode->CrtcHTotal * pMode->CrtcVTotal); - - if ((pMode->CrtcHTotal < 640) && (pMode->CrtcVTotal < 480)) - refreshRate >>= 2; /* double pixel and double scan */ - - DEBUGMSG(0, (0, X_INFO, "dotclock %lu %d\n", dotClock, refreshRate)); + if (pGeode->useVGA) { + vgaHWPtr pvgaHW = VGAHWPTR(pScrni); - selectedRate = validRates[0]; - - for (i = 0; i < (sizeof(validRates) / sizeof(validRates[0])); i++) { - if (validRates[i] < (refreshRate + THRESHOLD)) { - selectedRate = validRates[i]; - } + vgaHWProtect(pScrni, TRUE); + vgaHWRestore(pScrni, &pvgaHW->SavedReg, VGA_SR_ALL); + vgaHWProtect(pScrni, FALSE); } - - return selectedRate; } -void -lx_clear_screen(ScrnInfoPtr pScrni, int width, int height, int bpp) +static Bool +LXUnmapMem(ScrnInfoPtr pScrni) { - /* no accels, mode is not yet set */ GeodeRec *pGeode = GEODEPTR(pScrni); - unsigned long offset = vg_get_display_offset(); - unsigned long pitch = vg_get_display_pitch(); - unsigned long n = width * ((bpp + 7) >> 3); - - DEBUGMSG(0, (0, X_INFO, "clear screen %lx %d %d %d %lu %lu\n", offset, - width, height, bpp, pitch, n)); - while (height > 0) { - memset(pGeode->FBBase + offset, 0, n); - offset += pitch; - --height; - } -} + + xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_gp_ptr, LX_GP_REG_SIZE); + xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_vg_ptr, LX_VG_REG_SIZE); + xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_vid_ptr, LX_VID_REG_SIZE); + xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_vip_ptr, LX_VIP_REG_SIZE); -void -lx_clear_fb(ScrnInfoPtr pScrni) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - unsigned char *fb = pGeode->FBBase + pGeode->FBOffset; + xf86UnMapVidMem(pScrni->scrnIndex, cim_fb_ptr, pGeode->FBAvail); - memset(fb, 0, pGeode->FBSize); - if (pGeode->ShadowPtr != NULL && pGeode->ShadowPtr != fb) - memset(pGeode->ShadowPtr, 0, pGeode->ShadowSize); + return TRUE; } -static int -lx_set_tv_mode(ScrnInfoPtr pScrni, int tv_mode) +/* These should be correctly accounted for rotation */ + +static void +LXAdjustFrame(int scrnIndex, int x, int y, int flags) { - int ret, bpp, flags; - int tv_conversion, tv_bus_fmt, tv_flags; - int tv_601_fmt, tv_601_flags; - int tv_vsync_shift, tv_vsync_shift_count, tv_vsync_select; - unsigned long src_width, src_height; - char *bp, *cp, *dp; + ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; GeodeRec *pGeode = GEODEPTR(pScrni); - VOPCONFIGURATIONBUFFER vopc; - - bpp = pScrni->bitsPerPixel; - if (bpp == 32) - bpp = 24; - flags = lx_tv_mode_interlaced(tv_mode) != 0 ? VG_MODEFLAG_INTERLACED : 0; - src_width = src_height = 0; - ret = vg_set_tv_mode(&src_width, &src_height, - pGeode->tv_encoder, tv_mode, bpp, flags, 0, 0); - DEBUGMSG(1, (0, X_INFO, - "Setting TV mode %lux%lu encoder=%d,bpp=%d,flags=%d,overscan " - "%d,%d\n", src_width, src_height, pGeode->tv_encoder, bpp, - flags, pGeode->tvox, pGeode->tvoy)); - ret = vg_set_tv_mode(&src_width, &src_height, - pGeode->tv_encoder, tv_mode, bpp, flags, pGeode->tvox, pGeode->tvoy); - - DEBUGMSG(1, (0, X_INFO, "Set TV mode ret=%d\n", ret)); - if (ret == 0) { - memset(&vopc, 0, sizeof(vopc)); - tv_flags = pGeode->tv_flags; - tv_bus_fmt = pGeode->tv_bus_fmt; - tv_601_fmt = pGeode->tv_601_fmt; - tv_601_flags = pGeode->tv_601_flags; - tv_vsync_shift = pGeode->tv_vsync_shift; - tv_vsync_shift_count = pGeode->tv_vsync_shift_count; - tv_vsync_select = pGeode->tv_vsync_select; - tv_conversion = pGeode->tv_conversion; - if (tv_bus_fmt < 0) { - dp = "defaults"; - switch (tv_mode) { - case VG_TVMODE_NTSC: - case VG_TVMODE_6X4_NTSC: - case VG_TVMODE_8X6_NTSC: - case VG_TVMODE_10X7_NTSC: - case VG_TVMODE_PAL: - case VG_TVMODE_6X4_PAL: - case VG_TVMODE_8X6_PAL: - case VG_TVMODE_10X7_PAL: - tv_bus_fmt = VOP_MODE_VIP11; - break; - default: - tv_bus_fmt = VOP_MODE_VIP20_16BIT; - break; - } - } else - dp = "set"; - switch (tv_bus_fmt) { - case VOP_MODE_VIP11: - bp = "vop11"; - break; - case VOP_MODE_CCIR656: - bp = "ccir656"; - break; - case VOP_MODE_VIP20_8BIT: - bp = "vip20_8bit"; - break; - case VOP_MODE_VIP20_16BIT: - bp = "vip20_16bit"; - break; - case VOP_MODE_601: - switch (tv_601_fmt) { - default: - tv_601_fmt = VOP_601_YUV_8BIT; - case VOP_601_YUV_8BIT: - bp = "601_yuv_8bit"; - break; - case VOP_601_YUV_16BIT: - bp = "601_yuv_16bit"; - break; - case VOP_601_RGB_8_8_8: - bp = "601_rgb_8_8_8"; - break; - case VOP_601_YUV_4_4_4: - bp = "601_yuv_4_4_4"; - break; - } - break; - default: - tv_bus_fmt = VOP_MODE_DISABLED; - case VOP_MODE_DISABLED: - bp = "disabled"; - break; - } - switch (tv_conversion) { - default: - tv_conversion = VOP_422MODE_COSITED; - case VOP_422MODE_COSITED: - cp = "cosited"; - break; - case VOP_422MODE_INTERSPERSED: - cp = "interspersed"; - break; - case VOP_422MODE_ALTERNATING: - cp = "alternating"; - break; - } - vopc.flags = tv_flags; - vopc.mode = tv_bus_fmt; - vopc.conversion_mode = tv_conversion; - vopc.vsync_out = tv_vsync_select; - vopc.vop601.flags = tv_601_flags; - vopc.vop601.vsync_shift = tv_vsync_shift; - vopc.vop601.vsync_shift_count = tv_vsync_shift_count; - vopc.vop601.output_mode = tv_601_fmt; - DEBUGMSG(1, (0, X_INFO, - "Set TV mode %s to %s, conv %s, flags %x\n", - dp, bp, cp, tv_flags)); - DEBUGMSG(1, (0, X_INFO, - "Set TV 601 mode %x flags %x vsync shift %x/%x\n", - tv_601_fmt, tv_601_flags, tv_vsync_shift, - tv_vsync_shift_count)); - vop_set_configuration(&vopc); - } - return ret; -} + unsigned long offset; + + /* XXX: Is pitch correct here? */ -static int -lx_set_custom_mode(unsigned long bpp, unsigned long flags, - unsigned long hactive, unsigned long hblankstart, - unsigned long hsyncstart, unsigned long hsyncend, - unsigned long hblankend, unsigned long htotal, - unsigned long vactive, unsigned long vblankstart, - unsigned long vsyncstart, unsigned long vsyncend, - unsigned long vblankend, unsigned long vtotal, unsigned long frequency) -{ - VG_DISPLAY_MODE mode; - - memset(&mode, 0, sizeof(mode)); - mode.flags = flags; - mode.src_width = hactive; - mode.src_height = vactive; - mode.mode_width = hactive; - mode.mode_height = vactive; - mode.hactive = hactive; - mode.hblankstart = hblankstart; - mode.hsyncstart = hsyncstart; - mode.hsyncend = hsyncend; - mode.hblankend = hblankend; - mode.htotal = htotal; - mode.vactive = vactive; - mode.vblankstart = vblankstart; - mode.vsyncstart = vsyncstart; - mode.vsyncend = vsyncend; - mode.vblankend = vblankend; - mode.vtotal = vtotal; - mode.vactive_even = vactive; - mode.vblankstart_even = vblankstart; - mode.vsyncstart_even = vsyncstart; - mode.vsyncend_even = vsyncend; - mode.vblankend_even = vblankend; - mode.vtotal_even = vtotal; - mode.frequency = frequency; - - return vg_set_custom_mode(&mode, bpp); + offset = pGeode->FBOffset + (y * pGeode->Pitch); + offset += x * (pScrni->bitsPerPixel >> 3); + + vg_set_display_offset(offset); } -/*---------------------------------------------------------------------------- - * LXSetMode. - * - * Description :This function sets parametrs for screen mode - * - * Parameters. - * pScrni :Pointer to the screenInfo structure. - * Pmode :Pointer to the screen modes - * - * Returns :TRUE on success and FALSE on Failure. - * - * Comments :none. -*---------------------------------------------------------------------------- -*/ - static Bool -LXSetMode(ScrnInfoPtr pScrni, DisplayModePtr pMode) +LXSetVideoMode(ScrnInfoPtr pScrni, DisplayModePtr pMode) { - int bpp, bppx, rate, video_enable, tv_mode, opath; - unsigned long flags, srcw, srch, actw, acth, dstw, dsth, video_flags; - GeodeRec *pGeode = GEODEPTR(pScrni); DF_VIDEO_SOURCE_PARAMS vs_odd, vs_even; + int flags = 0; + int video_enable; + unsigned long video_flags; - gp_wait_until_idle(); - /* disable video */ df_get_video_enable(&video_enable, &video_flags); + if (video_enable != 0) df_set_video_enable(0, 0); + df_get_video_source_configuration(&vs_odd, &vs_even); lx_disable_dac_power(pScrni, DF_CRT_DISABLE); + vg_set_compression_enable(0); - DEBUGMSG(1, (0, X_NONE, "LXSetMode! %p %p %p\n", - cim_gp_ptr, cim_vid_ptr, cim_fb_ptr)); - - /* Set the VT semaphore */ - pScrni->vtSema = TRUE; - - srcw = pMode->CrtcHDisplay; - srch = pMode->CrtcVDisplay; - bpp = pScrni->bitsPerPixel; - rate = LXGetRefreshRate(pMode); - /* otherwise color/chroma keying doesnt work */ - bppx = bpp == 32 ? 24 : bpp; - - /* The timing will be adjusted later */ - DEBUGMSG(1, (0, X_PROBED, - "Setting mode %dx%d %0.3f %d %d %d %d %d %d %d %d\n", - pMode->CrtcHDisplay, pMode->CrtcVDisplay, - pMode->SynthClock / 1000.0, pMode->CrtcHDisplay, - pMode->CrtcHSyncStart, pMode->CrtcHSyncEnd, pMode->CrtcHTotal, - pMode->CrtcVDisplay, pMode->CrtcVSyncStart, pMode->CrtcVSyncEnd, - pMode->CrtcVTotal)); - DEBUGMSG(1, (0, X_INFO, - "Set display mode: %lux%lu-%d (%dHz) Pitch %d/%d\n", srcw, srch, - bpp, rate, pGeode->Pitch, pGeode->AccelPitch)); - - opath = DF_DISPLAY_CRT; - if ((pGeode->EnabledOutput & LX_OT_FP) != 0) { - if ((pGeode->EnabledOutput & LX_OT_CRT) != 0) - opath = DF_DISPLAY_CRT_FP; - else - opath = DF_DISPLAY_FP; - } - - if (pGeode->TVSupport && (tv_mode = lx_tv_mode(pMode)) >= 0) { - DEBUGMSG(1, (0, X_INFO, "Set TV mode %d\n", tv_mode)); - lx_set_tv_mode(pScrni, tv_mode); - opath = DF_DISPLAY_VOP; - } else if (pGeode->CustomMode != 0) { - DEBUGMSG(1, (0, X_PROBED, "Setting Custom mode\n")); - flags = 0; - if ((pMode->Flags & V_NHSYNC) != 0) - flags |= VG_MODEFLAG_NEG_HSYNC; - if ((pMode->Flags & V_NVSYNC) != 0) - flags |= VG_MODEFLAG_NEG_VSYNC; - lx_set_custom_mode(bppx, flags, pMode->CrtcHDisplay, - pMode->CrtcHBlankStart, pMode->CrtcHSyncStart, - pMode->CrtcHSyncEnd, pMode->CrtcHBlankEnd, - pMode->CrtcHTotal, pMode->CrtcVDisplay, - pMode->CrtcVBlankStart, pMode->CrtcVSyncStart, - pMode->CrtcVSyncEnd, pMode->CrtcVBlankEnd, - pMode->CrtcVTotal, (int)((pMode->SynthClock / 1000.0) * 0x10000)); - } else if ((pGeode->EnabledOutput & LX_OT_FP) != 0) { - /* display is fp */ - actw = pGeode->FPGeomActX; - dstw = pGeode->FPGeomDstX; - acth = pGeode->FPGeomActY; - dsth = pGeode->FPGeomDstY; - flags = (pGeode->EnabledOutput & LX_OT_CRT) != - 0 ? VG_MODEFLAG_CRT_AND_FP : 0; - /* cant do scaling if width > 1024 (hw bfr size limitation) */ - if (srcw > 1024) { - if (srcw != actw) - DEBUGMSG(1, (0, X_PROBED, - "FPGeomSrcX > 1024, scaling disabled\n")); - actw = srcw; - acth = srch; - vg_set_border_color(0); - } - DEBUGMSG(1, (0, X_PROBED, - "Setting Display for TFT %lux%lu %lux%lu %lux%lu %d\n", srcw, - srch, actw, acth, dstw, dsth, pScrni->bitsPerPixel)); - vg_set_panel_mode(srcw, srch, actw, acth, dstw, dsth, bppx, flags); - } else { - /* display is crt */ - DEBUGMSG(1, (0, X_PROBED, "Setting Display for CRT %lux%lu-%d@%d\n", - srcw, srch, bppx, LXGetRefreshRate(pMode))); - vg_set_display_mode(srcw, srch, srcw, srch, bppx, - LXGetRefreshRate(pMode), 0); - } - - df_set_output_path(opath); + if (!pMode->type || pMode->type == M_T_USERDEF) + lx_set_custom_mode(pGeode, pMode, pScrni->bitsPerPixel); + else { + if (pMode->Flags & V_NHSYNC) + flags |= VG_MODEFLAG_NEG_HSYNC; + if (pMode->Flags & V_NVSYNC) + flags |= VG_MODEFLAG_NEG_VSYNC; + + if (pGeode->Output & OUTPUT_PANEL) { + int activex = pGeode->PanelX; + int activey = pGeode->PanelY; + + flags = pGeode->Output & OUTPUT_CRT ? VG_MODEFLAG_CRT_AND_FP : 0; + + if (pMode->CrtcHDisplay > 1024 && + pMode->CrtcHDisplay != pGeode->PanelX) { + ErrorF("The source is greater then 1024 - scaling is disabled.\n"); + activex = pMode->CrtcHDisplay; + activey = pMode->CrtcVDisplay; + + vg_set_border_color(0); + } + + vg_set_panel_mode(pMode->CrtcHDisplay, pMode->CrtcVDisplay, + activex, activey, activex, activey, + pScrni->bitsPerPixel, flags); + } + else { + vg_set_display_mode(pMode->CrtcHDisplay, pMode->CrtcVDisplay, + pMode->CrtcHDisplay, pMode->CrtcVDisplay, + pScrni->bitsPerPixel, GeodeGetRefreshRate(pMode), + 0); + } + } + + if (pGeode->Output & OUTPUT_PANEL) + df_set_output_path((pGeode->Output & OUTPUT_CRT) ? DF_DISPLAY_CRT_FP : DF_DISPLAY_FP); + else + df_set_output_path(DF_DISPLAY_CRT); + vg_set_display_pitch(pGeode->Pitch); gp_set_bpp(pScrni->bitsPerPixel); - - vg_set_display_offset(0L); + + vg_set_display_offset(0); vg_wait_vertical_blank(); - DEBUGMSG(1, (0, X_PROBED, "Display mode set\n")); - /* enable compression if option selected */ - if (pGeode->Compression != 0) { - DEBUGMSG(1, (0, X_PROBED, "Compression mode set %d\n", - pGeode->Compression)); - /* set the compression parameters,and it will be turned on later. */ - vg_configure_compression(&(pGeode->CBData)); - - /* set the compression buffer, all parameters already set */ - vg_set_compression_enable(1); + if (pGeode->Compression) { + vg_configure_compression(&(pGeode->CBData)); + vg_set_compression_enable(1); } - if (pGeode->HWCursor != 0) { - VG_PANNING_COORDINATES panning; + if (pGeode->HWCursor && !(pMode->Flags & V_DBLSCAN)) { + VG_PANNING_COORDINATES panning; - /* Load blank cursor */ - LXLoadCursorImage(pScrni, NULL); - vg_set_cursor_position(0, 0, &panning); - LXShowCursor(pScrni); + LXLoadCursorImage(pScrni, NULL); + vg_set_cursor_position(0, 0, &panning); + LXShowCursor(pScrni); + } else { + vg_set_cursor_enable(0); + pGeode->HWCursor = FALSE; } - DEBUGMSG(1, (0, X_INFO, "setting mode done.\n")); - - vg_set_display_offset(pGeode->PrevDisplayOffset); - - /* Restore the contents in the screen info */ - DEBUGMSG(1, (0, X_INFO, "After setting the mode\n")); - switch (pGeode->Rotate) { - case 1: - case 3: - pGeode->HDisplay = pMode->VDisplay; - pGeode->VDisplay = pMode->HDisplay; - break; - default: - pGeode->HDisplay = pMode->HDisplay; - pGeode->VDisplay = pMode->VDisplay; - break; - } + LXAdjustFrame(pScrni->scrnIndex, pScrni->frameX0, pScrni->frameY0, 0); df_configure_video_source(&vs_odd, &vs_even); + if (video_enable != 0) - df_set_video_enable(video_enable, video_flags); + df_set_video_enable(video_enable, video_flags); + lx_enable_dac_power(pScrni, 1); return TRUE; } -/*---------------------------------------------------------------------------- - * LXEnterGraphics. - * - * Description :This function will intiallize the displaytiming - structure for nextmode and switch to VGA mode. - * - * Parameters. - * pScrn :Screen information will be stored in this structure. - * pScrni :Pointer to the screenInfo structure. - * - * Returns :TRUE on success and FALSE on Failure. - * - * Comments :gfx_vga_mode_switch() will start and end the - * switching based on the arguments 0 or 1.soft_vga - * is disabled in this function. -*---------------------------------------------------------------------------- -*/ static Bool -LXEnterGraphics(ScreenPtr pScrn, ScrnInfoPtr pScrni) +LXSwitchMode(int index, DisplayModePtr pMode, int flags) { - int bpp; - unsigned long cmd_bfr_phys; + ScrnInfoPtr pScrni = xf86Screens[index]; GeodeRec *pGeode = GEODEPTR(pScrni); - vgaHWPtr pvgaHW = VGAHWPTR(pScrni); - - DEBUGMSG(1, (0, X_INFO, "LXEnterGraphics.\n")); + int ret = TRUE; + int rotate; + /* Syn the engine and shutdown the DAC momentarily */ gp_wait_until_idle(); - cmd_bfr_phys = - pGeode->InitBaseAddress.framebuffer_base + pGeode->CmdBfrOffset; - cim_cmd_base_ptr = cim_fb_ptr + pGeode->CmdBfrOffset; - gp_set_frame_buffer_base(pGeode->InitBaseAddress.framebuffer_base, - pGeode->FBTop); - gp_set_command_buffer_base(cmd_bfr_phys, 0, pGeode->CmdBfrSize); - lx_disable_dac_power(pScrni, DF_CRT_DISABLE); - /* Save CRT State */ - vg_get_current_display_mode(&pGeode->FBcimdisplaytiming.vgDisplayMode, - &bpp); - - pGeode->FBcimdisplaytiming.wBpp = bpp; - pGeode->FBcimdisplaytiming.wPitch = vg_get_display_pitch(); - - /* Save Display offset */ - pGeode->FBDisplayOffset = vg_get_display_offset(); - pGeode->FBBIOSMode = pvgaHW->readCrtc(pvgaHW, 0x040); - DEBUGMSG(1, (0, X_INFO, "FBBIOSMode %d\n", pGeode->FBBIOSMode)); - - /* Save the current Compression state */ - pGeode->FBCompressionEnable = vg_get_compression_enable(); - - vg_get_compression_info(&(pGeode->FBCBData)); - - /* Save Cursor offset */ - vg_get_cursor_info(&pGeode->FBCursor); - - /* only if comming from VGA */ - if (pGeode->FBVGAActive) { - unsigned short sequencer; - vgaHWPtr pvgaHW = VGAHWPTR(pScrni); - - /* Map VGA aperture */ - if (!vgaHWMapMem(pScrni)) - return FALSE; - - /* Unlock VGA registers */ - vgaHWUnlock(pvgaHW); + /* Set up the memory for the new mode */ + rotate = LXGetRotation(pScrni->pScreen); + ret = LXAllocateMemory(pScrni->pScreen, pScrni, rotate); - /* Save the current state and setup the current mode */ - vgaHWSave(pScrni, &VGAHWPTR(pScrni)->SavedReg, VGA_SR_ALL); - - /* DISABLE VGA SEQUENCER */ - /* This allows the VGA state machine to terminate. We must delay */ - /* such that there are no pending MBUS requests. */ - - cim_outb(DC3_SEQUENCER_INDEX, DC3_SEQUENCER_CLK_MODE); - sequencer = cim_inb(DC3_SEQUENCER_DATA); - sequencer |= DC3_CLK_MODE_SCREEN_OFF; - cim_outb(DC3_SEQUENCER_DATA, sequencer); - - vg_delay_milliseconds(1); - - /* BLANK THE VGA DISPLAY */ - cim_outw(DC3_SEQUENCER_INDEX, DC3_SEQUENCER_RESET); - sequencer = cim_inb(DC3_SEQUENCER_DATA); - sequencer &= ~DC3_RESET_VGA_DISP_ENABLE; - cim_outb(DC3_SEQUENCER_DATA, sequencer); - - vg_delay_milliseconds(1); + if (ret) { + if (pGeode->curMode != pMode) + ret = LXSetVideoMode(pScrni, pMode); } - lx_clear_fb(pScrni); - - if (!LXSetMode(pScrni, pScrni->currentMode)) { - return FALSE; - } - - lx_enable_dac_power(pScrni, 1); - return TRUE; -} - -void -lx_disable_dac_power(ScrnInfoPtr pScrni, int option) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); + if (ret) + ret = LXRotate(pScrni, pMode); - if ((pGeode->EnabledOutput & LX_OT_FP) != 0) - df_set_panel_enable(0); - if ((pGeode->EnabledOutput & LX_OT_CRT) != 0) { - if ((pGeode->EnabledOutput & LX_OT_FP) != 0) - /* wait for the panel to be fully powered off */ - while ((READ_VID32(DF_POWER_MANAGEMENT) & 2) == 0) ; - df_set_crt_enable(option); - } -} + /* Go back the way it was */ -void -lx_enable_dac_power(ScrnInfoPtr pScrni, int option) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); + if (ret == FALSE) { + if (!LXSetVideoMode(pScrni, pGeode->curMode)) + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Could not restore the previous mode\n"); + } else + pGeode->curMode = pMode; - df_set_crt_enable(DF_CRT_ENABLE); - if (option != 0 && (pGeode->EnabledOutput & LX_OT_CRT) == 0) { - unsigned int misc = READ_VID32(DF_VID_MISC); - - misc |= DF_DAC_POWER_DOWN; - WRITE_VID32(DF_VID_MISC, misc); - } - if ((pGeode->EnabledOutput & LX_OT_FP) != 0) - df_set_panel_enable(1); + return ret; } -/*---------------------------------------------------------------------------- - * LXLeaveGraphics: - * - * Description :This function will restore the displaymode parameters - * and switches the VGA mode - * - * Parameters. - * pScrni :Pointer to the screenInfo structure. - * - * Returns :none. -*---------------------------------------------------------------------------- -*/ static void LXLeaveGraphics(ScrnInfoPtr pScrni) { - GeodeRec *pGeode = GEODEPTR(pScrni); - VG_PANNING_COORDINATES panning; - - gp_wait_until_idle(); - - /* Restore VG registers */ - lx_disable_dac_power(pScrni, DF_CRT_DISABLE); - vg_set_custom_mode(&(pGeode->FBcimdisplaytiming.vgDisplayMode), - pGeode->FBcimdisplaytiming.wBpp); - - vg_set_compression_enable(0); - - /* Restore the previous Compression state */ - if (pGeode->FBCompressionEnable) { - vg_configure_compression(&(pGeode->FBCBData)); - vg_set_compression_enable(1); - } - - vg_set_display_pitch(pGeode->FBcimdisplaytiming.wPitch); - vg_set_display_offset(pGeode->FBDisplayOffset); - - /* Restore Cursor */ - vg_set_cursor_position(pGeode->FBCursor.cursor_x, - pGeode->FBCursor.cursor_y, &panning); - - /* For the moment, always do an int 10 */ - -#if INT10_SUPPORT + GeodeRec *pGeode = GEODEPTR(pScrni); + VG_PANNING_COORDINATES panning; + + gp_wait_until_idle(); + + lx_disable_dac_power(pScrni, DF_CRT_DISABLE); + + vg_set_custom_mode(&(pGeode->FBcimdisplaytiming.vgDisplayMode), + pGeode->FBcimdisplaytiming.wBpp); + + vg_set_compression_enable(0); + + /* Restore the previous Compression state */ + if (pGeode->FBCompressionEnable) { + vg_configure_compression(&(pGeode->FBCBData)); + vg_set_compression_enable(1); + } + + vg_set_display_pitch(pGeode->FBcimdisplaytiming.wPitch); + vg_set_display_offset(pGeode->FBDisplayOffset); + + /* Restore Cursor */ + vg_set_cursor_position(pGeode->FBCursor.cursor_x, + pGeode->FBCursor.cursor_y, &panning); + + + if (pGeode->useVGA && pGeode->VGAActive) { pGeode->vesa->pInt->num = 0x10; pGeode->vesa->pInt->ax = 0x0 | pGeode->FBBIOSMode; pGeode->vesa->pInt->bx = 0; xf86ExecX86int10(pGeode->vesa->pInt); -#endif vg_delay_milliseconds(3); - LXRestore(pScrni); - - lx_enable_dac_power(pScrni, 0); + } + + LXRestore(pScrni); + lx_enable_dac_power(pScrni, 1); + pScrni->vtSema = FALSE; } -/*---------------------------------------------------------------------------- - * LXCloseScreen. - * - * Description :This function will restore the original mode - * and also it unmap video memory - * - * Parameters. - * ScrnIndex :Screen index value of the screen will be closed. - * pScrn :Pointer to the screen structure. - * - * - * Returns :TRUE on success and FALSE on Failure. - * - * Comments :none. -*---------------------------------------------------------------------------- -*/ static Bool LXCloseScreen(int scrnIndex, ScreenPtr pScrn) { ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; GeodeRec *pGeode = GEODEPTR(pScrni); - if (pGeode->ShadowPtr && !pGeode->ShadowInFBMem) - xfree(pGeode->ShadowPtr); + if (pScrni->vtSema) + LXLeaveGraphics(pScrni); - DEBUGMSG(1, (scrnIndex, X_PROBED, "LXCloseScreen %d\n", pScrni->vtSema)); + if (pGeode->pExa) { + exaDriverFini(pScrn); + xfree(pGeode->pExa); + pGeode->pExa = NULL; + } - if (pScrni->vtSema) - LXLeaveGraphics(pScrni); + LXUnmapMem(pScrni); - if (pGeode->AccelInfoRec) - XAADestroyInfoRec(pGeode->AccelInfoRec); + if (pGeode->useVGA) + vgaHWUnmapMem(pScrn); - if (pGeode->AccelImageWriteBuffers) { -#if LX_USE_OFFSCRN_MEM - xfree(pGeode->AccelImageWriteBuffers[0]); -#endif - xfree(pGeode->AccelImageWriteBuffers); - pGeode->AccelImageWriteBuffers = NULL; - } + Scrni->PointerMoved = pGeode->PointerMoved; + pScrn->CloseScreen = pGeode->CloseScreen; + + if (pScrn->CloseScreen) + return (*pScrn->CloseScreen)(scrnIndex, pScrn); - if (pGeode->AccelColorExpandBuffers) { - xfree(pGeode->AccelColorExpandBuffers[0]); - xfree(pGeode->AccelColorExpandBuffers); - pGeode->AccelColorExpandBuffers = NULL; - } - pScrni->vtSema = FALSE; + return TRUE; +} + +static Bool +LXEnterGraphics(ScreenPtr pScrn, ScrnInfoPtr pScrni) +{ + int bpp; + GeodeRec *pGeode = GEODEPTR(pScrni); - LXUnmapMem(pScrni); + if (!LXMapMem(pScrni)) + return FALSE; + + pGeode->VGAActive = gu3_get_vga_active(); + + gp_wait_until_idle(); + + //lx_disable_dac_power(pScrni, DF_CRT_DISABLE); + + vg_get_current_display_mode(&pGeode->FBcimdisplaytiming.vgDisplayMode, &bpp); + + //dump_previous(&pGeode->FBcimdisplaytiming.vgDisplayMode); + + pGeode->FBcimdisplaytiming.wBpp = bpp; + pGeode->FBcimdisplaytiming.wPitch = vg_get_display_pitch(); + + pGeode->FBDisplayOffset = vg_get_display_offset(); + + if (pGeode->useVGA) { + vgaHWPtr pvgaHW = VGAHWPTR(pScrni); + pGeode->FBBIOSMode = pvgaHW->readCrtc(pvgaHW, 0x040); + } + + pGeode->FBCompressionEnable = vg_get_compression_enable(); + vg_get_compression_info(&(pGeode->FBCBData)); + + /* Save Cursor offset */ + vg_get_cursor_info(&pGeode->FBCursor); + + /* Turn off the VGA */ + + if (pGeode->useVGA) { + unsigned short sequencer; + vgaHWPtr pvgaHW = VGAHWPTR(pScrni); + + /* Map VGA aperture */ + if (!vgaHWMapMem(pScrni)) + return FALSE; + + /* Unlock VGA registers */ + vgaHWUnlock(pvgaHW); + + /* Save the current state and setup the current mode */ + vgaHWSave(pScrni, &VGAHWPTR(pScrni)->SavedReg, VGA_SR_ALL); + + /* DISABLE VGA SEQUENCER */ + /* This allows the VGA state machine to terminate. We must delay */ + /* such that there are no pending MBUS requests. */ + + cim_outb(DC3_SEQUENCER_INDEX, DC3_SEQUENCER_CLK_MODE); + sequencer = cim_inb(DC3_SEQUENCER_DATA); + sequencer |= DC3_CLK_MODE_SCREEN_OFF; + cim_outb(DC3_SEQUENCER_DATA, sequencer); + + vg_delay_milliseconds(1); + + /* BLANK THE VGA DISPLAY */ + cim_outw(DC3_SEQUENCER_INDEX, DC3_SEQUENCER_RESET); + sequencer = cim_inb(DC3_SEQUENCER_DATA); + sequencer &= ~DC3_RESET_VGA_DISP_ENABLE; + cim_outb(DC3_SEQUENCER_DATA, sequencer); + + vg_delay_milliseconds(1); + } + + /* Set up the memory */ + /* XXX - FIXME - when we alow inital rotation, it should be here */ + LXAllocateMemory(pScrn, pScrni, pGeode->rotation); + + /* Clear the framebuffer */ + memset(pGeode->FBBase + pGeode->displayOffset, 0, pGeode->displaySize); + + /* Set up the video mode */ + + LXSetVideoMode(pScrni, pScrni->currentMode); + pGeode->curMode = pScrni->currentMode; + pScrni->vtSema = TRUE; + + return TRUE; +} + +static void +LXLoadPalette(ScrnInfoPtr pScrni, + int numColors, int *indizes, LOCO * colors, VisualPtr pVisual) +{ + int i, index, color; - if (pGeode && (pScrn->CloseScreen = pGeode->CloseScreen)) { - pGeode->CloseScreen = NULL; - return ((*pScrn->CloseScreen) (scrnIndex, pScrn)); + for (i = 0; i < numColors; i++) { + index = indizes[i] & 0xFF; + color = (((unsigned long)(colors[index].red & 0xFF)) << 16) | + (((unsigned long)(colors[index].green & 0xFF)) << 8) | + ((unsigned long)(colors[index].blue & 0xFF)); + + vg_set_display_palette_entry(index, color); } - return TRUE; } #ifdef DPMSExtension -/*---------------------------------------------------------------------------- - * LXDPMSSet. - * - * Description :This function sets geode into Power Management - * Signalling mode. - * - * Parameters. - * pScrni :Pointer to screen info strucrure. - * mode :Specifies the power management mode. - * - * Returns :none. - * - * Comments :none. -*---------------------------------------------------------------------------- -*/ + static void LXDPMSSet(ScrnInfoPtr pScrni, int mode, int flags) { @@ -2218,601 +1104,307 @@ LXDPMSSet(ScrnInfoPtr pScrni, int mode, int flags) pGeode = GEODEPTR(pScrni); - DEBUGMSG(1, (0, X_INFO, "LXDPMSSet!\n")); + if (!pScrni->vtSema) + return; - /* Check if we are actively controlling the display */ - if (!pScrni->vtSema) { - ErrorF("LXDPMSSet called when we not controlling the VT!\n"); - return; - } switch (mode) { - case DPMSModeOn: /* Screen: On; HSync: On; VSync: On */ - lx_enable_dac_power(pScrni, 1); - break; + case DPMSModeOn: + lx_enable_dac_power(pScrni, 1); + break; - case DPMSModeStandby: /* Screen: Off; HSync: Off; VSync: On */ - lx_disable_dac_power(pScrni, DF_CRT_STANDBY); - break; + case DPMSModeStandby: + lx_disable_dac_power(pScrni, DF_CRT_STANDBY); + break; - case DPMSModeSuspend: /* Screen: Off; HSync: On; VSync: Off */ - lx_disable_dac_power(pScrni, DF_CRT_SUSPEND); - break; + case DPMSModeSuspend: + lx_disable_dac_power(pScrni, DF_CRT_SUSPEND); + break; - case DPMSModeOff: /* Screen: Off; HSync: Off; VSync: Off */ - lx_disable_dac_power(pScrni, DF_CRT_DISABLE); - break; + case DPMSModeOff: + lx_disable_dac_power(pScrni, DF_CRT_DISABLE); + break; } } + #endif -/*---------------------------------------------------------------------------- - * LXScreenInit. - * - * Description :This function will be called at the each ofserver - * generation. - * - * Parameters. - * scrnIndex :Specfies the screenindex value during generation. - * pScrn :Pointer to screen strucrure. - * argc :parameters for command line arguments count - * argv :command line arguments if any it is not used. - * - * Returns :none. - * - * Comments :none. -*---------------------------------------------------------------------------- -*/ static Bool -LXScreenInit(int scrnIndex, ScreenPtr pScrn, int argc, char **argv) +LXCreateScreenResources(ScreenPtr pScreen) { - int i, bytpp, size, fbsize, fboffset, fbavail; - int pitch, displayWidth, virtualX, virtualY; - int HDisplay, VDisplay, maxHDisplay, maxVDisplay, maxX, maxY; - unsigned char *FBStart, **ap, *bp; - DisplayModePtr p; - GeodeRec *pGeode; - VisualPtr visual; - BoxRec AvailBox; - RegionRec OffscreenRegion; - ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; - Bool Inited = FALSE; - - DEBUGMSG(1, (0, X_INFO, "LXScreenInit!\n")); - /* Get driver private */ - pGeode = LXGetRec(pScrni); - DEBUGMSG(1, (0, X_INFO, "LXScreenInit(0)!\n")); - - /* - * Allocate a vgaHWRec - */ - - if (!vgaHWGetHWRec(pScrni)) - return FALSE; - if (!vgaHWMapMem(pScrni)) - return FALSE; + ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; + GeodeRec *pGeode = GEODEPTR(pScrni); - vgaHWGetIOBase(VGAHWPTR(pScrni)); + pScreen->CreateScreenResources = pGeode->CreateScreenResources; + if (!(*pScreen->CreateScreenResources) (pScreen)) + return FALSE; - if (!LXMapMem(pScrni)) - return FALSE; + if (xf86LoaderCheckSymbol("LXRandRSetConfig") + && pGeode->rotation != RR_Rotate_0) { + Rotation(*LXRandRSetConfig) (ScreenPtr pScreen, Rotation rr, int rate, + RRScreenSizePtr pSize) = NULL; + RRScreenSize p; + Rotation requestedRotation = pGeode->rotation; - pGeode->Pitch = LXCalculatePitchBytes(pScrni->virtualX, - pScrni->bitsPerPixel); - pGeode->AccelPitch = pGeode->Pitch; - bytpp = (pScrni->bitsPerPixel + 7) / 8; + pGeode->rotation = RR_Rotate_0; - /* start of framebuffer for accels */ - fboffset = 0; - fbavail = pGeode->FBAvail; + /* Just setup enough for an initial rotate */ - /* allocate display frame buffer at zero offset */ - fbsize = pScrni->virtualY * pGeode->Pitch; - pGeode->FBSize = fbsize; + p.width = pScreen->width; + p.height = pScreen->height; + p.mmWidth = pScreen->mmWidth; + p.mmHeight = pScreen->mmHeight; - pGeode->CursorSize = (HW_CURSOR_W * HW_CURSOR_H) / 8 * 2; - pGeode->CursorStartOffset = 0; + LXRandRSetConfig = LoaderSymbol("LXRandRSetConfig"); + if (LXRandRSetConfig) { + pGeode->starting = TRUE; + (*LXRandRSetConfig) (pScreen, requestedRotation, 0, &p); + pGeode->starting = FALSE; + } + } - DEBUGMSG(1, (scrnIndex, X_PROBED, "%d %d %d\n", - pScrni->virtualX, pScrni->bitsPerPixel, pGeode->Pitch)); + return TRUE; +} - HDisplay = pScrni->currentMode->HDisplay; - VDisplay = pScrni->currentMode->VDisplay; - pGeode->orig_virtX = pScrni->virtualX; - pGeode->orig_virtY = pScrni->virtualY; +static Bool +LXScreenInit(int scrnIndex, ScreenPtr pScrn, int argc, char **argv) +{ + ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; + GeodeRec *pGeode = GEODEPTR(pScrni); + XF86ModReqInfo shadowReq; + int maj, min, ret, rotate; + BOOL shadowfb = TRUE; - p = pScrni->modes; - maxHDisplay = p->HDisplay; - maxVDisplay = p->VDisplay; - while ((p = p->next) != pScrni->modes) { - if (maxHDisplay < p->HDisplay) - maxHDisplay = p->HDisplay; - if (maxVDisplay < p->VDisplay) - maxVDisplay = p->VDisplay; - } - DEBUGMSG(1, (scrnIndex, X_PROBED, "maxHDisplay %d maxVDisplay %d\n", - maxHDisplay, maxVDisplay)); - - switch (pGeode->Rotate) { - case 1: - case 3: - pGeode->HDisplay = VDisplay; - pGeode->VDisplay = HDisplay; - virtualX = pScrni->virtualY; - virtualY = pScrni->virtualX; - maxX = maxVDisplay; - maxY = maxHDisplay; - break; - default: - pGeode->HDisplay = HDisplay; - pGeode->VDisplay = VDisplay; - virtualX = pScrni->virtualX; - virtualY = pScrni->virtualY; - maxX = maxHDisplay; - maxY = maxVDisplay; - break; - } + pGeode->starting = TRUE; - /* shadow may be first in FB, since accels render there */ - - pGeode->ShadowPtr = NULL; - if (pGeode->ShadowFB) { - if (!pGeode->PointerMoved) { - pGeode->PointerMoved = pScrni->PointerMoved; - pScrni->PointerMoved = LXPointerMoved; - } - if (!pGeode->NoAccel) { - pGeode->ShadowPitch = - LXCalculatePitchBytes(virtualX, pScrni->bitsPerPixel); - size = pGeode->ShadowPitch * virtualY; - if (size <= fbavail - fbsize) { - pGeode->ShadowPtr = - (unsigned char *)pGeode->FBBase + fboffset; - pGeode->AccelPitch = pGeode->ShadowPitch; - pGeode->ShadowSize = size; - pGeode->ShadowInFBMem = TRUE; - fboffset += size; - fbavail -= size; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Shadow FB, No FB Memory, trying offscreen\n"); - } - } - if (pGeode->ShadowPtr == NULL) { - pGeode->ShadowPitch = - BitmapBytePad(pScrni->bitsPerPixel * virtualX); - size = pGeode->ShadowPitch * virtualY; - pGeode->ShadowPtr = xalloc(size); - if (pGeode->ShadowPtr != NULL) { - pGeode->ShadowSize = size; - pGeode->ShadowInFBMem = FALSE; - if (!pGeode->NoAccel) { - pGeode->NoAccel = TRUE; - pGeode->HWCursor = FALSE; - xf86DrvMsg(scrnIndex, X_ERROR, - "Shadow FB offscreen, All Accels disabled\n"); - } - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Shadow FB, No offscreen Memory, disabled\n"); - pGeode->ShadowFB = FALSE; - pGeode->Rotate = 0; - pGeode->HDisplay = HDisplay; - pGeode->VDisplay = VDisplay; - virtualX = pScrni->virtualX; - virtualY = pScrni->virtualY; - } - } - } + ErrorF("SCREENINIT!\n"); - if (pGeode->ShadowPtr != NULL) { - displayWidth = pGeode->ShadowPitch / bytpp; - FBStart = pGeode->ShadowPtr; - DEBUGMSG(1, (0, X_PROBED, "Shadow %p \n", FBStart)); - } else { - displayWidth = pGeode->Pitch / bytpp; - FBStart = pGeode->FBBase; - DEBUGMSG(1, (0, X_PROBED, "FBStart %p \n", FBStart)); - } + /* If we are using VGA then go ahead and map the memory */ - DEBUGMSG(1, (0, X_PROBED, "FB display %X size %X \n", fboffset, fbsize)); - pGeode->FBOffset = fboffset; /* offset of display framebuffer */ - pScrni->fbOffset = fboffset; - fboffset += fbsize; - fbavail -= fbsize; - - if (pGeode->Compression) { /* Compression enabled */ - pGeode->CBData.size = 512 + 32; - pGeode->CBData.pitch = 512 + 32; - size = maxY * pGeode->CBData.pitch; - DEBUGMSG(1, (0, X_PROBED, "CB %#x size %#x (%d*%lu)\n", fboffset, - size, maxY, pGeode->CBData.pitch)); - if (size <= fbavail) { - pGeode->CBData.compression_offset = fboffset; - fboffset += size; - fbavail -= size; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Compression, No FB Memory, disabled\n"); - pGeode->Compression = FALSE; - } - } + if (pGeode->useVGA) { - if (pGeode->HWCursor) { /* HWCursor enabled */ - size = pGeode->CursorSize; - if (size <= fbavail) { - pGeode->CursorStartOffset = fboffset; - fboffset += size; - fbavail -= size; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "HWCursor, No FB Memory, disabled\n"); - pGeode->HWCursor = FALSE; - } - } + if (!vgaHWMapMem(pScrni)) + return FALSE; - if (!pGeode->NoAccel) { /* Acceleration enabled */ - if (pGeode->NoOfImgBuffers > 0) { - pGeode->AccelImageWriteBuffers = NULL; - pitch = pGeode->AccelPitch; - size = pitch * pGeode->NoOfImgBuffers; -#if !LX_USE_OFFSCRN_MEM - if (size <= fbavail) { - bp = (unsigned char *)pGeode->FBBase + fboffset; - ap = xalloc(sizeof(pGeode->AccelImageWriteBuffers[0]) * - pGeode->NoOfImgBuffers); - if (ap != NULL) { - for (i = 0; i < pGeode->NoOfImgBuffers; ++i) { - ap[i] = bp; - bp += pitch; - } - pGeode->AccelImageWriteBuffers = ap; - fboffset += size; - fbavail -= size; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Image Write, No Memory\n"); - } - } else { - xf86DrvMsg(scrnIndex, X_ERROR, "Image Write, No FB Memory\n"); - } -#else - if ((bp = (unsigned char *)xalloc(size)) != NULL) { - ap = xalloc(sizeof(pGeode->AccelImageWriteBuffers[0]) * - pGeode->NoOfImgBuffers); - if (ap != NULL) { - for (i = 0; i < pGeode->NoOfImgBuffers; ++i) { - ap[i] = bp; - bp += pitch; - } - pGeode->AccelImageWriteBuffers = ap; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Image Write, No Memory\n"); - } - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Image Write, No offscreen Memory\n"); - } -#endif - if (pGeode->AccelImageWriteBuffers == NULL) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Accel Image Write disabled\n"); - pGeode->NoOfImgBuffers = 0; - } - } - - if (pGeode->NoOfColorExpandLines > 0) { - pGeode->AccelColorExpandBuffers = NULL; - pitch = ((pGeode->AccelPitch + 31) >> 5) << 2; - size = pitch * pGeode->NoOfColorExpandLines; - if ((bp = (unsigned char *)xalloc(size)) != NULL) { - ap = xalloc(sizeof(pGeode->AccelColorExpandBuffers[0]) * - pGeode->NoOfColorExpandLines); - if (ap != NULL) { - for (i = 0; i < pGeode->NoOfColorExpandLines; ++i) { - ap[i] = bp; - bp += pitch; - } - pGeode->AccelColorExpandBuffers = ap; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Color Expansion, No Memory\n"); - } - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Color Expansion, No offscreen Memory\n"); - } - if (pGeode->AccelColorExpandBuffers == NULL) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Accel Color Expansion disabled\n"); - pGeode->NoOfColorExpandLines = 0; - } - } - } else { - pGeode->NoOfImgBuffers = 0; - pGeode->AccelImageWriteBuffers = NULL; - pGeode->NoOfColorExpandLines = 0; - pGeode->AccelColorExpandBuffers = NULL; + vgaHWGetIOBase(VGAHWPTR(pScrni)); } + + if (!pGeode->NoAccel) { - /* Initialise graphics mode */ + pGeode->pExa = xnfcalloc(sizeof(ExaDriverRec), 1); + + if (pGeode->pExa) { + + /* THis is set in LXAllocMem */ + pGeode->pExa->memoryBase = 0; + + /* This is set in LXAllocateMemory */ + pGeode->pExa->memorySize = 0; + + pGeode->pExa->pixmapOffsetAlign = 32; + pGeode->pExa->pixmapPitchAlign = 32; + pGeode->pExa->flags = EXA_OFFSCREEN_PIXMAPS; + pGeode->pExa->maxX = pGeode->maxWidth - 1; + pGeode->pExa->maxY = pGeode->maxHeight - 1; + } + else { + xf86DrvMsg(scrnIndex, X_ERROR, "Couldn't allocate the EXA structure.\n"); + pGeode->NoAccel = TRUE; + } + } + + /* XXX FIXME - Take down any of the structures on failure? */ if (!LXEnterGraphics(pScrn, pScrni)) - return FALSE; - - pScrni->virtualX = virtualX; - pScrni->virtualY = virtualY; + return FALSE; - /* Reset visual list */ miClearVisualTypes(); - /* Setup the visual we support */ + /* XXX Again - take down anything? */ + if (pScrni->bitsPerPixel > 8) { - DEBUGMSG(1, (scrnIndex, X_PROBED, - "miSetVisualTypes %d %X %X %X\n", - pScrni->depth, - TrueColorMask, pScrni->rgbBits, pScrni->defaultVisual)); - - if (!miSetVisualTypes(pScrni->depth, - TrueColorMask, pScrni->rgbBits, pScrni->defaultVisual)) { - return FALSE; - } + if (!miSetVisualTypes(pScrni->depth, + TrueColorMask, pScrni->rgbBits, pScrni->defaultVisual)) { + return FALSE; + } } else { - if (!miSetVisualTypes(pScrni->depth, - miGetDefaultVisualMask(pScrni->depth), - pScrni->rgbBits, pScrni->defaultVisual)) { - return FALSE; - } + if (!miSetVisualTypes(pScrni->depth, + miGetDefaultVisualMask(pScrni->depth), + pScrni->rgbBits, pScrni->defaultVisual)) { + return FALSE; + } } - /* Set for RENDER extensions */ miSetPixmapDepths(); - /* Call the framebuffer layer's ScreenInit function, and fill in other - * pScrn fields. - */ - switch (pScrni->bitsPerPixel) { -#if CFB - case 8: - Inited = cfbScreenInit(pScrn, FBStart, virtualX, virtualY, - pScrni->xDpi, pScrni->yDpi, displayWidth); - break; - case 16: - Inited = cfb16ScreenInit(pScrn, FBStart, virtualX, virtualY, - pScrni->xDpi, pScrni->yDpi, displayWidth); - break; - case 24: - case 32: - Inited = cfb32ScreenInit(pScrn, FBStart, virtualX, virtualY, - pScrni->xDpi, pScrni->yDpi, displayWidth); - break; -#else - case 8: - case 16: - case 24: - case 32: - Inited = fbScreenInit(pScrn, FBStart, virtualX, virtualY, - pScrni->xDpi, pScrni->yDpi, displayWidth, pScrni->bitsPerPixel); - break; -#endif - default: - xf86DrvMsg(scrnIndex, X_ERROR, - "Internal error: invalid bpp (%d) in ScreenInit\n", - pScrni->bitsPerPixel); - Inited = FALSE; - break; - } + /* Point at the visible area to start */ - if (!Inited) - return FALSE; - - LXRotationInit(pScrni); - LXAdjustFrame(scrnIndex, pScrni->frameX0, pScrni->frameY0, 0); - - /* SET UP GRAPHICS MEMORY AVAILABLE FOR PIXMAP CACHE */ - AvailBox.x1 = 0; - AvailBox.y1 = (fboffset + pGeode->AccelPitch - 1) / pGeode->AccelPitch; - AvailBox.x2 = displayWidth; - AvailBox.y2 = (pGeode->FBAvail - pGeode->AccelPitch + 1) / - pGeode->AccelPitch; - - if (AvailBox.y1 < AvailBox.y2) { - xf86DrvMsg(scrnIndex, X_INFO, - "Initializing Memory manager to (%d,%d) (%d,%d)\n", - AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2); - REGION_INIT(pScrn, &OffscreenRegion, &AvailBox, 2); - if (!xf86InitFBManagerRegion(pScrn, &OffscreenRegion)) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Memory manager initialization failed, Cache Diabled\n"); - } - REGION_UNINIT(pScrn, &OffscreenRegion); - } else { - xf86DrvMsg(scrnIndex, X_INFO, - "No Off Screen Memory, Cache Disabled (%d,%d) (%d,%d)\n", - AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2); - } + ret = fbScreenInit(pScrn, pGeode->FBBase + pGeode->displayOffset, + pScrni->virtualX, pScrni->virtualY, + pScrni->xDpi, pScrni->yDpi, pGeode->displayWidth, + pScrni->bitsPerPixel); - xf86SetBlackWhitePixels(pScrn); + if (!ret) + return FALSE; - if (!pGeode->ShadowFB) { - LXDGAInit(pScrn); - } + xf86SetBlackWhitePixels(pScrn); + /* Set up the color ordering */ if (pScrni->bitsPerPixel > 8) { - /* Fixup RGB ordering */ - visual = pScrn->visuals + pScrn->numVisuals; - while (--visual >= pScrn->visuals) { - if ((visual->class | DynamicClass) == DirectColor) { - visual->offsetRed = pScrni->offset.red; - visual->offsetGreen = pScrni->offset.green; - visual->offsetBlue = pScrni->offset.blue; - visual->redMask = pScrni->mask.red; - visual->greenMask = pScrni->mask.green; - visual->blueMask = pScrni->mask.blue; - } - } + VisualPtr visual = pScrn->visuals + pScrn->numVisuals; + + while (--visual >= pScrn->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScrni->offset.red; + visual->offsetGreen = pScrni->offset.green; + visual->offsetBlue = pScrni->offset.blue; + visual->redMask = pScrni->mask.red; + visual->greenMask = pScrni->mask.green; + visual->blueMask = pScrni->mask.blue; + } + } } -#if CFB -#else - /* must be after RGB ordering fixed */ + + /* Must follow the color ordering */ fbPictureInit(pScrn, 0, 0); -#endif - if (!pGeode->NoAccel) { - LXAccelInit(pScrn); - } + if (!pGeode->NoAccel) + pGeode->NoAccel = LXExaInit(pScrn) ? FALSE : TRUE; + miInitializeBackingStore(pScrn); xf86SetBackingStore(pScrn); - /* Initialise software cursor */ + + /* Set up the soft cursor */ miDCInitialize(pScrn, xf86GetPointerScreenFuncs()); - /* Initialize HW cursor layer. - * Must follow software cursor initialization - */ - if (pGeode->HWCursor) { - if (!LXHWCursorInit(pScrn)) - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, - "Hardware cursor initialization failed\n"); - } - /* Setup default colourmap */ - if (!miCreateDefColormap(pScrn)) { - return FALSE; + + /* Set up the HW cursor - must follow the soft cursor init */ + + if (pGeode->tryHWCursor) { + if (!LXHWCursorInit(pScrn)) + xf86DrvMsg(scrnIndex, X_ERROR, + "Hardware cursor initialization failed.\n"); } + + /* Set up the color map */ + + if (!miCreateDefColormap(pScrn)) + return FALSE; + if (pScrni->bitsPerPixel == 8) { - /* Initialize colormap layer. - * Must follow initialization of the default colormap - */ - if (!xf86HandleColormaps(pScrn, 256, 8, LXLoadPalette, NULL, - CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) { - return FALSE; - } - } + /* Must follow initialization of the default colormap */ - if (pGeode->ShadowFB) { - DEBUGMSG(1, (0, X_INFO, "Shadowed, Rotate=%d, NoAccel=%d\n", - pGeode->Rotate, pGeode->NoAccel)); - LXShadowFBInit(pScrn, pGeode, bytpp); + if (!xf86HandleColormaps(pScrn, 256, 8, + LXLoadPalette, NULL, + CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) { + return FALSE; + } } #ifdef DPMSExtension xf86DPMSInit(pScrn, LXDPMSSet, 0); #endif - LXInitVideo(pScrn); /* needed for video */ - /* Wrap the screen's CloseScreen vector and set its - * SaveScreen vector - */ + LXInitVideo(pScrn); + + /* Set up RandR */ + /* We provide our own RandR goodness - disable the default */ + xf86DisableRandR(); + + memset(&shadowReq, 0, sizeof(shadowReq)); + shadowReq.majorversion = 1; + shadowReq.minorversion = 1; + + if (LoadSubModule(pScrni->module, "shadow", + NULL, NULL, NULL, &shadowReq, &maj, &min)) { + + rotate = RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270; + shadowSetup(pScrn); + } else { + LoaderErrorMsg(NULL, "shadow", maj, min); + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Error loading shadow - rotation not available.\n"); + + if (pGeode->rotation != RR_Rotate_0) + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Reverting back to normal rotation.\n"); + + rotate = pGeode->rotation = RR_Rotate_0; + } + + LXRandRInit(pScrn, rotate); + + pGeode->PointerMoved = pScrni->PointerMoved; + pScrni->PointerMoved = GeodePointerMoved; + pGeode->CreateScreenResources = pScrn->CreateScreenResources; + pScrn->CreateScreenResources = LXCreateScreenResources; + pGeode->CloseScreen = pScrn->CloseScreen; pScrn->CloseScreen = LXCloseScreen; - pScrn->SaveScreen = LXSaveScreen; - /* Report any unused options */ - if (serverGeneration == 1) { - xf86ShowUnusedOptions(pScrni->scrnIndex, pScrni->options); - } + if (serverGeneration == 1) + xf86ShowUnusedOptions(pScrni->scrnIndex, pScrni->options); - return TRUE; -} + pGeode->starting = FALSE; -/*---------------------------------------------------------------------------- - * LXSwitchMode. - * - * Description :This function will switches the screen mode - * - * Parameters: - * scrnIndex :Specfies the screen index value. - * pMode :pointer to the mode structure. - * flags :may be used for status check?. - * - * Returns :Returns TRUE on success and FALSE on failure. - * - * Comments :none. -*---------------------------------------------------------------------------- -*/ -Bool -LXSwitchMode(int scrnIndex, DisplayModePtr pMode, int flags) -{ - DEBUGMSG(1, (0, X_INFO, "LXSwitchMode\n")); - return LXSetMode(xf86Screens[scrnIndex], pMode); + return TRUE; } -/*---------------------------------------------------------------------------- - * LXAdjustFrame. - * - * Description :This function is used to intiallize the start - * address of the memory. - * Parameters. - * scrnIndex :Specfies the screen index value. - * x :x co-ordinate value interms of pixels. - * y :y co-ordinate value interms of pixels. - * - * Returns :none. - * - * Comments :none. -*---------------------------------------------------------------------------- -*/ -void -LXAdjustFrame(int scrnIndex, int x, int y, int flags) +static int +LXValidMode(int scrnIndex, DisplayModePtr pMode, Bool Verbose, int flags) { ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; GeodeRec *pGeode = GEODEPTR(pScrni); - int newX, newY; - unsigned long offset; - - if (x + pGeode->HDisplay >= pScrni->virtualX) - x = pScrni->virtualX - pGeode->HDisplay; - if (x < 0) - x = 0; - if (y + pGeode->VDisplay >= pScrni->virtualY) - y = pScrni->virtualY - pGeode->VDisplay; - if (y < 0) - y = 0; - pScrni->frameX0 = x; - pScrni->frameY0 = y; - pScrni->frameX1 = x + pGeode->HDisplay - 1; - pScrni->frameY1 = y + pGeode->VDisplay - 1; - (*pGeode->Rotation) (x, y, pScrni->virtualX, pScrni->virtualY, &newX, - &newY); - (*pGeode->RBltXlat) (newX, newY, pGeode->HDisplay, pGeode->VDisplay, - &newX, &newY); - offset = pGeode->FBOffset + newY * pGeode->Pitch + - newX * (pScrni->bitsPerPixel >> 3); - vg_set_display_offset(offset); + int p, ret; + VG_QUERY_MODE vgQueryMode; + + memset(&vgQueryMode, 0, sizeof(vgQueryMode)); + + if (pMode->type && pMode->type != M_T_USERDEF) { + + if (pGeode->Output & OUTPUT_PANEL) { + + /* Can't scale this mode */ + + if ((pGeode->PanelY != pMode->CrtcHDisplay) && + pMode->CrtcHDisplay > 1024) + return MODE_NOMODE; + + vgQueryMode.panel_width = pGeode->PanelX; + vgQueryMode.panel_height = pGeode->PanelY; + + vgQueryMode.query_flags |= VG_QUERYFLAG_PANELWIDTH | VG_QUERYFLAG_PANELHEIGHT; + } + + vgQueryMode.active_width = pMode->CrtcHDisplay; + vgQueryMode.active_height = pMode->CrtcVDisplay; + vgQueryMode.bpp = pScrni->bitsPerPixel; + vgQueryMode.hz = GeodeGetRefreshRate(pMode); + vgQueryMode.query_flags |= VG_QUERYFLAG_REFRESH | VG_QUERYFLAG_BPP | + VG_QUERYFLAG_ACTIVEWIDTH | VG_QUERYFLAG_ACTIVEHEIGHT; + + ret = vg_get_display_mode_index(&vgQueryMode); + + if (ret < 0) + return MODE_BAD; + } + + if (pGeode->tryCompression) + p = GeodeCalculatePitchBytes(pMode->CrtcHDisplay, pScrni->bitsPerPixel); + else + p = ((pMode->CrtcHDisplay + 3) & ~3) * (pScrni->bitsPerPixel >> 3); + + if (p * pMode->CrtcVDisplay > pGeode->FBAvail) + return MODE_MEM; + + return MODE_OK; } -/*---------------------------------------------------------------------------- - * LXEnterVT. - * - * Description :This is called when VT switching back to the X server - * - * Parameters. - * scrnIndex :Specfies the screen index value. - * flags :Not used inside the function. - * - * Returns :none. - * - * Comments :none. -*---------------------------------------------------------------------------- -*/ +/* XXX - Way more to do here */ + static Bool LXEnterVT(int scrnIndex, int flags) { - DEBUGMSG(1, (0, X_INFO, "LXEnterVT\n")); return LXEnterGraphics(NULL, xf86Screens[scrnIndex]); } -/*---------------------------------------------------------------------------- - * LXLeaveVT. - * - * Description :This is called when VT switching X server text mode. - * - * Parameters. - * scrnIndex :Specfies the screen index value. - * flags :Not used inside the function. - * - * Returns :none. - * - * Comments :none. -*---------------------------------------------------------------------------- -*/ static void LXLeaveVT(int scrnIndex, int flags) { @@ -2820,232 +1412,20 @@ LXLeaveVT(int scrnIndex, int flags) GeodeRec *pGeode = GEODEPTR(pScrni); pGeode->PrevDisplayOffset = vg_get_display_offset(); - DEBUGMSG(1, (0, X_INFO, "LXLeaveVT\n")); LXLeaveGraphics(xf86Screens[scrnIndex]); } -/*---------------------------------------------------------------------------- - * LXFreeScreen. - * - * Description :This is called to free any persistent data structures. - * - * Parameters. - * scrnIndex :Specfies the screen index value. - * flags :Not used inside the function. - * - * Returns :none. - * - * Comments :This will be called only when screen being deleted.. -*---------------------------------------------------------------------------- -*/ -static void -LXFreeScreen(int scrnIndex, int flags) -{ - DEBUGMSG(1, (0, X_INFO, "LXFreeScreen\n")); - if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) - vgaHWFreeHWRec(xf86Screens[scrnIndex]); - LXFreeRec(xf86Screens[scrnIndex]); -} - -/*---------------------------------------------------------------------------- - * LXValidMode. - * - * Description :This function checks if a mode is suitable for selected - * chipset. - * Parameters. - * scrnIndex :Specfies the screen index value. - * pMode :Pointer to the screen mode structure.. - * verbose :not used for implementation. - * flags :not used for implementation - * - * Returns :MODE_OK if the specified mode is supported or - * MODE_NO_INTERLACE. - * Comments :none. -*---------------------------------------------------------------------------- -*/ -static int -LXValidMode(int scrnIndex, DisplayModePtr pMode, Bool Verbose, int flags) -{ - unsigned int total_memory_required; - ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; - int ret = -1; - GeodeRec *pGeode = GEODEPTR(pScrni); - - DEBUGMSG(0, (0, X_NONE, "GeodeValidateMode: %dx%d %d %d\n", - pMode->CrtcHDisplay, pMode->CrtcVDisplay, - pScrni->bitsPerPixel, LXGetRefreshRate(pMode))); - if (pGeode->CustomMode == 0) { - int tv_mode; - VG_QUERY_MODE vgQueryMode; - unsigned long flags; - - if (pMode->Flags & V_INTERLACE) - return MODE_NO_INTERLACE; - - flags = VG_QUERYFLAG_REFRESH | VG_QUERYFLAG_BPP | - VG_QUERYFLAG_ACTIVEWIDTH | VG_QUERYFLAG_ACTIVEHEIGHT; - - if ((pGeode->EnabledOutput & LX_OT_FP) != 0) { - /* scaling required, but too big to scale */ - if (pGeode->FPGeomDstX != pMode->CrtcHDisplay - && pMode->CrtcHDisplay > 1024) - return MODE_NOMODE; - flags = VG_QUERYFLAG_PANELWIDTH | VG_QUERYFLAG_PANELHEIGHT | - VG_QUERYFLAG_PANEL; - vgQueryMode.panel_width = pGeode->FPGeomDstX; - vgQueryMode.panel_height = pGeode->FPGeomDstY; - } - - vgQueryMode.active_width = pMode->CrtcHDisplay; - vgQueryMode.active_height = pMode->CrtcVDisplay; - vgQueryMode.bpp = pScrni->bitsPerPixel; - vgQueryMode.hz = LXGetRefreshRate(pMode); - vgQueryMode.query_flags = VG_QUERYFLAG_REFRESH | VG_QUERYFLAG_BPP | - VG_QUERYFLAG_ACTIVEWIDTH | VG_QUERYFLAG_ACTIVEHEIGHT; - if ((tv_mode = lx_tv_mode(pMode)) >= 0) { - vgQueryMode.encoder = pGeode->tv_encoder; - vgQueryMode.tvmode = tv_mode; - vgQueryMode.query_flags |= - VG_QUERYFLAG_TVMODE | VG_QUERYFLAG_ENCODER; - vgQueryMode.query_flags &= ~VG_QUERYFLAG_REFRESH; - if (lx_tv_mode_interlaced(tv_mode) != 0) { - vgQueryMode.query_flags |= VG_QUERYFLAG_INTERLACED; - vgQueryMode.active_height /= 2; - } - } - ret = vg_get_display_mode_index(&vgQueryMode); - if (ret < 0) - return MODE_NOMODE; - } - - total_memory_required = LXCalculatePitchBytes(pMode->CrtcHDisplay, - pScrni->bitsPerPixel) * pMode->CrtcVDisplay; - - DEBUGMSG(0, (0, X_NONE, "Total Mem %x %lx\n", - total_memory_required, pGeode->FBAvail)); - - if (total_memory_required > pGeode->FBAvail) - return MODE_MEM; - - return MODE_OK; -} - -/*---------------------------------------------------------------------------- - * LXLoadPalette. - * - * Description :This function sets the palette entry used for graphics data - * - * Parameters. - * pScrni:Points the screeninfo structure. - * numColors:Specifies the no of colors it supported. - * indizes :This is used get index value . - * LOCO :to be added. - * pVisual :to be added. - * - * Returns :MODE_OK if the specified mode is supported or - * MODE_NO_INTERLACE. - * Comments :none. -*---------------------------------------------------------------------------- -*/ - -static void -LXLoadPalette(ScrnInfoPtr pScrni, - int numColors, int *indizes, LOCO * colors, VisualPtr pVisual) -{ - int i, index, color; - - for (i = 0; i < numColors; i++) { - index = indizes[i] & 0xFF; - color = (((unsigned long)(colors[index].red & 0xFF)) << 16) | - (((unsigned long)(colors[index].green & 0xFF)) << 8) | - ((unsigned long)(colors[index].blue & 0xFF)); - vg_set_display_palette_entry(index, color); - } -} - -static Bool -LXMapMem(ScrnInfoPtr pScrni) +void +LXSetupChipsetFPtr(ScrnInfoPtr pScrn) { - unsigned long cmd_bfr_phys; - GeodeRec *pGeode = GEODEPTR(pScrni); - - DEBUGMSG(1, (0, X_NONE, "LXMapMem\n")); - - cim_gp_ptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex, - VIDMEM_MMIO, - pGeode->InitBaseAddress.gp_register_base, pGeode->gp_reg_size); - cim_vg_ptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex, - VIDMEM_MMIO, - pGeode->InitBaseAddress.vg_register_base, pGeode->vg_reg_size); - cim_vid_ptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex, - VIDMEM_MMIO, - pGeode->InitBaseAddress.df_register_base, pGeode->vid_reg_size); - cim_vip_ptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex, - VIDMEM_MMIO, - pGeode->InitBaseAddress.vip_register_base, pGeode->vip_reg_size); - - cim_fb_ptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex, - VIDMEM_FRAMEBUFFER, - pGeode->InitBaseAddress.framebuffer_base, - pGeode->InitBaseAddress.framebuffer_size); - - pGeode->FBBase = cim_fb_ptr; - - DEBUGMSG(1, (0, X_NONE, "cim ptrs %p %p %p %p %p\n", - cim_gp_ptr, cim_vg_ptr, cim_vid_ptr, cim_vip_ptr, cim_fb_ptr)); - - /* CHECK IF REGISTERS WERE MAPPED SUCCESSFULLY */ - if ((!cim_gp_ptr) || (!cim_vid_ptr) || (!cim_fb_ptr)) { - DEBUGMSG(1, (0, X_NONE, "Could not map hardware registers.\n")); - return (FALSE); - } - - cmd_bfr_phys = - pGeode->InitBaseAddress.framebuffer_base + pGeode->CmdBfrOffset; - cim_cmd_base_ptr = cim_fb_ptr + pGeode->CmdBfrOffset; - - /* - * Map the top of the frame buffer as the scratch buffer - * (GP3_SCRATCH_BUFFER_SIZE) - */ - gp_set_frame_buffer_base(pGeode->InitBaseAddress.framebuffer_base, - pGeode->FBTop); - gp_set_command_buffer_base(cmd_bfr_phys, 0, pGeode->CmdBfrSize); - DEBUGMSG(1, (0, X_NONE, "cim cmd %p %lx %lx %lx\n", - cim_cmd_base_ptr, pGeode->CmdBfrSize, cmd_bfr_phys, - pGeode->FBTop)); - - /* Map the XpressROM ptr to read what platform are we on */ - XpressROMPtr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex, - VIDMEM_FRAMEBUFFER, 0xF0000, 0x10000); - - DEBUGMSG(1, (0, X_NONE, "adapter info %lx %lx %lx %lx %p, %p\n", - pGeode->cpu_version, - pGeode->vid_version, pGeode->FBLinearAddr, - pGeode->FBAvail, pGeode->FBBase, XpressROMPtr)); - - return TRUE; + pScrn->PreInit = LXPreInit; + pScrn->ScreenInit = LXScreenInit; + pScrn->SwitchMode = LXSwitchMode; + pScrn->AdjustFrame = LXAdjustFrame; + pScrn->EnterVT = LXEnterVT; + pScrn->LeaveVT = LXLeaveVT; + pScrn->FreeScreen = GeodeFreeScreen; + pScrn->ValidMode = LXValidMode; } -/* - * Unmap the framebuffer and MMIO memory. - */ -static Bool -LXUnmapMem(ScrnInfoPtr pScrni) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - DEBUGMSG(1, (0, X_NONE, "LXUnMapMem\n")); - - /* unmap all the memory map's */ - xf86UnMapVidMem(pScrni->scrnIndex, cim_gp_ptr, pGeode->gp_reg_size); - xf86UnMapVidMem(pScrni->scrnIndex, cim_vg_ptr, pGeode->vg_reg_size); - xf86UnMapVidMem(pScrni->scrnIndex, cim_vid_ptr, pGeode->vid_reg_size); - xf86UnMapVidMem(pScrni->scrnIndex, cim_vip_ptr, pGeode->vip_reg_size); - xf86UnMapVidMem(pScrni->scrnIndex, - cim_fb_ptr, pGeode->InitBaseAddress.framebuffer_size); - xf86UnMapVidMem(pScrni->scrnIndex, XpressROMPtr, 0x10000); - - return TRUE; -} diff --git a/src/amd_lx_exa.c b/src/amd_lx_exa.c new file mode 100644 index 0000000..de3c5dd --- /dev/null +++ b/src/amd_lx_exa.c @@ -0,0 +1,1034 @@ +/* + * Copyright (c) 2007 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Neither the name of the Advanced Micro Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + */ + +/* TODO: + Support a8 as a source or destination? + convert !a8 or !a4 masks? + support multiple pass operations? +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "amd.h" +#include "cim_defs.h" +#include "cim_regs.h" + +#include "amd_blend.h" + +static const struct exa_format_t { + int exa; + int bpp; + int fmt; + int alphabits; +} lx_exa_formats[] = { + {PICT_a8r8g8b8, 32, CIMGP_SOURCE_FMT_8_8_8_8, 8 }, + {PICT_x8r8g8b8, 32, CIMGP_SOURCE_FMT_8_8_8_8, 0 }, + {PICT_x8b8g8r8, 32, CIMGP_SOURCE_FMT_32BPP_BGR, 0 }, + {PICT_a4r4g4b4, 16, CIMGP_SOURCE_FMT_4_4_4_4, 4 }, + {PICT_a1r5g5b5, 16, CIMGP_SOURCE_FMT_1_5_5_5, 1 }, + {PICT_r5g6b5, 16, CIMGP_SOURCE_FMT_0_5_6_5, 0 }, + {PICT_b5g6r5, 16, CIMGP_SOURCE_FMT_16BPP_BGR, 0 }, + {PICT_x1r5g5b5, 16, CIMGP_SOURCE_FMT_1_5_5_5, 0 }, + {PICT_x1b5g5r5, 16, CIMGP_SOURCE_FMT_15BPP_BGR, 0 }, + {PICT_r3g3b2, 8, CIMGP_SOURCE_FMT_3_3_2, 0 } +}; + +/* This is a chunk of memory we use for scratch space */ + +#define COMP_TYPE_MASK 0 +#define COMP_TYPE_ONEPASS 1 +#define COMP_TYPE_TWOPASS 3 + +static struct { + int type; + + unsigned int srcOffset; + unsigned int srcPitch; + unsigned int srcBpp; + unsigned int srcWidth, srcHeight; + PixmapPtr srcPixmap; + + int op; + int repeat; + unsigned int fourBpp; + unsigned int bufferOffset; + struct exa_format_t *srcFormat; + struct exa_format_t *dstFormat; +} exaScratch; + +static const int SDfn[16] = { + 0x00, 0x88, 0x44, 0xCC, 0x22, 0xAA, 0x66, 0xEE, + 0x11, 0x99, 0x55, 0xDD, 0x33, 0xBB, 0x77, 0xFF +}; + +static const int SDfn_PM[16] = { + 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, + 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA +}; + +/* These functions check to see if we can safely prefetch the memory + * for the blt, or if we have to wait the previous blt to complete. + * One function is for the fill, and the other is for the copy because + * they have different requirements based on ROP + */ + +static int lx0 = -1, ly0 = -1, lx1 = -1, ly1 = -1; + +static int lx_fill_flags(int x0, int y0, int w, int h, int rop) +{ + int x1 = x0 + w, y1 = y0 + h; + int n = ((rop^(rop>>1))&0x55) == 0 || /* no dst */ + x0 >= lx1 || y0 >= ly1 || /* rght/below */ + x1 <= lx0 || y1 <= ly0 ? /* left/above */ + 0 : CIMGP_BLTFLAGS_HAZARD; + + lx0 = x0; + ly0 = y0; + lx1 = x1; + ly1 = y1; + + return n; +} + +static int lx_copy_flags(int x0, int y0, int x1, int y1, int w, int h, + int rop) +{ + int x2 = x1+w, y2 = y1+h; + + /* dst not hazzard and src not hazzard */ + int n = ( ((rop^(rop>>1))&0x55) == 0 || + x1 >= lx1 || y1 >= ly1 || + x2 <= lx0 || y2 <= ly0 ) && + ( ((rop^(rop>>2))&0x33) == 0 || + x0 >= lx1 || y0 >= ly1 || + x0+w <= lx0 || y0+h <= ly0 ) ? + 0 : CIMGP_BLTFLAGS_HAZARD; + + lx0 = x1; + ly0 = y1; + lx1 = x2; + ly1 = y2; + + return n; +} + +/* These are borrowed from the exa engine - they should be made global + and available to drivers, but until then.... +*/ + +/* exaGetPixelFromRGBA (exa_render.c) */ + +static Bool +_GetPixelFromRGBA(CARD32 *pixel, + CARD16 red, + CARD16 green, + CARD16 blue, + CARD16 alpha, + CARD32 format) +{ + int rbits, bbits, gbits, abits; + int rshift, bshift, gshift, ashift; + + *pixel = 0; + + if (!PICT_FORMAT_COLOR(format)) + return FALSE; + + rbits = PICT_FORMAT_R(format); + gbits = PICT_FORMAT_G(format); + bbits = PICT_FORMAT_B(format); + abits = PICT_FORMAT_A(format); + + if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) { + bshift = 0; + gshift = bbits; + rshift = gshift + gbits; + ashift = rshift + rbits; + } else { /* PICT_TYPE_ABGR */ + rshift = 0; + gshift = rbits; + bshift = gshift + gbits; + ashift = bshift + bbits; + } + + *pixel |= ( blue >> (16 - bbits)) << bshift; + *pixel |= ( red >> (16 - rbits)) << rshift; + *pixel |= (green >> (16 - gbits)) << gshift; + *pixel |= (alpha >> (16 - abits)) << ashift; + + return TRUE; +} + +/* exaGetRGBAFromPixel (exa_render.c) */ + +static Bool +_GetRGBAFromPixel(CARD32 pixel, + CARD16 *red, + CARD16 *green, + CARD16 *blue, + CARD16 *alpha, + CARD32 format) +{ + int rbits, bbits, gbits, abits; + int rshift, bshift, gshift, ashift; + + if (!PICT_FORMAT_COLOR(format)) + return FALSE; + + rbits = PICT_FORMAT_R(format); + gbits = PICT_FORMAT_G(format); + bbits = PICT_FORMAT_B(format); + abits = PICT_FORMAT_A(format); + + if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) { + bshift = 0; + gshift = bbits; + rshift = gshift + gbits; + ashift = rshift + rbits; + } else { /* PICT_TYPE_ABGR */ + rshift = 0; + gshift = rbits; + bshift = gshift + gbits; + ashift = bshift + bbits; + } + + *red = ((pixel >> rshift ) & ((1 << rbits) - 1)) << (16 - rbits); + while (rbits < 16) { + *red |= *red >> rbits; + rbits <<= 1; + } + + *green = ((pixel >> gshift ) & ((1 << gbits) - 1)) << (16 - gbits); + while (gbits < 16) { + *green |= *green >> gbits; + gbits <<= 1; + } + + *blue = ((pixel >> bshift ) & ((1 << bbits) - 1)) << (16 - bbits); + while (bbits < 16) { + *blue |= *blue >> bbits; + bbits <<= 1; + } + + if (abits) { + *alpha = ((pixel >> ashift ) & ((1 << abits) - 1)) << (16 - abits); + while (abits < 16) { + *alpha |= *alpha >> abits; + abits <<= 1; + } + } else + *alpha = 0xffff; + + return TRUE; +} + +static unsigned int lx_get_source_color(PicturePtr pSrc, int x, int y, int dstFormat) +{ + FbBits *bits; + FbStride stride; + int bpp, xoff, yoff; + + CARD32 in, out; + CARD16 red, green, blue, alpha; + + fbGetDrawable (pSrc->pDrawable, bits, stride, bpp, xoff, yoff); + + bits += (y * stride) + (x * (bpp >> 3)); + + /* Read the source value */ + + switch(bpp) { + case 32: + case 24: + in = (CARD32) *((CARD32 *) bits); + break; + + case 16: + in = (CARD32) *((CARD16 *) bits); + break; + + case 8: + in = (CARD32) *((CARD8 *) bits); + break; + } + + _GetRGBAFromPixel(in, &red, &blue, &green, &alpha, pSrc->format); + _GetPixelFromRGBA(&out, red, blue, green, alpha, dstFormat); + + return out; +} + +static Bool +lx_prepare_solid(PixmapPtr pxMap, int alu, Pixel planemask, Pixel fg) +{ + GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxMap); + int pitch = exaGetPixmapPitch(pxMap); + int op = (planemask == ~0U) ? SDfn[alu] : SDfn_PM[alu]; + + gp_declare_blt(0); + gp_set_bpp(pxMap->drawable.bitsPerPixel); + + gp_set_raster_operation(op); + + if (planemask != ~0U) + gp_set_solid_pattern(planemask); + + exaScratch.op = op; + + gp_set_solid_source(fg); + gp_set_strides(pitch, pitch); + gp_write_parameters(); +} + +static void +lx_do_solid(PixmapPtr pxMap, int x1, int y1, int x2, int y2) +{ + int bpp = (pxMap->drawable.bitsPerPixel + 7) / 8; + int pitch = exaGetPixmapPitch(pxMap); + unsigned int offset = exaGetPixmapOffset(pxMap) + (pitch * y1) + (bpp * x1); + + gp_declare_blt(lx_fill_flags(x1, y1,x2-x1,y2-y1, exaScratch.op)); + gp_pattern_fill(offset, x2-x1, y2-y1); +} + +static Bool +lx_prepare_copy( PixmapPtr pxSrc, PixmapPtr pxDst, int dx, int dy, + int alu, Pixel planemask) +{ + GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst); + int dpitch = exaGetPixmapPitch(pxDst); + int op = (planemask == ~0U) ? SDfn[alu] : SDfn_PM[alu]; + + gp_declare_blt(0); + gp_set_bpp(pxDst->drawable.bitsPerPixel); + + gp_set_raster_operation(op); + + if (planemask != ~0U) + gp_set_solid_pattern(planemask); + + exaScratch.srcOffset = exaGetPixmapOffset(pxSrc); + exaScratch.srcPitch = exaGetPixmapPitch(pxSrc); + exaScratch.srcBpp = (pxSrc->drawable.bitsPerPixel + 7) / 8; + + exaScratch.op = op; + + gp_set_strides(dpitch, exaScratch.srcPitch); + gp_write_parameters(); +} + +static void +lx_do_copy(PixmapPtr pxDst, int srcX, int srcY, + int dstX, int dstY, int w, int h) +{ + int dstBpp = (pxDst->drawable.bitsPerPixel + 7) / 8; + int dstPitch = exaGetPixmapPitch(pxDst); + unsigned int srcOffset, dstOffset; + int flags = 0; + + gp_declare_blt(lx_copy_flags(srcX, srcY, dstX, dstY,w,h, exaScratch.op)); + + //gp_declare_blt(0); + + srcOffset = exaScratch.srcOffset + (exaScratch.srcPitch * srcY) + + (exaScratch.srcBpp) * srcX; + + dstOffset = exaGetPixmapOffset(pxDst) + (dstPitch * dstY) + + (dstBpp * dstX); + + flags = 0; + + if (dstX > srcX) + flags |= CIMGP_NEGXDIR; + + if (dstY > srcY) + flags |= CIMGP_NEGYDIR; + + gp_screen_to_screen_blt(dstOffset, srcOffset, w, h, flags); +} + +/* Composite operations + +These are the simplest - one pass operations - if there is no format or +mask, the we can make these happen pretty fast + + Operation Type Channel Alpha +PictOpClear 0 2 0 3 +PictOpSrc 0 3 0 3 +PictOpDst 0 3 1 3 +PictOpOver 2 0 0 3 +PictOpOverReverse 2 0 1 3 +PictOpIn 0 1 0 3 +PictOpInReverse 0 1 1 3 +PictOpOut 1 0 0 3 +PictOpOutReverse 1 0 1 3 +PictOpAdd 2 2 0 3 + +The following require multiple passes +PictOpAtop +PictOpXor +*/ + +struct blend_ops_t { + int operation; + int type; + int channel; +} lx_alpha_ops[] = { + /* PictOpClear */ + { CIMGP_ALPHA_TIMES_A, CIMGP_CONSTANT_ALPHA, CIMGP_CHANNEL_A_SOURCE }, { }, + /* PictOpSrc */ + { CIMGP_ALPHA_TIMES_A, CIMGP_ALPHA_EQUALS_ONE, CIMGP_CHANNEL_A_SOURCE }, { }, + /* PictOpDst */ + { CIMGP_ALPHA_TIMES_A, CIMGP_ALPHA_EQUALS_ONE, CIMGP_CHANNEL_A_DEST }, { }, + /* PictOpOver*/ + { CIMGP_A_PLUS_BETA_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_SOURCE }, { }, + /* PictOpOverReverse */ + { CIMGP_A_PLUS_BETA_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_DEST }, { }, + /* PictOpIn */ + { CIMGP_ALPHA_TIMES_A, CIMGP_CHANNEL_B_ALPHA, CIMGP_CHANNEL_A_SOURCE }, { }, + /* PictOpInReverse */ + { CIMGP_ALPHA_TIMES_A, CIMGP_CHANNEL_B_ALPHA, CIMGP_CHANNEL_A_DEST }, { }, + /* PictOpOut */ + { CIMGP_BETA_TIMES_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_SOURCE }, { }, + /* PictOpOutReverse */ + { CIMGP_BETA_TIMES_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_DEST }, { }, + /* SrcAtop */ + { CIMGP_ALPHA_TIMES_A, CIMGP_CHANNEL_B_ALPHA, CIMGP_CHANNEL_A_DEST }, + { CIMGP_BETA_TIMES_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_SOURCE }, + /* SrcAtopReverse */ + { CIMGP_ALPHA_TIMES_A, CIMGP_CHANNEL_B_ALPHA, CIMGP_CHANNEL_A_SOURCE }, + { CIMGP_BETA_TIMES_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_DEST }, + /* Xor */ + { CIMGP_BETA_TIMES_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_SOURCE }, + { CIMGP_BETA_TIMES_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_SOURCE }, + /* PictOpAdd */ + { CIMGP_A_PLUS_BETA_B, CIMGP_CONSTANT_ALPHA, CIMGP_CHANNEL_A_SOURCE }, { } +}; + + +#define ARRAY_SIZE(a) (sizeof((a)) / (sizeof(*(a)))) + +static const struct exa_format_t *lx_get_format(PicturePtr p) +{ + int i; + unsigned int format = p->format; + + for(i = 0; i < ARRAY_SIZE(lx_exa_formats); i++) { + + if (lx_exa_formats[i].bpp < PICT_FORMAT_BPP(format)) + break; + else if (lx_exa_formats[i].bpp != PICT_FORMAT_BPP(format)) + continue; + + if (lx_exa_formats[i].exa == format) + return (&lx_exa_formats[i]); + } + +#if 0 + ErrorF("Couldn't match on format %x\n", format); + ErrorF("BPP = %d, type = %d, ARGB(%d,%d,%d,%d)n", + PICT_FORMAT_BPP(format), + PICT_FORMAT_TYPE(format), + PICT_FORMAT_A(format), + PICT_FORMAT_R(format), + PICT_FORMAT_G(format), + PICT_FORMAT_B(format)); +#endif + + return NULL; +} + +static Bool lx_check_composite(int op, PicturePtr pSrc, PicturePtr pMsk, + PicturePtr pDst) +{ + GeodeRec *pGeode = GEODEPTR_FROM_PICTURE(pDst); + + /* Check that the operation is supported */ + + if (op > PictOpAdd) + return FALSE; + + /* Check that the filter matches what we support */ + + switch(pSrc->filter) { + case PictFilterNearest: + case PictFilterFast: + case PictFilterGood: + case PictFilterBest: + break; + + default: + ErrorF("invalid filter %d\n", pSrc->filter); + return FALSE; + } + + /* We don't handle transforms */ + + if (pSrc->transform) + return FALSE; + + /* We only support single pass operations at this point */ + + if (pMsk && usesPasses(op)) + return FALSE; + + + /* XXX - I don't understand PICT_a8 enough - so I'm punting */ + + if (pSrc->format == PICT_a8 || pDst->format == PICT_a8) + return FALSE; + + return TRUE; +} + +static Bool lx_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMsk, + PicturePtr pDst, PixmapPtr pxSrc, PixmapPtr pxMsk, + PixmapPtr pxDst) +{ + GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst); + const struct exa_format_t *srcFmt, *dstFmt; + int apply; + + /* Get the formats for the source and destination */ + + if ((srcFmt = lx_get_format(pSrc)) == NULL) { + ErrorF("EXA: Invalid source format %x\n", pSrc->format); + return FALSE; + } + + if ((dstFmt = lx_get_format(pDst)) == NULL) { + ErrorF("EXA: Invalid destination format %x\n", pDst->format); + return FALSE; + } + + /* Make sure operations that need alpha bits have them */ + /* If a mask is enabled, the alpha will come from there */ + + if (!pMsk && (!srcFmt->alphabits && usesSrcAlpha(op))) { + ErrorF("EXA: Source needs alpha bits\n"); + return FALSE; + } + + if (!pMsk && (!dstFmt->alphabits && usesDstAlpha(op))) { + ErrorF("EXA: Dest needs alpha bits\n"); + return FALSE; + } + + /* FIXME: See a way around this! */ + + if (srcFmt->alphabits == 0 && dstFmt->alphabits != 0) + return FALSE; + + /* Set up the scratch buffer with the information we need */ + + exaScratch.srcFormat = (struct exa_format_t *) srcFmt; + exaScratch.dstFormat = (struct exa_format_t *) dstFmt; + exaScratch.op = op; + exaScratch.repeat = pSrc->repeat; + exaScratch.bufferOffset = pGeode->exaBfrOffset; + + + if (pMsk && op != PictOpClear) { + unsigned int srcColor; + struct blend_ops_t *opPtr = &lx_alpha_ops[op * 2]; + int direction = (opPtr->channel == CIMGP_CHANNEL_A_SOURCE) ? 0 : 1; + + /* We can only do masks with a 8bpp or a 4bpp mask */ + + if (pMsk->format != PICT_a8 && pMsk->format != PICT_a4) + return FALSE; + + /* Direction 0 indicates src->dst, 1 indiates dst->src */ + + if (((direction == 0) && (pxSrc->drawable.bitsPerPixel < 16)) || + ((direction == 1) && (pxDst->drawable.bitsPerPixel < 16))) { + ErrorF("Can't do mask blending with less then 16bpp\n"); + return FALSE; + } + + /* FIXME: What to do here? */ + + if (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1) + return FALSE; + + /* Save off the info we need (reuse the source values to save space) */ + + exaScratch.type = COMP_TYPE_MASK; + + exaScratch.srcOffset = exaGetPixmapOffset(pxMsk); + exaScratch.srcPitch = exaGetPixmapPitch(pxMsk); + exaScratch.srcBpp = (pxMsk->drawable.bitsPerPixel + 7) / 8; + + exaScratch.srcWidth = pMsk->pDrawable->width; + exaScratch.srcHeight = pMsk->pDrawable->height; + + /* Flag to indicate if this a 8BPP or a 4BPP mask */ + exaScratch.fourBpp = (pxMsk->drawable.bitsPerPixel == 4) ? 1 : 0; + + /* If the direction is reversed, then remember the source */ + + if (direction == 1) + exaScratch.srcPixmap = pxSrc; + + /* Extract the source color to use */ + + if (direction == 0) + srcColor = lx_get_source_color(pSrc, 0, 0, pDst->format); + else + srcColor = lx_get_source_color(pDst, 0, 0, pSrc->format); + + /* Build part of the blt now to save time later */ + + gp_declare_blt (0); + gp_set_solid_source (srcColor); + gp_write_parameters(); + } + else { + if (usesPasses(op)) + exaScratch.type = COMP_TYPE_TWOPASS; + else + exaScratch.type = COMP_TYPE_ONEPASS; + + exaScratch.srcOffset = exaGetPixmapOffset(pxSrc); + exaScratch.srcPitch = exaGetPixmapPitch(pxSrc); + exaScratch.srcBpp = (pxSrc->drawable.bitsPerPixel + 7) / 8; + + exaScratch.srcWidth = pSrc->pDrawable->width; + exaScratch.srcHeight = pSrc->pDrawable->height; + } + + return TRUE; +} + +int lx_get_bpp_from_format(int format) { + + switch(format) { + case CIMGP_SOURCE_FMT_8_8_8_8: + case CIMGP_SOURCE_FMT_32BPP_BGR: + return 32; + + case CIMGP_SOURCE_FMT_4_4_4_4: + return 12; + + case CIMGP_SOURCE_FMT_0_5_6_5: + case CIMGP_SOURCE_FMT_16BPP_BGR: + return 16; + + case CIMGP_SOURCE_FMT_1_5_5_5: + case CIMGP_SOURCE_FMT_15BPP_BGR: + return 15; + + case CIMGP_SOURCE_FMT_3_3_2: + return 8; + } + + return 0; +} + +int lx_get_alpha_one(int format) +{ + switch(format) { + case CIMGP_SOURCE_FMT_8_8_8_8: + case CIMGP_SOURCE_FMT_32BPP_BGR: + return 0xFF << 16; + + case CIMGP_SOURCE_FMT_4_4_4_4: + return 0xF << 12; + + case CIMGP_SOURCE_FMT_1_5_5_5: + case CIMGP_SOURCE_FMT_15BPP_BGR: + return 1 << 15; + } + + return 0; +} + +static lx_set_source_format(int srcFormat, int dstFormat) +{ + /* If BGR is set in the destination, then move the BGR bit to the source */ + /* If they are both BGR, then don't set the bit */ + + if (!(srcFormat & 0x10) && (dstFormat & 0x10)) + gp_set_source_format(srcFormat | 0x10); + else if ((srcFormat & 0x10) && (dstFormat & 0x10)) + gp_set_source_format(srcFormat & ~0x10); + else + gp_set_source_format(srcFormat); +} + + +#if 1 + +static void +lx_composite_onepass(PixmapPtr pxDst, unsigned long dstOffset, + unsigned long srcOffset, int width, int height) +{ + struct blend_ops_t *opPtr; + int apply; + + opPtr = &lx_alpha_ops[exaScratch.op * 2]; + + apply = (exaScratch.dstFormat->alphabits != 0 && + exaScratch.srcFormat->alphabits != 0) ? + CIMGP_APPLY_BLEND_TO_ALL : CIMGP_APPLY_BLEND_TO_RGB; + + gp_declare_blt(0); + gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt)); + gp_set_strides(exaGetPixmapPitch(pxDst), exaScratch.srcPitch); + + lx_set_source_format(exaScratch.srcFormat->fmt, exaScratch.dstFormat->fmt); + + gp_set_alpha_operation(opPtr->operation, opPtr->type, opPtr->channel, + apply, 0); + + gp_screen_to_screen_convert(dstOffset, srcOffset, width, height, 0); +} + +#else + +/* XXX - For now, we assume that the conversion will fit */ + +static void +lx_composite_onepass(PixmapPtr pxDst, unsigned long dstOffset, + unsigned long srcOffset, int width, int height) +{ + struct blend_ops_t *opPtr; + int apply; + int sbpp = lx_get_bpp_from_format(exaScratch.srcFormat->fmt); + + /* Copy the destination into the scratch buffer */ + + gp_declare_blt(0); + + gp_set_bpp(sbpp); + + gp_set_source_format(exaScratch.dstFormat->fmt); + + gp_set_raster_operation(0xCC); + gp_set_strides(exaScratch.srcPitch, exaGetPixmapPitch(pxDst)); + gp_screen_to_screen_convert(exaScratch.bufferOffset, dstOffset, width, + height, 0); + + /* Do the blend */ + + opPtr = &lx_alpha_ops[exaScratch.op * 2]; + apply = (exaScratch.srcFormat->alphabits == 0) ? + CIMGP_APPLY_BLEND_TO_RGB : CIMGP_APPLY_BLEND_TO_ALL; + + gp_declare_blt (0); + gp_set_bpp(sbpp); + + gp_set_alpha_operation(opPtr->operation, opPtr->type, opPtr->channel, + apply, 0); + + gp_set_strides(exaScratch.srcPitch, exaScratch.srcPitch); + gp_screen_to_screen_blt(exaScratch.bufferOffset, srcOffset, + width, height, 0); + + /* And copy back */ + + gp_declare_blt(0); + gp_set_bpp(pxDst->drawable.bitsPerPixel); + gp_set_source_format (exaScratch.srcFormat->fmt); + gp_set_raster_operation(0xCC); + gp_set_strides(exaGetPixmapPitch(pxDst), exaScratch.srcPitch); + gp_screen_to_screen_convert(dstOffset, exaScratch.bufferOffset, + width, height, 0); +} + +#endif + +#if 0 + +lx_composite_convert(PixmapPtr pxDst, unsigned long dstOffset, + unsigned long srcOffset, int width, int height) +{ + /* Step 1 - copy the destination into the scratch buffer */ + + ErrorF("Convert\n"); + + gp_declare_blt(0); + gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt)); + + gp_set_raster_operation(0xCC); + gp_set_strides(exaGetPixmapPitch(pxDst), exaGetPixmapPitch(pxDst)); + + gp_screen_to_screen_blt(exaScratch.bufferOffset, dstOffset, width, height, 0); + + /* Step 2 - Do the original blend */ + + lx_composite_onepass(pxDst, exaScratch.bufferOffset, srcOffset, width, height); + + /* Step 3 - copy back and fixup the alpha */ + gp_declare_blt(0); + gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt)); + gp_set_strides(exaGetPixmapPitch(pxDst), exaGetPixmapPitch(pxDst)); + + /* FIXME: Does this alpha value need to be changed for the mode? */ + + gp_set_alpha_operation(CIMGP_ALPHA_TIMES_A, CIMGP_CONSTANT_ALPHA, + CIMGP_CHANNEL_A_SOURCE, CIMGP_APPLY_BLEND_TO_ALPHA, + 1); + + gp_screen_to_screen_blt(dstOffset, exaScratch.bufferOffset, width, height, 0); +} + +#endif + +/* This function handles the multipass blend functions */ + +static void +lx_composite_multipass(PixmapPtr pxDst, unsigned long dstOffset, unsigned long srcOffset, int width, int height) +{ + struct blend_ops_t *opPtr; + int sbpp = lx_get_bpp_from_format(exaScratch.srcFormat->fmt); + int apply; + + /* Copy the destination to the scratch buffer, and convert it to the source format */ + + gp_declare_blt(0); + + gp_set_bpp(sbpp); + gp_set_source_format(exaScratch.dstFormat->fmt); + gp_set_raster_operation(0xCC); + gp_set_strides(exaScratch.srcPitch, exaGetPixmapPitch(pxDst)); + gp_screen_to_screen_convert(exaScratch.bufferOffset, dstOffset, width, height, 0); + + /* Do the first blend from the source to the scratch buffer */ + + gp_declare_blt(0); + gp_set_bpp(sbpp); + gp_set_source_format(exaScratch.srcFormat->fmt); + + opPtr = &lx_alpha_ops[exaScratch.op * 2]; + + apply = (exaScratch.srcFormat->alphabits == 0) ? + CIMGP_APPLY_BLEND_TO_RGB : CIMGP_APPLY_BLEND_TO_ALL; + + gp_set_alpha_operation(opPtr->operation, opPtr->type, opPtr->channel, + apply, 0); + + gp_set_strides(exaScratch.srcPitch, exaScratch.srcPitch); + gp_screen_to_screen_blt(exaScratch.bufferOffset, srcOffset, width, height, 0); + + /* Finally, do the second blend back to the destination */ + + opPtr = &lx_alpha_ops[(exaScratch.op * 2) + 1]; + + apply = (exaScratch.dstFormat->alphabits == 0) ? + CIMGP_APPLY_BLEND_TO_RGB : CIMGP_APPLY_BLEND_TO_ALL; + + gp_declare_blt(0); + gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt)); + + /* The only way to kick BGR is to set it in the source */ + + lx_set_source_format(exaScratch.srcFormat->fmt, exaScratch.dstFormat->fmt); + + gp_set_alpha_operation(opPtr->operation, opPtr->type, opPtr->channel, + apply, 0); + + gp_screen_to_screen_convert(dstOffset, exaScratch.bufferOffset, width, height, 0); +} + +static void +lx_do_composite_mask(PixmapPtr pxDst, unsigned long dstOffset, unsigned int maskOffset, + int width, int height) +{ + GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst); + unsigned char *data = pGeode->FBBase + maskOffset; + + struct blend_ops_t *opPtr = &lx_alpha_ops[exaScratch.op * 2]; + + gp_declare_blt (0); + gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt)); + + gp_blend_mask_blt(dstOffset, 0, width, height, data, + exaScratch.srcPitch, opPtr->operation, + exaScratch.fourBpp); +} + +#define GetPixmapOffset(px, x, y) ( exaGetPixmapOffset((px)) + \ + (exaGetPixmapPitch((px)) * (y)) + \ + ((((px)->drawable.bitsPerPixel + 7) / 8) * (x)) ) + + +static void +lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX, + int maskY, int dstX, int dstY, int width, int height) { + + struct blend_ops_t *opPtr = &lx_alpha_ops[exaScratch.op * 2]; + + unsigned int dstBpp = (pxDst->drawable.bitsPerPixel + 7) / 8; + unsigned int dstPitch = exaGetPixmapPitch(pxDst); + unsigned int dstOffset, srcOffset; + + unsigned int opX = dstX; + unsigned int opY = dstY; + unsigned int opWidth = width; + unsigned int opHeight = height; + + if (exaScratch.type == COMP_TYPE_MASK) + srcOffset = exaScratch.srcOffset + (maskY * exaScratch.srcPitch) + + (maskX * exaScratch.srcBpp); + else + srcOffset = exaScratch.srcOffset + (srcY * exaScratch.srcPitch) + + (srcX * exaScratch.srcBpp); + + /* Adjust the width / height of the operation the size of the source */ + + if (exaScratch.srcWidth < width) + opWidth = exaScratch.srcWidth; + + if (exaScratch.srcHeight < height) + opHeight = exaScratch.srcHeight; + + while(1) { + dstOffset = GetPixmapOffset(pxDst, dstX, dstY); + + switch(exaScratch.type) { + case COMP_TYPE_MASK: { + int direction = (opPtr->channel == CIMGP_CHANNEL_A_SOURCE) ? 0 : 1; + + if (direction == 1) { + dstOffset = GetPixmapOffset(exaScratch.srcPixmap, dstX,dstY); + lx_do_composite_mask(exaScratch.srcPixmap, dstOffset, srcOffset, opWidth, opHeight); + } + else { + lx_do_composite_mask(pxDst, dstOffset, srcOffset, opWidth, opHeight); + } + } + break; + + case COMP_TYPE_ONEPASS: + lx_composite_onepass(pxDst, dstOffset, srcOffset, opWidth, opHeight); + break; + + case COMP_TYPE_TWOPASS: + lx_composite_multipass(pxDst, dstOffset, srcOffset, opWidth, opHeight); + break; + } + + if (!exaScratch.repeat) + break; + + opX += opWidth; + + if (opX >= dstX + width) { + opX = dstX; + opY += opHeight; + + if (opY >= dstY + height) + break; + } + + opWidth = ((dstX + width) - opX) > exaScratch.srcWidth ? + exaScratch.srcWidth : (dstX + width) - opX; + opHeight = ((dstY + height) - opY) > exaScratch.srcHeight ? + exaScratch.srcHeight : (dstY + height) - opY; + } +} + +static void lx_wait_marker(ScreenPtr PScreen, int marker) +{ + gp_wait_until_idle(); +} + +static void lx_done(PixmapPtr ptr) +{ +} + +static Bool lx_upload(PixmapPtr pDst, int x, int y, int w, int h, + char *src, int src_pitch) +{ + char *dst = pDst->devPrivate.ptr; + int dpitch = exaGetPixmapPitch(pDst); + int bpp = pDst->drawable.bitsPerPixel; + GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pDst); + unsigned long offset; + + dst += (y * dpitch) + (x * (bpp >> 3)); + + gp_declare_blt(0); + + gp_set_bpp(bpp); + gp_set_raster_operation(0xCC); + gp_set_strides(dpitch, src_pitch); + gp_set_solid_pattern(0); + + offset = ((unsigned long) dst) - ((unsigned long) pGeode->FBBase); + gp_color_bitmap_to_screen_blt(offset, 0, w, h, src, src_pitch); + return TRUE; +} + +static Bool lx_download(PixmapPtr pSrc, int x, int y, int w, int h, + char *dst, int dst_pitch) +{ + char *src = pSrc->devPrivate.ptr; + int spitch = exaGetPixmapPitch(pSrc); + int bpp = pSrc->drawable.bitsPerPixel; + + src += (y * spitch) + (x * (bpp >> 3)); + + geode_memory_to_screen_blt((unsigned long)src, (unsigned long)dst, + spitch, dst_pitch, w, h, bpp); + return TRUE; +} + + +Bool LXExaInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; + GeodeRec *pGeode = GEODEPTR(pScrni); + ExaDriverPtr pExa = pGeode->pExa; + + pExa->exa_major = EXA_VERSION_MAJOR; + pExa->exa_minor = EXA_VERSION_MINOR; + + pExa->WaitMarker = lx_wait_marker; + + pExa->UploadToScreen = lx_upload; + pExa->DownloadFromScreen = lx_download; + + pExa->PrepareSolid = lx_prepare_solid; + pExa->Solid = lx_do_solid; + pExa->DoneSolid = lx_done; + + pExa->PrepareCopy = lx_prepare_copy; + pExa->Copy = lx_do_copy; + pExa->DoneCopy = lx_done; + + /* Composite */ + pExa->CheckComposite = lx_check_composite; + pExa->PrepareComposite = lx_prepare_composite; + pExa->Composite = lx_do_composite; + pExa->DoneComposite = lx_done; + + return exaDriverInit(pScreen, pGeode->pExa); +} diff --git a/src/amd_lx_randr.c b/src/amd_lx_randr.c new file mode 100644 index 0000000..7b93ae0 --- /dev/null +++ b/src/amd_lx_randr.c @@ -0,0 +1,331 @@ +/* Originally derived from the Intel example + * Copyright (C) 2002 Keith Packard, member of The XFree86 Project, Inc. + + * Copyright (c) 2006 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Neither the name of the Advanced Micro Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + */ + +#include "xf86.h" +#include "os.h" +#include "mibank.h" +#include "globals.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86DDC.h" +#include "mipointer.h" +#include "windowstr.h" +#include <X11/extensions/randr.h> +#include <randrstr.h> + +#include "amd.h" + +static int LXRandRIndex; +static int LXRandRGeneration; + +typedef struct _LXRandRInfo +{ + int virtualX; + int virtualY; + int mmWidth; + int mmHeight; + int maxX; + int maxY; + Rotation rotation; /* current mode */ + Rotation supported_rotations; /* driver supported */ +} XF86RandRInfoRec, *XF86RandRInfoPtr; + +#define XF86RANDRINFO(p) ((XF86RandRInfoPtr) (p)->devPrivates[LXRandRIndex].ptr) + +static int +LXRandRModeRefresh(DisplayModePtr mode) +{ + if (mode->VRefresh) + return (int)(mode->VRefresh + 0.5); + else + return (int)(mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + + 0.5); +} + +static Bool +LXRandRGetInfo(ScreenPtr pScreen, Rotation * rotations) +{ + RRScreenSizePtr pSize; + ScrnInfoPtr pScrni = XF86SCRNINFO(pScreen); + XF86RandRInfoPtr pRandr = XF86RANDRINFO(pScreen); + DisplayModePtr mode; + int refresh0 = 60; + int maxX = 0, maxY = 0; + + *rotations = pRandr->supported_rotations; + + if (pRandr->virtualX == -1 || pRandr->virtualY == -1) { + pRandr->virtualX = pScrni->virtualX; + pRandr->virtualY = pScrni->virtualY; + } + + for (mode = pScrni->modes;; mode = mode->next) { + int refresh = LXRandRModeRefresh(mode); + + if (pRandr->maxX == 0 || pRandr->maxY == 0) { + if (maxX < mode->HDisplay) + maxX = mode->HDisplay; + if (maxY < mode->VDisplay) + maxY = mode->VDisplay; + } + + if (mode == pScrni->modes) + refresh0 = refresh; + + pSize = RRRegisterSize(pScreen, + mode->HDisplay, mode->VDisplay, + pRandr->mmWidth, pRandr->mmHeight); + if (!pSize) + return FALSE; + + RRRegisterRate(pScreen, pSize, refresh); + + if (mode == pScrni->currentMode && + mode->HDisplay == pScrni->virtualX + && mode->VDisplay == pScrni->virtualY) + RRSetCurrentConfig(pScreen, pRandr->rotation, refresh, pSize); + if (mode->next == pScrni->modes) + break; + } + + if (pRandr->maxX == 0 || pRandr->maxY == 0) { + pRandr->maxX = maxX; + pRandr->maxY = maxY; + } + + if (pScrni->currentMode->HDisplay != pScrni->virtualX || + pScrni->currentMode->VDisplay != pScrni->virtualY) { + + mode = pScrni->modes; + pSize = RRRegisterSize(pScreen, + pRandr->virtualX, pRandr->virtualY, + pRandr->mmWidth, pRandr->mmHeight); + if (!pSize) + return FALSE; + + RRRegisterRate(pScreen, pSize, refresh0); + if (pScrni->virtualX == pRandr->virtualX && + pScrni->virtualY == pRandr->virtualY) { + RRSetCurrentConfig(pScreen, pRandr->rotation, refresh0, pSize); + } + } + + return TRUE; +} + +static Bool +LXRandRSetMode(ScreenPtr pScreen, + DisplayModePtr mode, Bool useVirtual, int mmWidth, int mmHeight) +{ + ScrnInfoPtr pScrni = XF86SCRNINFO(pScreen); + XF86RandRInfoPtr pRandr = XF86RANDRINFO(pScreen); + + int oldWidth = pScreen->width; + int oldHeight = pScreen->height; + int oldmmWidth = pScreen->mmWidth; + int oldmmHeight = pScreen->mmHeight; + WindowPtr pRoot = WindowTable[pScreen->myNum]; + DisplayModePtr currentMode = NULL; + Bool ret = TRUE; + PixmapPtr pspix = NULL; + + if (pRoot) + (*pScrni->EnableDisableFBAccess) (pScreen->myNum, FALSE); + + if (useVirtual) { + pScrni->virtualX = pRandr->virtualX; + pScrni->virtualY = pRandr->virtualY; + } else { + pScrni->virtualX = mode->HDisplay; + pScrni->virtualY = mode->VDisplay; + } + + if (pRandr->rotation & (RR_Rotate_90 | RR_Rotate_270)) { + pScreen->width = pScrni->virtualY; + pScreen->height = pScrni->virtualX; + pScreen->mmWidth = mmHeight; + pScreen->mmHeight = mmWidth; + } else { + pScreen->width = pScrni->virtualX; + pScreen->height = pScrni->virtualY; + pScreen->mmWidth = mmWidth; + pScreen->mmHeight = mmHeight; + } + + if (pScrni->currentMode == mode) { + currentMode = pScrni->currentMode; + pScrni->currentMode = NULL; + } + + if (!xf86SwitchMode(pScreen, mode)) { + ret = FALSE; + pScrni->virtualX = pScreen->width = oldWidth; + pScrni->virtualY = pScreen->height = oldHeight; + pScreen->mmWidth = oldmmWidth; + pScreen->mmHeight = oldmmHeight; + pScrni->currentMode = currentMode; + } + + /* + * Get the new Screen pixmap ptr as SwitchMode might have called + * ModifyPixmapHeader and xf86EnableDisableFBAccess will put it back... + * Unfortunately. + + */ + + pspix = (*pScreen->GetScreenPixmap) (pScreen); + if (pspix->devPrivate.ptr) + pScrni->pixmapPrivate = pspix->devPrivate; + + xf86ReconfigureLayout(); + + xf86SetViewport(pScreen, pScreen->width, pScreen->height); + xf86SetViewport(pScreen, 0, 0); + + if (pRoot) + (*pScrni->EnableDisableFBAccess) (pScreen->myNum, TRUE); + + return ret; +} + +Bool +LXRandRSetConfig(ScreenPtr pScreen, Rotation rotation, + int rate, RRScreenSizePtr pSize) +{ + ScrnInfoPtr pScrni = XF86SCRNINFO(pScreen); + XF86RandRInfoPtr pRandr = XF86RANDRINFO(pScreen); + + DisplayModePtr mode; + int px, py; + Bool useVirtual = FALSE; + int maxX = 0, maxY = 0; + Rotation oldRotation = pRandr->rotation; + + pRandr->rotation = rotation; + + if (pRandr->virtualX == -1 || pRandr->virtualY == -1) { + pRandr->virtualX = pScrni->virtualX; + pRandr->virtualY = pScrni->virtualY; + } + + miPointerPosition(&px, &py); + + for (mode = pScrni->modes;; mode = mode->next) { + if (pRandr->maxX == 0 || pRandr->maxY == 0) { + if (maxX < mode->HDisplay) + maxX = mode->HDisplay; + if (maxY < mode->VDisplay) + maxY = mode->VDisplay; + } + if (mode->HDisplay == pSize->width && + mode->VDisplay == pSize->height && + (rate == 0 || LXRandRModeRefresh(mode) == rate)) + break; + if (mode->next == pScrni->modes) { + if (pSize->width == pRandr->virtualX && + pSize->height == pRandr->virtualY) { + mode = pScrni->modes; + useVirtual = TRUE; + break; + } + if (pRandr->maxX == 0 || pRandr->maxY == 0) { + pRandr->maxX = maxX; + pRandr->maxY = maxY; + } + return FALSE; + } + } + + if (pRandr->maxX == 0 || pRandr->maxY == 0) { + pRandr->maxX = maxX; + pRandr->maxY = maxY; + } + + if (!LXRandRSetMode(pScreen, mode, useVirtual, pSize->mmWidth, + pSize->mmHeight)) { + pRandr->rotation = oldRotation; + return FALSE; + } + + if (pScreen == miPointerCurrentScreen()) { + px = (px >= pScreen->width ? (pScreen->width - 1) : px); + py = (py >= pScreen->height ? (pScreen->height - 1) : py); + + xf86SetViewport(pScreen, px, py); + + (*pScreen->SetCursorPosition) (pScreen, px, py, FALSE); + } + + return TRUE; +} + +Rotation +LXGetRotation(ScreenPtr pScreen) +{ + XF86RandRInfoPtr pRandr = XF86RANDRINFO(pScreen); + + return pRandr->rotation; +} + +Bool +LXRandRInit(ScreenPtr pScreen, int rotation) +{ + XF86RandRInfoPtr pRandr; + rrScrPrivPtr rp; + + if (LXRandRGeneration != serverGeneration) { + LXRandRIndex = AllocateScreenPrivateIndex(); + LXRandRGeneration = serverGeneration; + } + + pRandr = xcalloc(sizeof(XF86RandRInfoRec), 1); + if (pRandr == NULL) + return FALSE; + + if (!RRScreenInit(pScreen)) { + xfree(pRandr); + return FALSE; + } + + rp = rrGetScrPriv(pScreen); + rp->rrGetInfo = LXRandRGetInfo; + rp->rrSetConfig = LXRandRSetConfig; + + pRandr->virtualX = -1; + pRandr->virtualY = -1; + + pRandr->mmWidth = pScreen->mmWidth; + pRandr->mmHeight = pScreen->mmHeight; + + pRandr->rotation = RR_Rotate_0; + pRandr->supported_rotations = rotation; + pRandr->maxX = pRandr->maxY = 0; + + pScreen->devPrivates[LXRandRIndex].ptr = pRandr; + return TRUE; +} diff --git a/src/amd_lx_rotate.c b/src/amd_lx_rotate.c new file mode 100644 index 0000000..a9b8f28 --- /dev/null +++ b/src/amd_lx_rotate.c @@ -0,0 +1,246 @@ +/* Copyrightg (c) 2007 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Neither the name of the Advanced Micro Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "shadow.h" +#include "amd.h" + +static void * +LXWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, + CARD32 * size, void *closure) +{ + ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; + GeodeRec *pGeode = GEODEPTR(pScrni); + + *size = pGeode->displayPitch; + + return (pGeode->FBBase + pGeode->displayOffset) + + row * pGeode->displayPitch + offset; +} + +void +LXUpdateFunc(ScreenPtr pScreen, shadowBufPtr pBuf) +{ + RegionPtr damage = shadowDamage (pBuf); + + int nbox = REGION_NUM_RECTS (damage); + BoxPtr pbox = REGION_RECTS (damage); + int x, y, w, h, degrees; + FbStride shaStride; + FbBits *shaBits; + int shaBpp, dx, dy,dw, dh; + int shaXoff, shaYoff; + unsigned int srcOffset, dstOffset; + PixmapPtr pShadow = pBuf->pPixmap; + ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; + GeodeRec *pGeode = GEODEPTR(pScrni); + + unsigned int srcBase; + + fbGetDrawable (&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, + shaYoff); + + /* Set up the blt */ + + gp_declare_blt(0); + + switch(shaBpp) { + case 8: + gp_set_source_format(CIMGP_SOURCE_FMT_3_3_2); + break; + + case 16: + gp_set_source_format(CIMGP_SOURCE_FMT_0_5_6_5); + break; + + case 32: + gp_set_source_format(CIMGP_SOURCE_FMT_8_8_8_8); + break; + } + + gp_set_bpp(pScrni->bitsPerPixel); + gp_set_raster_operation(0xCC); + gp_write_parameters(); + + while(nbox--) { + x = pbox->x1; + y = pbox->y1; + w = (pbox->x2 - pbox->x1); + h = pbox->y2 - pbox->y1; + + srcOffset = ((unsigned long) shaBits) - ((unsigned long) pGeode->FBBase); + srcOffset += (y * pGeode->Pitch) + (x * (shaBpp >> 3)); + + switch(pGeode->rotation) { + case RR_Rotate_90: + dx = (pScrni->pScreen->height - 1) - (y + (h-1)); + dy = x; + dw = h; + dh = w; + degrees = 90; + break; + + case RR_Rotate_180: + dx = (pScrni->pScreen->width - 1) - (x + (w-1)); + dy = (pScrni->pScreen->height - 1) - (y + (h-1)); + dw = w; + dh = h; + + degrees = 180; + break; + + case RR_Rotate_270: + dy = (pScrni->pScreen->width - 1) - (x + (w-1)); + dx = y; + dw = h; + dh = w; + + degrees = 270; + break; + } + + dstOffset = pGeode->displayOffset + + (dy * pGeode->displayPitch) + (dx * (pScrni->bitsPerPixel >> 3)); + + gp_declare_blt(0); + gp_set_strides(pGeode->displayPitch, pGeode->Pitch); + gp_rotate_blt(dstOffset, srcOffset, w, h, degrees); + } +} + +Bool +LXRotate(ScrnInfoPtr pScrni, DisplayModePtr mode) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + Rotation curr = pGeode->rotation; + unsigned int curdw = pScrni->displayWidth; + PixmapPtr pPixmap; + BOOL ret; + + pPixmap = pScrni->pScreen->GetScreenPixmap(pScrni->pScreen); + pGeode->rotation = LXGetRotation(pScrni->pScreen); + + /* Leave if we have nothing to do */ + + if (pGeode->rotation == curr && pGeode->curMode == mode) { + return TRUE; + } + + shadowRemove(pScrni->pScreen, NULL); + + switch (pGeode->rotation) { + case RR_Rotate_0: + ErrorF("Rotate to 0 degrees\n"); + pScrni->displayWidth = pGeode->displayWidth; + break; + + case RR_Rotate_90: + ErrorF("Rotate to 90 degrees\n"); + pScrni->displayWidth = pScrni->pScreen->width; + break; + + case RR_Rotate_180: + ErrorF("Rotate to 180 degrees\n"); + pScrni->displayWidth = pGeode->displayWidth; + break; + + case RR_Rotate_270: + ErrorF("Rotate to 270 degrees\n"); + pScrni->displayWidth = pScrni->pScreen->width; + break; + } + + /* Set the new drawing pitch */ + + if (pGeode->Compression) + pGeode->Pitch = LXCalculatePitchBytes(pScrni->displayWidth, + pScrni->bitsPerPixel); + else + pGeode->Pitch = (pScrni->displayWidth * + (pScrni->bitsPerPixel >> 3)); + + if (pGeode->rotation != RR_Rotate_0) { + + + ret = shadowAdd(pScrni->pScreen, pPixmap, LXUpdateFunc, + LXWindowLinear, pGeode->rotation, NULL); + + /* XXX - FIXME - bail gracefully */ + + if (!ret) + ErrorF("shadowAdd failed\n"); + } + + if (pGeode->rotation == RR_Rotate_0) + pScrni->fbOffset = pGeode->displayOffset; + else + pScrni->fbOffset = pGeode->shadowOffset; + + pScrni->pScreen->ModifyPixmapHeader(pPixmap, + pScrni->pScreen->width, + pScrni->pScreen->height, + pScrni->pScreen->rootDepth, + pScrni->bitsPerPixel, + PixmapBytePad(pScrni->displayWidth, pScrni->pScreen->rootDepth), + (pointer) (pGeode->FBBase + pScrni->fbOffset)); + + /* Don't use XAA pixmap cache or offscreen pixmaps when rotated */ + + if (pGeode->AccelInfoRec) { + if (pGeode->rotation == RR_Rotate_0) { + pGeode->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE; + pGeode->AccelInfoRec->UsingPixmapCache = TRUE; + pGeode->AccelInfoRec->maxOffPixWidth = 0; + pGeode->AccelInfoRec->maxOffPixHeight = 0; + } + else { + pGeode->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER; + pGeode->AccelInfoRec->UsingPixmapCache = FALSE; + pGeode->AccelInfoRec->maxOffPixWidth = 1; + pGeode->AccelInfoRec->maxOffPixHeight = 1; + } + } + + return TRUE; + +error: + /* Restore the old rotation */ + pScrni->displayWidth = curdw; + + if (curr & (RR_Rotate_0 | RR_Rotate_180)) { + pScrni->pScreen->width = pScrni->virtualX; + pScrni->pScreen->height = pScrni->virtualY; + } else { + pScrni->pScreen->width = pScrni->virtualY; + pScrni->pScreen->height = pScrni->virtualX; + } + + pGeode->rotation = curr; + return FALSE; +} diff --git a/src/amd_lx_shadow.c b/src/amd_lx_shadow.c deleted file mode 100644 index 8440c4e..0000000 --- a/src/amd_lx_shadow.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - * Copyright (c) 2006 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Neither the name of the Advanced Micro Devices, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - */ - -/* - * File Contents: Direct graphics display routines are implemented and - * graphics rendering are all done in memory. - * - * Project: Geode Xfree Frame buffer device driver. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "xf86.h" -#include "xf86_OSproc.h" -#include "xf86Resources.h" -#include "xf86_ansic.h" -#include "xf86PciInfo.h" -#include "xf86Pci.h" -#include "amd.h" -#include "shadowfb.h" -#include "servermd.h" - -#define CLIP(sip,bp,u1,v1,u2,v2) \ - u1 = bp->x1; v1 = bp->y1; \ - u2 = bp->x2; v2 = bp->y2; \ - if( u1 < 0 ) u1 = 0; \ - if( v1 < 0 ) v1 = 0; \ - if( u1 > sip->virtualX ) u1 = sip->virtualX; \ - if( v1 > sip->virtualY ) v1 = sip->virtualY; \ - if( u2 < 0 ) u2 = 0; \ - if( v2 < 0 ) v2 = 0; \ - if( u2 > sip->virtualX ) u2 = sip->virtualX; \ - if( v2 > sip->virtualY ) v2 = sip->virtualY; - -void LXAccelSync(ScrnInfoPtr pScrni); - -void -LXRotation0(int x, int y, int w, int h, int *newX, int *newY) -{ - *newX = x; - *newY = y; -} - -void -LXRotation1(int x, int y, int w, int h, int *newX, int *newY) -{ - *newX = (h - 1) - y; - *newY = x; -} - -void -LXRotation2(int x, int y, int w, int h, int *newX, int *newY) -{ - *newX = (w - 1) - x; - *newY = (h - 1) - y; -} - -void -LXRotation3(int x, int y, int w, int h, int *newX, int *newY) -{ - *newY = (w - 1) - x; - *newX = y; -} - -void -LXRBltXlat0(int x, int y, int w, int h, int *newX, int *newY) -{ - *newX = x; - *newY = y; -} - -void -LXRBltXlat1(int x, int y, int w, int h, int *newX, int *newY) -{ - *newX = x - (h - 1); - *newY = y; -} - -void -LXRBltXlat2(int x, int y, int w, int h, int *newX, int *newY) -{ - *newX = x - (w - 1); - *newY = y - (h - 1); -} - -void -LXRBltXlat3(int x, int y, int w, int h, int *newX, int *newY) -{ - *newX = x; - *newY = y - (w - 1); -} - -/*---------------------------------------------------------------------------- - * LXPointerMoved. - * - * Description :This function moves one screen memory from one area to other. - * - * Parameters. - * index :Pointer to screen index. - * x :Specifies the new x co-ordinates of new area. - * y :Specifies the new y co-ordinates of new area. - * Returns :none - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ -void -LXPointerMoved(int index, int x, int y) -{ - ScrnInfoPtr pScrni = xf86Screens[index]; - GeodeRec *pGeode = GEODEPTR(pScrni); - Bool frameChanged = FALSE; - - if (x < 0) - x = 0; - else if (x >= pScrni->virtualX) - x = pScrni->virtualX - 1; - - if (y < 0) - y = 0; - else if (y >= pScrni->virtualY) - y = pScrni->virtualY - 1; - - if (pScrni->frameX0 > x) { - pScrni->frameX0 = x; - pScrni->frameX1 = x + pGeode->HDisplay - 1; - frameChanged = TRUE; - } - - if (pScrni->frameX1 < x) { - pScrni->frameX1 = x + 1; - pScrni->frameX0 = x - pGeode->HDisplay + 1; - frameChanged = TRUE; - } - - if (pScrni->frameY0 > y) { - pScrni->frameY0 = y; - pScrni->frameY1 = y + pGeode->VDisplay - 1; - frameChanged = TRUE; - } - - if (pScrni->frameY1 < y) { - pScrni->frameY1 = y; - pScrni->frameY0 = y - pGeode->VDisplay + 1; - frameChanged = TRUE; - } - - if (frameChanged && pScrni->AdjustFrame != NULL) - pScrni->AdjustFrame(pScrni->scrnIndex, pScrni->frameX0, - pScrni->frameY0, 0); -} - -void -LXRefreshArea_Cpy(ScrnInfoPtr pScrni, int num, BoxPtr pbox) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - int x1, y1, x2, y2, width, height; - unsigned long src, dst; - int Bpp = pScrni->bitsPerPixel >> 3; - - gp_declare_blt(0); - gp_set_raster_operation(0xcc); /* copy dst=src */ - gp_write_parameters(); - for (; --num >= 0; ++pbox) { - CLIP(pScrni, pbox, x1, y1, x2, y2); - if ((width = x2 - x1) <= 0 || (height = y2 - y1) <= 0) - continue; - src = y1 * pGeode->ShadowPitch + x1 * Bpp; - dst = pGeode->FBOffset + y1 * pGeode->Pitch + x1 * Bpp; - gp_declare_blt(0); - gp_set_strides(pGeode->Pitch, pGeode->ShadowPitch); - gp_screen_to_screen_blt(dst, src, width, height, 0); - } -} - -/*---------------------------------------------------------------------------- - * LXRefreshArea8. - * - * Description :This function copies the memory to be displayed from the - * shadow pointer by 8bpp. - * Parameters. - * pScrni :Pointer to ScrnInfo structure. - * num :Specifies the num of squarebox area to be displayed. - * pbox :Points to square of memory to be displayed. - * Returns :none - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ - -static int lx_shdw_fmt[4] = { - CIMGP_SOURCE_FMT_3_3_2, - CIMGP_SOURCE_FMT_0_5_6_5, - CIMGP_SOURCE_FMT_24BPP, - CIMGP_SOURCE_FMT_8_8_8_8 -}; - -void -LXRefreshArea_Blt(ScrnInfoPtr pScrni, int num, BoxPtr pbox) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - int width, height, x1, y1, x2, y2, newX, newY; - unsigned long src, dst; - int Bpp = pScrni->bitsPerPixel >> 3; - - gp_set_source_format(lx_shdw_fmt[Bpp - 1]); - gp_declare_blt(0); - gp_set_raster_operation(0xcc); /* copy dst=src */ - gp_write_parameters(); - for (; --num >= 0; ++pbox) { - CLIP(pScrni, pbox, x1, y1, x2, y2); - if ((width = x2 - x1) <= 0 || (height = y2 - y1) <= 0) - continue; - (*pGeode->Rotation) (x1, y1, pScrni->virtualX, pScrni->virtualY, - &newX, &newY); - (*pGeode->RBltXlat) (newX, newY, width, height, &newX, &newY); - src = y1 * pGeode->ShadowPitch + x1 * Bpp; - dst = pGeode->FBOffset + newY * pGeode->Pitch + newX * Bpp; - gp_declare_blt(0); - gp_set_strides(pGeode->Pitch, pGeode->ShadowPitch); - gp_rotate_blt(dst, src, width, height, pGeode->Rotate * 90); - } -} - -void -LXRefreshArea0_Cpu(ScrnInfoPtr pScrni, int num, BoxPtr pbox) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - int width, height, x1, y1, x2, y2; - unsigned char *src, *dst; - int Bpp = pScrni->bitsPerPixel >> 3; - - LXAccelSync(pScrni); - for (; --num >= 0; ++pbox) { - CLIP(pScrni, pbox, x1, y1, x2, y2); - if ((width = x2 - x1) <= 0 || (height = y2 - y1) <= 0) - continue; - src = pGeode->ShadowPtr + y1 * pGeode->ShadowPitch + x1 * Bpp; - dst = pGeode->FBBase + pGeode->FBOffset + y1 * pGeode->Pitch + x1 * - Bpp; - width *= Bpp; - while (--height >= 0) { - memcpy(dst, src, width); - dst += pGeode->Pitch; - src += pGeode->ShadowPitch; - } - } -} - -#define RefreshArea1_Cpu(nm,typ) \ -void LXRefreshArea1_Cpu##nm(ScrnInfoPtr pScrni, int num, BoxPtr pbox) \ -{ \ - GeodeRec *pGeode = GEODEPTR(pScrni); \ - int l, width, height, x1, y1, x2, y2, newX, newY; \ - unsigned long src, dst, dp; \ - typ *sp; \ - LXAccelSync(pScrni); \ - for (; --num>=0; ++pbox) { \ - CLIP(pScrni,pbox,x1,y1,x2,y2); \ - if ((width=x2-x1) <=0 || (height=y2-y1) <= 0) continue; \ - src = y1*pGeode->ShadowPitch + x1*sizeof(typ); \ - newX = pScrni->virtualY-1 - y1; \ - newY = x1; \ - dst = pGeode->FBOffset + newY*pGeode->Pitch + newX*sizeof(typ); \ - while (--height >= 0) { \ - sp = (typ *)(pGeode->ShadowPtr + src); \ - dp = (unsigned long)(pGeode->FBBase + dst); \ - for (l=width; --l>=0;) { \ - *(typ *)dp = *sp++; \ - dp += pGeode->Pitch; \ - } \ - dst -= sizeof(typ); \ - src += pGeode->ShadowPitch; \ - } \ - } \ -} - -RefreshArea1_Cpu(8, unsigned char) -RefreshArea1_Cpu(16, unsigned short) -RefreshArea1_Cpu(32, unsigned int) -#define RefreshArea2_Cpu(nm,typ) \ -void LXRefreshArea2_Cpu##nm(ScrnInfoPtr pScrni, int num, BoxPtr pbox) \ -{ \ - GeodeRec *pGeode = GEODEPTR(pScrni); \ - int l, width, height, x1, y1, x2, y2, newX, newY; \ - unsigned long src, dst, dp; \ - typ *sp; \ - LXAccelSync(pScrni); \ - for (; --num>=0; ++pbox) { \ - CLIP(pScrni,pbox,x1,y1,x2,y2); \ - if ((width=x2-x1) <=0 || (height=y2-y1) <= 0) continue; \ - src = y1*pGeode->ShadowPitch + x1*sizeof(typ); \ - newX = pScrni->virtualX-1 - x1; \ - newY = pScrni->virtualY-1 - y1; \ - dst = pGeode->FBOffset + newY*pGeode->Pitch + newX*sizeof(typ); \ - while (--height >= 0) { \ - sp = (typ *)(pGeode->ShadowPtr + src); \ - dp = (unsigned long)(pGeode->FBBase + dst); \ - for( l=width; --l>=0; ) { \ - *(typ *)dp = *sp++; \ - dp -= sizeof(typ); \ - } \ - src += pGeode->ShadowPitch; \ - dst -= pGeode->Pitch; \ - } \ - } \ -} -RefreshArea2_Cpu(8, unsigned char) -RefreshArea2_Cpu(16, unsigned short) -RefreshArea2_Cpu(32, unsigned int) -#define RefreshArea3_Cpu(nm,typ) \ -void LXRefreshArea3_Cpu##nm(ScrnInfoPtr pScrni, int num, BoxPtr pbox) \ -{ \ - GeodeRec *pGeode = GEODEPTR(pScrni); \ - int l, width, height, x1, y1, x2, y2, newX, newY; \ - unsigned long src, dst, dp; \ - typ *sp; \ - LXAccelSync(pScrni); \ - for (; --num>=0; ++pbox) { \ - CLIP(pScrni,pbox,x1,y1,x2,y2); \ - if ((width=x2-x1) <=0 || (height=y2-y1) <= 0) continue; \ - src = y1*pGeode->ShadowPitch + x1*sizeof(typ); \ - newX = y1; \ - newY = pScrni->virtualX-1 - x1; \ - dst = pGeode->FBOffset + newY*pGeode->Pitch + newX*sizeof(typ); \ - while (--height >= 0) { \ - sp = (typ *)(pGeode->ShadowPtr + src); \ - dp = (unsigned long)(pGeode->FBBase + dst); \ - for( l=width; --l>=0; ) { \ - *(typ *)dp = *sp++; \ - dp -= pGeode->Pitch; \ - } \ - dst += sizeof(typ); \ - src += pGeode->ShadowPitch; \ - } \ - } \ -} -RefreshArea3_Cpu(8, unsigned char) -RefreshArea3_Cpu(16, unsigned short) -RefreshArea3_Cpu(32, unsigned int) - - void LXRotationInit(ScrnInfoPtr pScrni) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - switch (pGeode->Rotate) { - case 1: - pGeode->Rotation = LXRotation1; - pGeode->RBltXlat = LXRBltXlat1; - break; - case 2: - pGeode->Rotation = LXRotation2; - pGeode->RBltXlat = LXRBltXlat2; - break; - case 3: - pGeode->Rotation = LXRotation3; - pGeode->RBltXlat = LXRBltXlat3; - break; - default: - pGeode->Rotation = LXRotation0; - pGeode->RBltXlat = LXRBltXlat0; - break; - } -} - -void -LXShadowFBInit(ScreenPtr pScrn, GeodeRec *pGeode, int bytpp) -{ - RefreshAreaFuncPtr refreshArea; - - if (pGeode->NoAccel || !pGeode->ShadowInFBMem || 0) { - switch (bytpp) { - case 2: - switch (pGeode->Rotate) { - case 1: - refreshArea = LXRefreshArea1_Cpu16; - break; - case 2: - refreshArea = LXRefreshArea2_Cpu16; - break; - case 3: - refreshArea = LXRefreshArea3_Cpu16; - break; - default: - refreshArea = LXRefreshArea0_Cpu; - break; - } - break; - case 4: - switch (pGeode->Rotate) { - case 1: - refreshArea = LXRefreshArea1_Cpu32; - break; - case 2: - refreshArea = LXRefreshArea2_Cpu32; - break; - case 3: - refreshArea = LXRefreshArea3_Cpu32; - break; - default: - refreshArea = LXRefreshArea0_Cpu; - break; - } - break; - default: - switch (pGeode->Rotate) { - case 1: - refreshArea = LXRefreshArea1_Cpu8; - break; - case 2: - refreshArea = LXRefreshArea2_Cpu8; - break; - case 3: - refreshArea = LXRefreshArea3_Cpu8; - break; - default: - refreshArea = LXRefreshArea0_Cpu; - break; - } - break; - } - } else { - refreshArea = pGeode->Rotate ? LXRefreshArea_Blt : LXRefreshArea_Cpy; - } - ShadowFBInit(pScrn, refreshArea); -} diff --git a/src/amd_lx_vga.c b/src/amd_lx_vga.c index 6351f3d..699ca21 100644 --- a/src/amd_lx_vga.c +++ b/src/amd_lx_vga.c @@ -25,7 +25,7 @@ */ /* - * This file contains routines to set modes using the VGA registers. + * This file contains routines to set modes using the VGA registers. * Since this file is for the first generation graphics unit, it interfaces * to SoftVGA registers. It works for both VSA1 and VSA2. */ @@ -38,8 +38,5 @@ int gu3_get_vga_active(void) { int data = READ_REG32(DC3_GENERAL_CFG); - - if (data & DC3_GCFG_VGAE) - return 1; - return 0; + return (data & DC3_GCFG_VGAE) ? 1 : 0; } diff --git a/src/amd_lx_video.c b/src/amd_lx_video.c index a0836b0..0b06069 100644 --- a/src/amd_lx_video.c +++ b/src/amd_lx_video.c @@ -1,12 +1,11 @@ -/* - * Copyright (c) 2006 Advanced Micro Devices, Inc. +/* Copyright (c) 2007 Advanced Micro Devices, Inc. * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. @@ -16,232 +15,82 @@ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. * * Neither the name of the Advanced Micro Devices, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. */ -/* - * File Contents: This file consists of main Xfree video supported routines. - * - * Project: Geode Xfree Frame buffer device driver. - * - */ - -/* - * Fixes & Extensions to support Y800 greyscale modes - * Alan Hourihane <alanh@fairlite.demon.co.uk> - */ +/* TODO: + Add rotation + Add back in double buffering? + +*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif -#ifndef AMD_V4L2_VIDEO +#include <stdlib.h> +#include <string.h> + #include "xf86.h" #include "xf86_OSproc.h" #include "xf86Resources.h" -#include "xf86_ansic.h" #include "compiler.h" #include "xf86PciInfo.h" #include "xf86Pci.h" #include "xf86fbman.h" #include "regionstr.h" +#include "dixstruct.h" #include "amd.h" -#include "Xv.h" -#include "xaa.h" -#include "xaalocal.h" -#include "dixstruct.h" +#include "xf86xv.h" +#include <X11/extensions/Xv.h> #include "fourcc.h" #include "amd_fourcc.h" -#if DEBUGLVL>0 -#define DBLOG(n,s...) do { if((DEBUGLVL)>=(n)) fprintf(zdfp,s); } while(0) -#include "xf86_ansic.h" -extern FILE *zdfp; -#else -#define DBLOG(n,s...) do {} while(0) -#endif - -#define OFF_DELAY 200 /* milliseconds */ -#define FREE_DELAY 60000 - -#define OFF_TIMER 0x01 -#define FREE_TIMER 0x02 +#define OFF_DELAY 200 +#define FREE_DELAY 60000 +#define OFF_TIMER 0x01 +#define FREE_TIMER 0x02 #define CLIENT_VIDEO_ON 0x04 - #define TIMER_MASK (OFF_TIMER | FREE_TIMER) -#define XV_PROFILE 0 -#define REINIT 1 - -#ifndef XvExtension -void -LXInitVideo(ScreenPtr pScrn) -{ -} - -void -LXResetVideo(ScrnInfoPtr pScrni) -{ -} - -void -LXSetVideoPosition(int x, int y, int width, int height, - short src_w, short src_h, short drw_w, - short drw_h, int id, int offset, ScrnInfoPtr pScrni) -{ -} -#else - -#define DBUF 1 -void LXInitVideo(ScreenPtr pScrn); -void LXResetVideo(ScrnInfoPtr pScrni); -static XF86VideoAdaptorPtr LXSetupImageVideo(ScreenPtr); -static void LXInitOffscreenImages(ScreenPtr); -static void LXStopVideo(ScrnInfoPtr, pointer, Bool); -static int LXSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); -static int LXGetPortAttribute(ScrnInfoPtr, Atom, INT32 *, pointer); -static void LXQueryBestSize(ScrnInfoPtr, Bool, - short, short, short, short, unsigned int *, unsigned int *, pointer); -static int LXPutImage(ScrnInfoPtr, short, short, short, short, short, short, - short, short, int, unsigned char *, short, short, Bool, - RegionPtr, pointer); -static int LXQueryImageAttributes(ScrnInfoPtr, int, unsigned short *, - unsigned short *, int *, int *); - -static void LXBlockHandler(int, pointer, pointer, pointer); -void LXSetVideoPosition(int x, int y, int width, int height, - short src_w, short src_h, short drw_w, - short drw_h, int id, int offset, ScrnInfoPtr pScrni); - -extern void LXAccelSync(ScrnInfoPtr pScrni); #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) +#define ARRAY_SIZE(a) (sizeof((a)) / (sizeof(*(a)))) -static Atom xvColorKey, xvColorKeyMode, xvFilter; - -#if DBUF -static Atom xvDoubleBuffer; -#endif - -/*---------------------------------------------------------------------------- - * LXInitVideo - * - * Description: This is the initialization routine. It creates a new video - * adapter and calls LXSetupImageVideo to initialize it by - * filling XF86VideoAdaptorREc. Then it lists the existing - * adaptors and adds the new one to it. Finally the list of - * XF86VideoAdaptorPtr pointers are passed to the - * xf86XVScreenInit(). - * - * Parameters. - * ScreenPtr - * pScrn :Screen handler pointer having screen information. - * - * Returns :none - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ -void -LXInitVideo(ScreenPtr pScrn) -{ - GeodeRec *pGeode; - ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; - - DBLOG(1, "LXInitVideo()\n"); - - pGeode = GEODEPTR(pScrni); - - if (!pGeode->NoAccel) { - XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; - XF86VideoAdaptorPtr newAdaptor = NULL; - - int num_adaptors; - - newAdaptor = LXSetupImageVideo(pScrn); - LXInitOffscreenImages(pScrn); - - num_adaptors = xf86XVListGenericAdaptors(pScrni, &adaptors); - - if (newAdaptor) { - if (!num_adaptors) { - num_adaptors = 1; - adaptors = &newAdaptor; - } else { - newAdaptors = /* need to free this someplace */ - xalloc((num_adaptors + - 1) * sizeof(XF86VideoAdaptorPtr *)); - if (newAdaptors) { - memcpy(newAdaptors, adaptors, num_adaptors * - sizeof(XF86VideoAdaptorPtr)); - newAdaptors[num_adaptors] = newAdaptor; - adaptors = newAdaptors; - num_adaptors++; - } - } - } - - if (num_adaptors) - xf86XVScreenInit(pScrn, adaptors, num_adaptors); - - if (newAdaptors) - xfree(newAdaptors); - } -} - -/* client libraries expect an encoding */ static XF86VideoEncodingRec DummyEncoding[1] = { - { - 0, - "XV_IMAGE", - 1024, 1024, - {1, 1} - } + { 0, "XV_IMAGE", 1024, 1024, {1, 1} } }; -#define NUM_FORMATS 4 - -static XF86VideoFormatRec Formats[NUM_FORMATS] = { - {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor} +static XF86VideoFormatRec Formats[] = { + {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor} }; -#if DBUF -#define NUM_ATTRIBUTES 4 -#else -#define NUM_ATTRIBUTES 3 -#endif - -static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = { -#if DBUF - {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}, -#endif - {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, - {XvSettable | XvGettable, 0, 1, "XV_FILTER"}, - {XvSettable | XvGettable, 0, 1, "XV_COLORKEYMODE"} +static XF86AttributeRec Attributes[] = { + {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, + {XvSettable | XvGettable, 0, 1, "XV_FILTER"}, + {XvSettable | XvGettable, 0, 1, "XV_COLORKEYMODE"} }; static XF86ImageRec Images[] = { - XVIMAGE_UYVY, - XVIMAGE_YUY2, - XVIMAGE_Y2YU, - XVIMAGE_YVYU, - XVIMAGE_Y800, - XVIMAGE_I420, - XVIMAGE_YV12 + XVIMAGE_UYVY, + XVIMAGE_YUY2, + XVIMAGE_Y2YU, + XVIMAGE_YVYU, + XVIMAGE_Y800, + XVIMAGE_I420, + XVIMAGE_YV12, + XVIMAGE_RGB565 }; -#define NUM_IMAGES (sizeof(Images)/sizeof(Images[0])); - typedef struct { - FBAreaPtr area; - FBLinearPtr linear; + void *area; + int offset; RegionRec clip; CARD32 filter; CARD32 colorKey; @@ -249,1116 +98,798 @@ typedef struct CARD32 videoStatus; Time offTime; Time freeTime; -#if DBUF - Bool doubleBuffer; - int currentBuffer; -#endif -} -GeodePortPrivRec, *GeodePortPrivPtr; +} GeodePortPrivRec, *GeodePortPrivPtr; #define GET_PORT_PRIVATE(pScrni) \ (GeodePortPrivRec *)((GEODEPTR(pScrni))->adaptor->pPortPrivates[0].ptr) -/*---------------------------------------------------------------------------- - * LXSetColorKey - * - * Description :This function reads the color key for the pallete and - * sets the video color key register. - * - * Parameters. - * ScreenInfoPtr - * pScrni :Screen pointer having screen information. - * pPriv :Video port private data - * - * Returns :none - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ -static INT32 -LXSetColorkey(ScrnInfoPtr pScrni, GeodePortPrivRec * pPriv) +static void +LXCopyFromSys(GeodeRec *pGeode, unsigned char *src, unsigned int dst, + int dstPitch, int srcPitch, int h, int w) { - int red, green, blue; - unsigned long key; - - switch (pScrni->depth) { - case 8: - vg_get_display_palette_entry(pPriv->colorKey & 0xFF, &key); - red = ((key >> 16) & 0xFF); - green = ((key >> 8) & 0xFF); - blue = (key & 0xFF); - break; - case 16: - red = (pPriv->colorKey & pScrni->mask.red) >> - pScrni->offset.red << (8 - pScrni->weight.red); - green = (pPriv->colorKey & pScrni->mask.green) >> - pScrni->offset.green << (8 - pScrni->weight.green); - blue = (pPriv->colorKey & pScrni->mask.blue) >> - pScrni->offset.blue << (8 - pScrni->weight.blue); - break; - default: - /* for > 16 bpp we send in the mask in xf86SetWeight. This - * function is providing the offset by 1 more. So we take - * this as a special case and subtract 1 for > 16 - */ - red = (pPriv->colorKey & pScrni->mask.red) >> - (pScrni->offset.red - 1) << (8 - pScrni->weight.red); - green = (pPriv->colorKey & pScrni->mask.green) >> - (pScrni->offset.green - 1) << (8 - pScrni->weight.green); - blue = (pPriv->colorKey & pScrni->mask.blue) >> - (pScrni->offset.blue - 1) << (8 - pScrni->weight.blue); - break; - } - - DBLOG(1, "LXSetColorkey() %08x %d\n", blue | (green << 8) | (red << 16), - pPriv->colorKeyMode); - if (pPriv->colorKeyMode != 0) - df_set_video_color_key((blue | (green << 8) | (red << 16)), - 0xFFFFFF, 1); - else - df_set_video_color_key(0, 0, 1); - REGION_EMPTY(pScrni->pScreen, &pPriv->clip); - - return 0; + gp_declare_blt(0); + gp_set_bpp(16); + + gp_set_raster_operation(0xCC); + gp_set_strides(dstPitch, srcPitch); + gp_set_solid_pattern(0); + + gp_color_bitmap_to_screen_blt(dst, 0, w, h, src, srcPitch); } -/*---------------------------------------------------------------------------- - * LXResetVideo - * - * Description : This function resets the video - * - * Parameters. - * ScreenInfoPtr - * pScrni :Screen pointer having screen information. - * - * Returns :None - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ - -void -LXResetVideo(ScrnInfoPtr pScrni) +static void +LXVideoSave(ScreenPtr pScreen, ExaOffscreenArea *area) { - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(1, "LXResetVideo()\n"); - - if (!pGeode->NoAccel) { - GeodePortPrivRec *pPriv = pGeode->adaptor->pPortPrivates[0].ptr; - - LXAccelSync(pScrni); - df_set_video_palette(NULL); - LXSetColorkey(pScrni, pPriv); - } + ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; + + GeodeRec *pGeode = GEODEPTR(pScrni); + GeodePortPrivRec *pPriv = GET_PORT_PRIVATE(pScrni); + + if (area == pPriv->area) + pPriv->area = NULL; } -/*---------------------------------------------------------------------------- - * LXSetupImageVideo - * - * Description : This function allocates space for a Videoadaptor and initializes - * the XF86VideoAdaptorPtr record. - * - * Parameters. - * ScreenPtr - * pScrn :Screen handler pointer having screen information. - * - * Returns :XF86VideoAdaptorPtr :- pointer to the initialized video adaptor record. - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ -static XF86VideoAdaptorPtr -LXSetupImageVideo(ScreenPtr pScrn) +static unsigned int +LXAllocateVidMem(ScrnInfoPtr pScrni, void **memp, int size) { - ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; - GeodeRec *pGeode = GEODEPTR(pScrni); - XF86VideoAdaptorPtr adapt; - GeodePortPrivRec *pPriv; - - DBLOG(1, "LXSetupImageVideo()\n"); - - if (!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + - sizeof(GeodePortPrivRec) + sizeof(DevUnion)))) - return NULL; - - adapt->type = XvWindowMask | XvInputMask | XvImageMask; - adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; - adapt->name = "Advanced Micro Devices"; - adapt->nEncodings = 1; - adapt->pEncodings = DummyEncoding; - adapt->nFormats = NUM_FORMATS; - adapt->pFormats = Formats; - adapt->nPorts = 1; - adapt->pPortPrivates = (DevUnion *) (&adapt[1]); - pPriv = (GeodePortPrivRec *) (&adapt->pPortPrivates[1]); - adapt->pPortPrivates[0].ptr = (pointer) (pPriv); - adapt->pAttributes = Attributes; - adapt->nImages = NUM_IMAGES; - adapt->nAttributes = NUM_ATTRIBUTES; - adapt->pImages = Images; - adapt->PutVideo = NULL; - adapt->PutStill = NULL; - adapt->GetVideo = NULL; - adapt->GetStill = NULL; - adapt->StopVideo = LXStopVideo; - adapt->SetPortAttribute = LXSetPortAttribute; - adapt->GetPortAttribute = LXGetPortAttribute; - adapt->QueryBestSize = LXQueryBestSize; - adapt->PutImage = LXPutImage; - adapt->QueryImageAttributes = LXQueryImageAttributes; - - pPriv->filter = 0; - pPriv->colorKey = pGeode->videoKey; - pPriv->colorKeyMode = 0; - pPriv->videoStatus = 0; -#if DBUF - pPriv->doubleBuffer = TRUE; - pPriv->currentBuffer = 0; /* init to first buffer */ -#endif - - /* gotta uninit this someplace */ -#if defined(REGION_NULL) - REGION_NULL(pScrn, &pPriv->clip); -#else - REGION_INIT(pScrn, &pPriv->clip, NullBox, 0); -#endif - - pGeode->adaptor = adapt; - - pGeode->BlockHandler = pScrn->BlockHandler; - pScrn->BlockHandler = LXBlockHandler; - - xvColorKey = MAKE_ATOM("XV_COLORKEY"); - xvColorKeyMode = MAKE_ATOM("XV_COLORKEYMODE"); - xvFilter = MAKE_ATOM("XV_FILTER"); -#if DBUF - xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER"); -#endif - - LXResetVideo(pScrni); - - return adapt; + GeodeRec *pGeode = GEODEPTR(pScrni); + ExaOffscreenArea *area = *memp; + + if (area != NULL) { + if (area->size >= size) + return area->offset; + + exaOffscreenFree(pScrni->pScreen, area); + } + + area = exaOffscreenAlloc(pScrni->pScreen, size, 16, TRUE, + LXVideoSave, NULL); + + *memp = area; + return (area == NULL) ? 0 : area->offset; } -/*---------------------------------------------------------------------------- - * LXStopVideo - * - * Description :This function is used to stop input and output video - * - * Parameters. - * pScrni :Screen handler pointer having screen information. - * data :Pointer to the video port's private data - * exit :Flag indicating whether the offscreen areas used for video - * to be deallocated or not. - * Returns :none - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ static void -LXStopVideo(ScrnInfoPtr pScrni, pointer data, Bool exit) +LXSetColorkey(ScrnInfoPtr pScrni, GeodePortPrivRec * pPriv) { - GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(1, "LXStopVideo()\n"); - - REGION_EMPTY(pScrni->pScreen, &pPriv->clip); - - LXAccelSync(pScrni); - if (exit) { - if (pPriv->videoStatus & CLIENT_VIDEO_ON) { - df_set_video_enable(0, 0); - } - if (pPriv->area) { - xf86FreeOffscreenArea(pPriv->area); - pPriv->area = NULL; - } - pPriv->videoStatus = 0; - pGeode->OverlayON = FALSE; - } else { - if (pPriv->videoStatus & CLIENT_VIDEO_ON) { - pPriv->videoStatus |= OFF_TIMER; - pPriv->offTime = currentTime.milliseconds + OFF_DELAY; - } - } + int red, green, blue; + unsigned long key; + + switch (pScrni->depth) { + case 8: + vg_get_display_palette_entry(pPriv->colorKey & 0xFF, &key); + red = ((key >> 16) & 0xFF); + green = ((key >> 8) & 0xFF); + blue = (key & 0xFF); + break; + case 16: + red = (pPriv->colorKey & pScrni->mask.red) >> + pScrni->offset.red << (8 - pScrni->weight.red); + green = (pPriv->colorKey & pScrni->mask.green) >> + pScrni->offset.green << (8 - pScrni->weight.green); + blue = (pPriv->colorKey & pScrni->mask.blue) >> + pScrni->offset.blue << (8 - pScrni->weight.blue); + break; + default: + /* for > 16 bpp we send in the mask in xf86SetWeight. This + * function is providing the offset by 1 more. So we take + * this as a special case and subtract 1 for > 16 + */ + + red = (pPriv->colorKey & pScrni->mask.red) >> + (pScrni->offset.red - 1) << (8 - pScrni->weight.red); + green = (pPriv->colorKey & pScrni->mask.green) >> + (pScrni->offset.green - 1) << (8 - pScrni->weight.green); + blue = (pPriv->colorKey & pScrni->mask.blue) >> + (pScrni->offset.blue - 1) << (8 - pScrni->weight.blue); + break; + } + + if (pPriv->colorKeyMode != 0) + df_set_video_color_key((blue | (green << 8) | (red << 16)), + 0xFFFFFF, 1); + else + df_set_video_color_key(0, 0, 1); + + REGION_EMPTY(pScrni->pScreen, &pPriv->clip); } -/*---------------------------------------------------------------------------- - * LXSetPortAttribute - * - * Description :This function is used to set the attributes of a port like colorkeymode, - * double buffer support and filter. - * - * Parameters. - * pScrni :Screen handler pointer having screen information. - * data :Pointer to the video port's private data - * attribute :The port attribute to be set - * value :Value of the attribute to be set. - * - * Returns :Sucess if the attribute is supported, else BadMatch - * - * Comments :none - * -*---------------------------------------------------------------------------- +/* A structure full of the scratch information that originates in the copy routines, + but is needed for the video display - maybe we should figure out a way to attach + this to structures? I hate to put it in pGeode since it will increase the size of + the structure, and possibly cause us cache issues. */ -static int -LXSetPortAttribute(ScrnInfoPtr pScrni, - Atom attribute, INT32 value, pointer data) -{ - GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; - DBLOG(1, "LXSetPortAttribute(%d,%#x)\n", attribute, value); +struct { + unsigned int dstOffset; + unsigned int dstPitch; + unsigned int UVPitch; + unsigned int UDstOffset; + unsigned int VDstOffset; +} videoScratch; - LXAccelSync(pScrni); - if (attribute == xvColorKey) { - pPriv->colorKey = value; - LXSetColorkey(pScrni, pPriv); - } -#if DBUF - else if (attribute == xvDoubleBuffer) { - if ((value < 0) || (value > 1)) - return BadValue; - pPriv->doubleBuffer = value; - } -#endif - else if (attribute == xvColorKeyMode) { - pPriv->colorKeyMode = value; - LXSetColorkey(pScrni, pPriv); - } else if (attribute == xvFilter) { - if ((value < 0) || (value > 1)) - return BadValue; - pPriv->filter = value; - } else - return BadMatch; +/* Copy planar YUV data */ - return Success; +static Bool +LXCopyPlanar(ScrnInfoPtr pScrni, int id, unsigned char *buf, + short x1, short y1, short x2, short y2, + int width, int height, pointer data) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; + + unsigned int YSrcPitch, YDstPitch; + unsigned int UVSrcPitch, UVDstPitch; + unsigned int YSrcOffset, YDstOffset; + unsigned int USrcOffset, UDstOffset; + unsigned int VSrcOffset, VDstOffset; + + unsigned int size, lines, top, left, pixels; + + YSrcPitch = (width + 3) & ~3; + YDstPitch = (width + 31) & ~31; + + UVSrcPitch = ((width >> 1) + 3) & ~3; + UVDstPitch = ((width >> 1) + 15) & ~15; + + if (id != FOURCC_I420) { + VSrcOffset = YSrcPitch * height; + USrcOffset = VSrcOffset + (UVSrcPitch * (height >> 1)); + + VDstOffset = YDstPitch * height; + UDstOffset = VDstOffset + (UVDstPitch * (height >> 1)); + } + else { + USrcOffset = YSrcPitch * height; + VSrcOffset = USrcOffset + (UVSrcPitch * (height >> 1)); + + UDstOffset = YDstPitch * height; + VDstOffset = UDstOffset + (UVDstPitch * (height >> 1)); + } + + size = YDstPitch * height; + size += UVDstPitch * height; + + pPriv->offset = LXAllocateVidMem(pScrni, &pPriv->area, size); + + if (pPriv->offset == 0) { + ErrorF("Error allocating an offscreen region.\n"); + return FALSE; + } + + /* The top of the source region we want to copy */ + top = y1 & ~1; + + /* The left hand side of the source region, aligned on a word */ + left = x1 & ~1; + + /* Number of bytes to copy, also word aligned */ + pixels = ((x2 + 1) & ~1) - left; + + /* Calculate the source offset */ + YSrcOffset = (top * YSrcPitch) + left; + USrcOffset += ((top >> 1) * UVSrcPitch) + (left >> 1); + VSrcOffset += ((top >> 1) * UVSrcPitch) + (left >> 1); + + /* Calculate the destination offset */ + YDstOffset = (top * YDstPitch) + left; + UDstOffset += ((top >> 1) * UVDstPitch) + (left >> 1); + VDstOffset += ((top >> 1) * UVDstPitch) + (left >> 1); + + lines = ((y2 + 1) & ~1) - top; + + /* Copy Y */ + + LXCopyFromSys(pGeode, buf + YSrcOffset, pPriv->offset + YDstOffset, + YDstPitch, YSrcPitch, lines, pixels); + + /* Copy U + V at the same time */ + + LXCopyFromSys(pGeode, buf + USrcOffset, pPriv->offset + UDstOffset, + UVDstPitch, UVSrcPitch, lines, pixels >> 1); + + /* Copy V */ + + //LXCopyFromSys(pGeode, buf + VSrcOffset, pPriv->offset + VDstOffset, + //UVDstPitch, UVSrcPitch, lines >> 1, pixels >> 1); + + videoScratch.dstOffset = pPriv->offset + YDstOffset; + videoScratch.dstPitch = YDstPitch; + videoScratch.UVPitch = UVDstPitch; + videoScratch.UDstOffset = pPriv->offset + UDstOffset; + videoScratch.VDstOffset = pPriv->offset + VDstOffset; + + return TRUE; } -/*---------------------------------------------------------------------------- - * LXGetPortAttribute - * - * Description :This function is used to get the attributes of a port like hue, - * saturation,brightness or contrast. - * - * Parameters. - * pScrni :Screen handler pointer having screen information. - * data :Pointer to the video port's private data - * attribute :The port attribute to be read - * value :Pointer to the value of the attribute to be read. - * - * Returns :Sucess if the attribute is supported, else BadMatch - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ -static int -LXGetPortAttribute(ScrnInfoPtr pScrni, - Atom attribute, INT32 * value, pointer data) +static Bool +LXCopyPacked(ScrnInfoPtr pScrni, int id, unsigned char *buf, + short x1, short y1, short x2, short y2, + int width, int height, pointer data) { - GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; - - DBLOG(1, "LXGetPortAttribute(%d)\n", attribute); - - if (attribute == xvColorKey) { - *value = pPriv->colorKey; - } -#if DBUF - else if (attribute == xvDoubleBuffer) { - *value = (pPriv->doubleBuffer) ? 1 : 0; - } -#endif - else if (attribute == xvColorKeyMode) { - *value = pPriv->colorKeyMode; - } else if (attribute == xvFilter) { - *value = pPriv->filter; - } else - return BadMatch; - - return Success; + GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; + GeodeRec *pGeode = GEODEPTR(pScrni); + unsigned int dstPitch, srcPitch; + unsigned int srcOffset, dstOffset; + unsigned int lines, top, left, pixels; + + dstPitch = ((width << 1) + 3) & ~3; + srcPitch = (width << 1); + + lines = ((dstPitch * height) + pGeode->Pitch - 1) / pGeode->Pitch; + + pPriv->offset = LXAllocateVidMem(pScrni, &pPriv->area, height * dstPitch); + + if (pPriv->offset == 0) { + ErrorF("Error while allocating an offscreen region.\n"); + return FALSE; + } + + /* The top of the source region we want to copy */ + top = y1; + + /* The left hand side of the source region, aligned on a word */ + left = x1 & ~1; + + /* Number of bytes to copy, also word aligned */ + pixels = ((x2 + 1) & ~1) - left; + + /* Adjust the incoming buffer */ + srcOffset = (top * srcPitch) + left; + + /* Calculate the destination offset */ + dstOffset = pPriv->offset + (top * dstPitch) + left; + + /* Make the copy happen */ + + if (id == FOURCC_Y800) { + + /* Use the shared (unaccelerated) greyscale copy - you could probably + accelerate it using a 2 pass blit and patterns, but it doesn't really + seem worth it + */ + + GeodeCopyGreyscale(buf + srcOffset, pGeode->FBBase + dstOffset, srcPitch, dstPitch, + height, pixels >> 1); + } + else + LXCopyFromSys(pGeode, buf + srcOffset, dstOffset, dstPitch, srcPitch, height, pixels); + + videoScratch.dstOffset = dstOffset; + videoScratch.dstPitch = dstPitch; + + return TRUE; } - -/*---------------------------------------------------------------------------- - * LXQueryBestSize - * - * Description : - * This function provides a way to query what the destination dimensions - * would end up being if they were to request that an area vid_w by vid_h - * from the video stream be scaled to rectangle of drw_w by drw_h on - * the screen. - * - * Parameters. - * ScreenInfoPtr - * pScrni :Screen handler pointer having screen information. - * data :Pointer to the video port's private data - * vid_w,vid_h :Width and height of the video data. - * drw_w,drw_h :Width and height of the scaled rectangle. - * p_w,p_h :Width and height of the destination rectangle. - * - * Returns :None - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ -static void -LXQueryBestSize(ScrnInfoPtr pScrni, Bool motion, short vid_w, short vid_h, - short drw_w, short drw_h, unsigned int *p_w, - unsigned int *p_h, pointer data) + +LXDisplayVideo(ScrnInfoPtr pScrni, int id, short width, short height, + BoxPtr dstBox, short srcW, short srcH, short drawW, short drawH) { - *p_w = drw_w; - *p_h = drw_h; - - if (*p_w > 16384) - *p_w = 16384; - - DBLOG(1, "LXQueryBestSize(%d, src %dx%d scl %dx%d dst %dx%d)\n", motion, - vid_w, vid_h, drw_w, drw_h, *p_w, *p_h); + long ystart, xend, yend; + unsigned long lines = 0; + unsigned long yExtra, uvExtra = 0; + DF_VIDEO_POSITION vidPos; + DF_VIDEO_SOURCE_PARAMS vSrcParams; + + gp_wait_until_idle(); + + switch(id) { + case FOURCC_UYVY: + vSrcParams.video_format = DF_VIDFMT_UYVY; + break; + + case FOURCC_Y800: + case FOURCC_YV12: + case FOURCC_I420: + vSrcParams.video_format = DF_VIDFMT_Y0Y1Y2Y3; + break; + case FOURCC_YUY2: + vSrcParams.video_format = DF_VIDFMT_YUYV; + break; + case FOURCC_Y2YU: + vSrcParams.video_format = DF_VIDFMT_Y2YU; + break; + case FOURCC_YVYU: + vSrcParams.video_format = DF_VIDFMT_YVYU; + break; + case FOURCC_RGB565: + vSrcParams.video_format = DF_VIDFMT_RGB; + break; + } + + vSrcParams.width = width; + vSrcParams.height = height; + vSrcParams.y_pitch = videoScratch.dstPitch; + vSrcParams.uv_pitch = videoScratch.UVPitch; + + /* Set up scaling */ + df_set_video_filter_coefficients(NULL, 1); + + if ((drawW >= srcW) && (drawH >= srcH)) + df_set_video_scale(width, height, drawW, drawH, + DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY); + else if (drawW < srcW) + df_set_video_scale(drawW, height, drawW, drawH, + DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY); + else if (drawH < srcH) + df_set_video_scale(width, drawH, drawW, drawH, + DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY); + + /* Figure out clipping */ + + xend = dstBox->x2; + yend = dstBox->y2; + + if (dstBox->y1 < 0) { + if (srcH < drawH) + lines = ((-dstBox->y1) * srcH) / drawH; + else + lines = (-dstBox->y1); + + ystart = 0; + drawH += dstBox->y1; + } + else { + ystart = dstBox->y1; + lines = 0; + } + + yExtra = lines * videoScratch.dstPitch; + uvExtra = (lines >> 1) * videoScratch.UVPitch; + + memset(&vidPos, 0, sizeof(vidPos)); + + vidPos.x = dstBox->x1; + vidPos.y = ystart; + vidPos.width = xend - dstBox->x1; + vidPos.height = yend - ystart; + + df_set_video_position(&vidPos); + + vSrcParams.y_offset = videoScratch.dstOffset + yExtra; + + switch(id) { + case FOURCC_Y800: + case FOURCC_I420: + case FOURCC_YV12: + vSrcParams.u_offset = videoScratch.UDstOffset + uvExtra; + vSrcParams.v_offset = videoScratch.VDstOffset + uvExtra; + break; + + default: + vSrcParams.u_offset = vSrcParams.v_offset = 0; + break; + } + + vSrcParams.flags = DF_SOURCEFLAG_IMPLICITSCALING; + df_configure_video_source(&vSrcParams, &vSrcParams); + df_set_video_enable(1, 0); } -static void -LXCopyGreyscale(unsigned char *src, unsigned char *dst, int srcp, int dstp, - int h, int w) +static int +LXPutImage(ScrnInfoPtr pScrni, + short srcX, short srcY, short drawX, short drawY, + short srcW, short srcH, short drawW, short drawH, + int id, unsigned char *buf, + short width, short height, Bool sync, RegionPtr clipBoxes, + pointer data, DrawablePtr pDraw) { - int i; - unsigned char *src2 = src; - unsigned char *dst2 = dst; - unsigned char *dst3; - unsigned char *src3; - - dstp <<= 1; - - while (h--) { - dst3 = dst2; - src3 = src2; - for (i = 0; i < w; i++) { - *dst3++ = *src3++; /* Copy Y data */ - *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */ - } - src3 = src2; - for (i = 0; i < w; i++) { - *dst3++ = *src3++; /* Copy Y data */ - *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */ - } - dst2 += dstp; - src2 += srcp; + GeodeRec *pGeode = GEODEPTR(pScrni); + GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; + INT32 x1,x2,y1,y2; + BoxRec dstBox; + + if (srcW <= 0 || srcH <= 0) { + ErrorF("Nothing to draw!\n"); + return Success; + } + + if (drawW <= 0 || drawH <=0) { + ErrorF("Nothing to show!\n"); + return Success; + } + + if (drawW > 16384) + drawW = 16384; + + x1 = srcX; + x2 = srcX + srcW; + y1 = srcY; + y2 = srcY + srcH; + + dstBox.x1 = drawX; + dstBox.x2 = drawX + drawW; + dstBox.y1 = drawY; + dstBox.y2 = drawY + drawH; + + dstBox.x1 -= pScrni->frameX0; + dstBox.x2 -= pScrni->frameX0; + dstBox.y1 -= pScrni->frameY0; + dstBox.y2 -= pScrni->frameY0; + + switch(id) { + case FOURCC_YV12: + case FOURCC_I420: + LXCopyPlanar(pScrni, id, buf, x1, y1, x2, y2, width, height, data); + break; + + case FOURCC_UYVY: + case FOURCC_YUY2: + case FOURCC_Y800: + case FOURCC_RGB565: + LXCopyPacked(pScrni, id, buf, x1, y1, x2, y2, width, height, data); + break; + } + + if (!RegionsEqual(&pPriv->clip, clipBoxes)) { + REGION_COPY(pScrni->pScreen, &pPriv->clip, clipBoxes); + + if (pPriv->colorKeyMode == 0) { + xf86XVFillKeyHelper(pScrni->pScreen, pPriv->colorKey, clipBoxes); } + + LXDisplayVideo(pScrni, id, width, height, &dstBox, + srcW, srcH, drawW, drawH); + } + + pPriv->videoStatus = CLIENT_VIDEO_ON; + pGeode->OverlayON = TRUE; + + return Success; } -/*---------------------------------------------------------------------------- - * LXCopyData420 - * - * Description : Copies data from src to destination - * - * Parameters. - * src : pointer to the source data - * dst : pointer to destination data - * srcp : pitch of the srcdata - * dstp : pitch of the destination data - * h & w : height and width of source data - * - * Returns :None - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ - static void -LXCopyData420(unsigned char *src, unsigned char *dst, int srcp, int dstp, - int h, int w) +LXQueryBestSize(ScrnInfoPtr pScrni, Bool motion, + short vidW, short vidH, short drawW, short drawH, + unsigned int *retW, unsigned int *retH, pointer data) { - while (h--) { - memcpy(dst, src, w); - src += srcp; - dst += dstp; - } + *retW = drawW > 16384 ? 16384 : drawW; + *retH = drawH; } - -/*---------------------------------------------------------------------------- - * LXCopyData422 - * - * Description : Copies data from src to destination - * - * Parameters. - * src : pointer to the source data - * dst : pointer to destination data - * srcp : pitch of the srcdata - * dstp : pitch of the destination data - * h & w : height and width of source data - * - * Returns :None - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ - -static void -LXCopyData422(unsigned char *src, unsigned char *dst, - int srcp, int dstp, int h, int w) + +static Atom xvColorKey, xvColorKeyMode, xvFilter; + +static int +LXGetPortAttribute(ScrnInfoPtr pScrni, + Atom attribute, INT32 * value, pointer data) { - w <<= 1; - while (h--) { - memcpy(dst, src, w); - src += srcp; - dst += dstp; - } + GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; + + if (attribute == xvColorKey) + *value = pPriv->colorKey; + else if (attribute == xvColorKeyMode) + *value = pPriv->colorKeyMode; + else if (attribute == xvFilter) + *value = pPriv->filter; + else + return BadMatch; + + return Success; } -static FBAreaPtr -LXAllocateMemory(ScrnInfoPtr pScrni, FBAreaPtr area, int numlines) +static int +LXSetPortAttribute(ScrnInfoPtr pScrni, + Atom attribute, INT32 value, pointer data) { - ScreenPtr pScrn = screenInfo.screens[pScrni->scrnIndex]; - FBAreaPtr new_area; + GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; + + gp_wait_until_idle(); + + if (attribute == xvColorKey) { + pPriv->colorKey = value; + LXSetColorkey(pScrni, pPriv); + } + else if (attribute == xvColorKeyMode) { + pPriv->colorKeyMode = value; + LXSetColorkey(pScrni, pPriv); + } + else if (attribute == xvFilter) { + if ((value < 0) || (value > 1)) + return BadValue; + pPriv->filter = value; + } + else + return BadMatch; + + return Success; +} - if (area) { - if ((area->box.y2 - area->box.y1) >= numlines) - return area; +void +LXStopVideo(ScrnInfoPtr pScrni, pointer data, Bool exit) +{ + GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; + GeodeRec *pGeode = GEODEPTR(pScrni); - if (xf86ResizeOffscreenArea(area, pScrni->displayWidth, numlines)) - return area; + REGION_EMPTY(pScrni->pScreen, &pPriv->clip); + gp_wait_until_idle(); - xf86FreeOffscreenArea(area); + if (exit) { + if (pPriv->videoStatus & CLIENT_VIDEO_ON) { + df_set_video_enable(0,0); + df_set_video_palette(NULL); } - new_area = xf86AllocateOffscreenArea(pScrn, pScrni->displayWidth, - numlines, 0, NULL, NULL, NULL); - - if (!new_area) { - int max_w, max_h; - - xf86QueryLargestOffscreenArea(pScrn, &max_w, &max_h, 0, - FAVOR_WIDTH_THEN_AREA, PRIORITY_EXTREME); + if (pPriv->area) + exaOffscreenFree(pScrni->pScreen, pPriv->area); - if ((max_w < pScrni->displayWidth) || (max_h < numlines)) - return NULL; + pPriv->videoStatus = 0; - xf86PurgeUnlockedOffscreenAreas(pScrn); - new_area = xf86AllocateOffscreenArea(pScrn, pScrni->displayWidth, - numlines, 0, NULL, NULL, NULL); + /* Eh? */ + pGeode->OverlayON = FALSE; + } + else { + if (pPriv->videoStatus & CLIENT_VIDEO_ON) { + pPriv->videoStatus |= OFF_TIMER; + pPriv->offTime = currentTime.milliseconds + OFF_DELAY; } - - return new_area; + } } - -static BoxRec dstBox; -static int srcPitch = 0, srcPitch2 = 0, dstPitch = 0, dstPitch2 = 0; -static INT32 Bx1, Bx2, By1, By2; -static int top, left, npixels, nlines; -static int offset, s1offset = 0, s2offset = 0, s3offset = 0; -static unsigned char *dst_start; -static int d2offset = 0, d3offset = 0; - -static DF_VIDEO_SOURCE_PARAMS vSrcParams; - + void -LXSetVideoPosition(int x, int y, int width, int height, - short src_w, short src_h, short drw_w, short drw_h, - int id, int offset, ScrnInfoPtr pScrni) +LXResetVideo(ScrnInfoPtr pScrni) { - long ystart, xend, yend; - unsigned long lines = 0; - unsigned long y_extra, uv_extra = 0; - DF_VIDEO_POSITION vidPos; - - DBLOG(1, "LXSetVideoPosition(%d,%d %dx%d, src %dx%d, dst %dx%d, id %d, " - "ofs %d)\n", x, y, width, height, src_w, src_h, drw_w, drw_h, - id, offset); - - xend = x + drw_w; - yend = y + drw_h; - - /* TOP CLIPPING */ - - if (y < 0) { - if (src_h < drw_h) - lines = (-y) * src_h / drw_h; - else - lines = (-y); - ystart = 0; - drw_h += y; - y_extra = lines * dstPitch; - uv_extra = (lines >> 1) * (dstPitch2); - } else { - ystart = y; - lines = 0; - y_extra = 0; - } - - memset(&vidPos, 0, sizeof(vidPos)); - vidPos.x = x; - vidPos.y = ystart; - vidPos.width = xend - x; - vidPos.height = yend - ystart; - - DBLOG(1, "video_pos %d,%d %dx%d\n", vidPos.x, vidPos.y, vidPos.width, - vidPos.height); - df_set_video_position(&vidPos); - - vSrcParams.y_offset = offset + y_extra; - if ((id == FOURCC_Y800) || (id == FOURCC_I420) || (id == FOURCC_YV12)) { - vSrcParams.u_offset = offset + d3offset + uv_extra; - vSrcParams.v_offset = offset + d2offset + uv_extra; - } else { - vSrcParams.u_offset = vSrcParams.v_offset = 0; - } - vSrcParams.flags = DF_SOURCEFLAG_IMPLICITSCALING; - - DBLOG(1, "video_format %#x yofs %#x uofs %#x vofs %#x yp %d uvp %d wh " - "%dx%d flg %#x\n", vSrcParams.video_format, vSrcParams.y_offset, - vSrcParams.u_offset, vSrcParams.v_offset, vSrcParams.y_pitch, - vSrcParams.uv_pitch, vSrcParams.width, vSrcParams.height, - vSrcParams.flags); + GeodeRec *pGeode = GEODEPTR(pScrni); - df_configure_video_source(&vSrcParams, &vSrcParams); -} + if (!pGeode->NoAccel) { + GeodePortPrivRec *pPriv = pGeode->adaptor->pPortPrivates[0].ptr; -/*---------------------------------------------------------------------------- - * LXDisplayVideo - * - * Description : This function sets up the video registers for playing video - * It sets up the video format,width, height & position of the - * video window ,video offsets( y,u,v) and video pitches(y,u,v) - * Parameters. - * - * Returns :None - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ + gp_wait_until_idle(); + df_set_video_palette(NULL); -static void -LXDisplayVideo(ScrnInfoPtr pScrni, int id, int offset, short width, - short height, int pitch, int x1, int y1, int x2, int y2, - BoxPtr dstBox, short src_w, short src_h, short drw_w, short drw_h) -{ - DBLOG(1, "LXDisplayVideo(id %d, ofs %d, %dx%d, p %d, %d,%d, %d,%d, src " - "%dx%d dst %dx%d)\n", id, offset, width, height, pitch, x1, y1, - x2, y2, src_w, src_h, drw_w, drw_h); - - LXAccelSync(pScrni); - - switch (id) { - case FOURCC_UYVY: - vSrcParams.video_format = DF_VIDFMT_UYVY; - break; - case FOURCC_Y800: - case FOURCC_YV12: - case FOURCC_I420: - vSrcParams.video_format = DF_VIDFMT_Y0Y1Y2Y3; - break; - case FOURCC_YUY2: - vSrcParams.video_format = DF_VIDFMT_YUYV; - break; - case FOURCC_Y2YU: - vSrcParams.video_format = DF_VIDFMT_Y2YU; - break; - case FOURCC_YVYU: - vSrcParams.video_format = DF_VIDFMT_YVYU; - break; + LXSetColorkey(pScrni, pPriv); } - - vSrcParams.width = width; - vSrcParams.height = height; - vSrcParams.y_pitch = dstPitch; - vSrcParams.uv_pitch = dstPitch2; - - df_set_video_filter_coefficients(NULL, 1); - if ((drw_w >= src_w) && (drw_h >= src_h)) - df_set_video_scale(width, height, drw_w, drw_h, - DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY); - else if (drw_w < src_w) - df_set_video_scale(drw_w, height, drw_w, drw_h, - DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY); - else if (drw_h < src_h) - df_set_video_scale(width, drw_h, drw_w, drw_h, - DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY); - - LXSetVideoPosition(dstBox->x1, dstBox->y1, width, height, src_w, - src_h, drw_w, drw_h, id, offset, pScrni); - - df_set_video_enable(1, 0); } -#if REINIT -static Bool -RegionsEqual(RegionPtr A, RegionPtr B) +static void +LXVidBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask) { - int *dataA, *dataB; - int num; - - num = REGION_NUM_RECTS(A); - if (num != REGION_NUM_RECTS(B)) { - return FALSE; - } - - if ((A->extents.x1 != B->extents.x1) || - (A->extents.x2 != B->extents.x2) || - (A->extents.y1 != B->extents.y1) || (A->extents.y2 != B->extents.y2)) - return FALSE; + ScreenPtr pScrn = screenInfo.screens[i]; + ScrnInfoPtr pScrni = xf86Screens[i]; + GeodeRec *pGeode = GEODEPTR(pScrni); + GeodePortPrivRec *pPriv = GET_PORT_PRIVATE(pScrni); - dataA = (int *)REGION_RECTS(A); - dataB = (int *)REGION_RECTS(B); + pScrn->BlockHandler = pGeode->BlockHandler; + (*pScrn->BlockHandler) (i, blockData, pTimeout, pReadmask); + pScrn->BlockHandler = LXVidBlockHandler; - while (num--) { - if ((dataA[0] != dataB[0]) || (dataA[1] != dataB[1])) - return FALSE; - dataA += 2; - dataB += 2; + if (pPriv->videoStatus & TIMER_MASK) { + Time now = currentTime.milliseconds; + + if (pPriv->videoStatus & OFF_TIMER) { + gp_wait_until_idle(); + + if (pPriv->offTime < now) { + df_set_video_enable(0, 0); + pPriv->videoStatus = FREE_TIMER; + pPriv->freeTime = now + FREE_DELAY; + } + } + else { + if (pPriv->freeTime < now) { + if (pPriv->area) { + exaOffscreenFree(pScrni->pScreen, pPriv->area); + pPriv->area = NULL; + } + + pPriv->videoStatus = 0; + } + } } - - return TRUE; } -#endif - -/*---------------------------------------------------------------------------- - * LXPutImage : - * This function writes a single frame of video into a drawable. - * The position and size of the source rectangle is specified by src_x,src_y, - * src_w and src_h. This data is stored in a system memory buffer at buf. - * The position and size of the destination rectangle is specified by drw_x, - * drw_y,drw_w,drw_h.The data is in the format indicated by the image - * descriptor and represents a source of size width by height. If sync is - * TRUE the driver should not return from this function until it is through - * reading the data from buf. Returning when sync is TRUE indicates that - * it is safe for the data at buf to be replaced,freed, or modified. - * - * Description : - * Parameters. - * - * Returns :None - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ -static int -LXPutImage(ScrnInfoPtr pScrni, short src_x, short src_y, short drw_x, - short drw_y, short src_w, short src_h, short drw_w, short drw_h, - int id, unsigned char *buf, short width, short height, Bool sync, - RegionPtr clipBoxes, pointer data) +static XF86VideoAdaptorPtr +LXSetupImageVideo(ScreenPtr pScrn) { - GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; - GeodeRec *pGeode = GEODEPTR(pScrni); - int new_h; - -#if REINIT - BOOL ReInitVideo = FALSE; - static BOOL DoReinitAgain = 0; -#endif - -#if XV_PROFILE - long oldtime, newtime; - - UpdateCurrentTime(); - oldtime = currentTime.milliseconds; -#endif - DBLOG(1, "LXPutImage(src %d,%d %dx%d dst %d,%d %dx%d, id %d %dx%d sync " - "%d)\n", src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h, - id, width, height, sync); - -#if REINIT - /* update cliplist */ - if (!RegionsEqual(&pPriv->clip, clipBoxes)) { - ReInitVideo = TRUE; - } - - if (DoReinitAgain) - ReInitVideo = TRUE; - - if (ReInitVideo) { - DBLOG(1, "Regional Not Equal - Init\n"); -#endif - DoReinitAgain = ~DoReinitAgain; - if (drw_w > 16384) - drw_w = 16384; - - /* Clip */ - Bx1 = src_x; - Bx2 = src_x + src_w; - By1 = src_y; - By2 = src_y + src_h; - - if ((Bx1 >= Bx2) || (By1 >= By2)) - return Success; - - dstBox.x1 = drw_x; - dstBox.x2 = drw_x + drw_w; - dstBox.y1 = drw_y; - dstBox.y2 = drw_y + drw_h; - - dstBox.x1 -= pScrni->frameX0; - dstBox.x2 -= pScrni->frameX0; - dstBox.y1 -= pScrni->frameY0; - dstBox.y2 -= pScrni->frameY0; - - switch (id) { - case FOURCC_YV12: - case FOURCC_I420: - srcPitch = (width + 3) & ~3; /* of luma */ - dstPitch = (width + 31) & ~31; - - s2offset = srcPitch * height; - d2offset = dstPitch * height; - - srcPitch2 = ((width >> 1) + 3) & ~3; - dstPitch2 = ((width >> 1) + 15) & ~15; - - s3offset = (srcPitch2 * (height >> 1)) + s2offset; - d3offset = (dstPitch2 * (height >> 1)) + d2offset; - - new_h = dstPitch * height; /* Y */ - new_h += (dstPitch2 * height); /* U+V */ - new_h += pGeode->Pitch - 1; - new_h /= pGeode->Pitch; - break; - - case FOURCC_UYVY: - case FOURCC_YUY2: - case FOURCC_Y800: - default: - dstPitch = ((width << 1) + 3) & ~3; - srcPitch = (width << 1); - new_h = ((dstPitch * height) + pGeode->Pitch - 1) / pGeode->Pitch; - break; - } - -#if DBUF - if (pPriv->doubleBuffer) - new_h <<= 1; -#endif - - if (!(pPriv->area = LXAllocateMemory(pScrni, pPriv->area, new_h))) - return BadAlloc; - - /* copy data */ - top = By1; - left = Bx1 & ~1; - npixels = ((Bx2 + 1) & ~1) - left; - - switch (id) { - case FOURCC_YV12: - case FOURCC_I420:{ - int tmp; - - top &= ~1; - offset = (pPriv->area->box.y1 * pGeode->Pitch) + - (top * dstPitch); - -#if DBUF - if (pPriv->doubleBuffer && pPriv->currentBuffer) - offset += (new_h >> 1) * pGeode->Pitch; -#endif - - dst_start = pGeode->FBBase + offset + left; - tmp = ((top >> 1) * srcPitch2) + (left >> 1); - s2offset += tmp; - s3offset += tmp; - if (id == FOURCC_I420) { - tmp = s2offset; - s2offset = s3offset; - s3offset = tmp; - } - nlines = ((By2 + 1) & ~1) - top; - } - break; - - case FOURCC_UYVY: - case FOURCC_YUY2: - case FOURCC_Y800: - default: - left <<= 1; - buf += (top * srcPitch) + left; - nlines = By2 - top; - offset = (pPriv->area->box.y1 * pGeode->Pitch) + (top * dstPitch); -#if DBUF - if (pPriv->doubleBuffer && pPriv->currentBuffer) - offset += (new_h >> 1) * pGeode->Pitch; -#endif + ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; + GeodeRec *pGeode = GEODEPTR(pScrni); + XF86VideoAdaptorPtr adapt; + GeodePortPrivRec *pPriv; + + adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + + sizeof(GeodePortPrivRec) + sizeof(DevUnion)); + + if (adapt == NULL) { + ErrorF("Couldn't create the rec\n"); + return NULL; + } + + adapt->type = XvWindowMask | XvInputMask | XvImageMask; + adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + + adapt->name = "AMD Geode LX"; + adapt->nEncodings = 1; + adapt->pEncodings = DummyEncoding; + adapt->nFormats = ARRAY_SIZE(Formats); + adapt->pFormats = Formats; + adapt->nPorts = 1; + adapt->pPortPrivates = (DevUnion *) (&adapt[1]); + pPriv = (GeodePortPrivRec *) (&adapt->pPortPrivates[1]); + adapt->pPortPrivates[0].ptr = (pointer) (pPriv); + adapt->pAttributes = Attributes; + adapt->nImages = ARRAY_SIZE(Images); + adapt->nAttributes = ARRAY_SIZE(Attributes); + adapt->pImages = Images; + adapt->PutVideo = NULL; + adapt->PutStill = NULL; + adapt->GetVideo = NULL; + adapt->GetStill = NULL; + adapt->StopVideo= LXStopVideo; + adapt->SetPortAttribute = LXSetPortAttribute; + adapt->GetPortAttribute = LXGetPortAttribute; + adapt->QueryBestSize = LXQueryBestSize; + adapt->PutImage =LXPutImage; + + /* Use the common function */ + adapt->QueryImageAttributes = GeodeQueryImageAttributes; + + pPriv->filter = 0; + pPriv->colorKey = pGeode->videoKey; + pPriv->colorKeyMode = 0; + pPriv->videoStatus = 0; + + REGION_NULL(pScrn, &pPriv->clip); + + pGeode->adaptor = adapt; + + pGeode->BlockHandler = pScrn->BlockHandler; + pScrn->BlockHandler = LXVidBlockHandler; + + xvColorKey = MAKE_ATOM("XV_COLORKEY"); + xvColorKeyMode = MAKE_ATOM("XV_COLORKEYMODE"); + xvFilter = MAKE_ATOM("XV_FILTER"); + + LXResetVideo(pScrni); + + return adapt; +} - dst_start = pGeode->FBBase + offset + left; - break; - } - s1offset = (top * srcPitch) + left; - -#if REINIT - /* update cliplist */ - REGION_COPY(pScrni->pScreen, &pPriv->clip, clipBoxes); - if (pPriv->colorKeyMode == 0) { - /* draw these */ - XAAFillSolidRects(pScrni, pPriv->colorKey, GXcopy, ~0, - REGION_NUM_RECTS(clipBoxes), REGION_RECTS(clipBoxes)); - } - LXDisplayVideo(pScrni, id, offset, width, height, dstPitch, - Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, drw_h); - } -#endif +/* Offscreen surface allocation */ - switch (id) { - case FOURCC_Y800: - LXCopyGreyscale(buf, dst_start, srcPitch, dstPitch, nlines, npixels); - break; - case FOURCC_YV12: - case FOURCC_I420: - LXCopyData420(buf + s1offset, dst_start, srcPitch, dstPitch, nlines, - npixels); - LXCopyData420(buf + s2offset, dst_start + d2offset, srcPitch2, - dstPitch2, nlines >> 1, npixels >> 1); - LXCopyData420(buf + s3offset, dst_start + d3offset, srcPitch2, - dstPitch2, nlines >> 1, npixels >> 1); - break; - case FOURCC_UYVY: - case FOURCC_YUY2: - default: - LXCopyData422(buf, dst_start, srcPitch, dstPitch, nlines, npixels); - break; - } -#if !REINIT - /* update cliplist */ - REGION_COPY(pScrni->pScreen, &pPriv->clip, clipBoxes); - if (pPriv->colorKeyMode == 0) { - /* draw these */ - XAAFillSolidRects(pScrni, pPriv->colorKey, GXcopy, ~0, - REGION_NUM_RECTS(clipBoxes), REGION_RECTS(clipBoxes)); - } - LXDisplayVideo(pScrni, id, offset, width, height, dstPitch, - Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, drw_h); -#endif +struct OffscreenPrivRec +{ + void * area; + int offset; + Bool isOn; +}; -#if XV_PROFILE - UpdateCurrentTime(); - newtime = currentTime.milliseconds; - DBLOG(1, "PI %d\n", newtime - oldtime); -#endif +static int +LXDisplaySurface(XF86SurfacePtr surface, + short srcX, short srcY, short drawX, short drawY, + short srcW, short srcH, short drawW, short drawH, + RegionPtr clipBoxes) +{ + struct OffscreenPrivRec *pPriv = + (struct OffscreenPrivRec *) surface->devPrivate.ptr; -#if DBUF - pPriv->currentBuffer ^= 1; -#endif + ScrnInfoPtr pScrni = surface->pScrn; + GeodePortPrivRec *portPriv = GET_PORT_PRIVATE(pScrni); + + INT32 x1, y1, x2, y2; + BoxRec dstBox; - pPriv->videoStatus = CLIENT_VIDEO_ON; - pGeode->OverlayON = TRUE; + dstBox.x1 = drawX; + dstBox.x2 = drawX + drawW; + dstBox.y1 = drawY; + dstBox.y2 = drawY + drawH; + if (drawW <= 0 | drawH <=0) return Success; -} - -/*---------------------------------------------------------------------------- - * LXQueryImageAttributes - * - * Description :This function is called to let the driver specify how data - * for a particular image of size width by height should be - * stored. - * - * Parameters. - * pScrni :Screen handler pointer having screen information. - * id :Id for the video format - * width :width of the image (can be modified by the driver) - * height :height of the image (can be modified by the driver) - * Returns : Size of the memory required for storing this image - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ -static int -LXQueryImageAttributes(ScrnInfoPtr pScrni, int id, unsigned short *w, - unsigned short *h, int *pitches, int *offsets) -{ - int size; - int tmp; - - if (*w > 1024) - *w = 1024; - if (*h > 1024) - *h = 1024; - - *w = (*w + 1) & ~1; - if (offsets) - offsets[0] = 0; - - switch (id) { - case FOURCC_YV12: - case FOURCC_I420: - *h = (*h + 1) & ~1; - size = (*w + 3) & ~3; - if (pitches) - pitches[0] = size; - size *= *h; - if (offsets) - offsets[1] = size; - tmp = ((*w >> 1) + 3) & ~3; - if (pitches) - pitches[1] = pitches[2] = tmp; - tmp *= (*h >> 1); - size += tmp; - if (offsets) - offsets[2] = size; - size += tmp; - break; - case FOURCC_UYVY: - case FOURCC_YUY2: - case FOURCC_Y800: - default: - size = *w << 1; - if (pitches) - pitches[0] = size; - size *= *h; - break; - } - DBLOG(1, "LXQueryImageAttributes(%d)= %d, %dx%d %d/%d/%d %d/%d/%d\n", - id, size, *w, *h, pitches[0], pitches[1], pitches[2], offsets[0], - offsets[1], offsets[2]); + /* Is this still valid? */ - return size; -} + dstBox.x1 -= pScrni->frameX0; + dstBox.x2 -= pScrni->frameX0; + dstBox.y1 -= pScrni->frameY0; + dstBox.y2 -= pScrni->frameY0; -static void -LXBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask) -{ - ScreenPtr pScrn = screenInfo.screens[i]; - ScrnInfoPtr pScrni = xf86Screens[i]; - GeodeRec *pGeode = GEODEPTR(pScrni); - GeodePortPrivRec *pPriv = GET_PORT_PRIVATE(pScrni); + xf86XVFillKeyHelper(pScrni->pScreen, portPriv->colorKey, clipBoxes); - pScrn->BlockHandler = pGeode->BlockHandler; - (*pScrn->BlockHandler) (i, blockData, pTimeout, pReadmask); - pScrn->BlockHandler = LXBlockHandler; + videoScratch.dstOffset = surface->offsets[0]; + videoScratch.dstPitch = surface->pitches[0]; - if (pPriv->videoStatus & TIMER_MASK) { - DBLOG(1, "LXBlockHandler(%d)\n", i); - LXAccelSync(pScrni); - UpdateCurrentTime(); - if (pPriv->videoStatus & OFF_TIMER) { - if (pPriv->offTime < currentTime.milliseconds) { - df_set_video_enable(0, 0); - pPriv->videoStatus = FREE_TIMER; - pPriv->freeTime = currentTime.milliseconds + FREE_DELAY; - } - } else { /* FREE_TIMER */ - if (pPriv->freeTime < currentTime.milliseconds) { - if (pPriv->area) { - xf86FreeOffscreenArea(pPriv->area); - pPriv->area = NULL; - } - pPriv->videoStatus = 0; - } - } - } -} + LXDisplayVideo(pScrni, surface->id, surface->width, surface->height, + &dstBox, srcW, srcH, drawW, drawH); -/****************** Offscreen stuff ***************/ + pPriv->isOn = TRUE; + + if (portPriv->videoStatus & CLIENT_VIDEO_ON) { + REGION_EMPTY(pScrni->pScreen, &portPriv->clip); + UpdateCurrentTime(); + portPriv->videoStatus = FREE_TIMER; + portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; + } -typedef struct -{ - FBAreaPtr area; - FBLinearPtr linear; - Bool isOn; + return Success; } -OffscreenPrivRec, *OffscreenPrivPtr; - -/*---------------------------------------------------------------------------- - * LXAllocateSurface - * - * Description :This function allocates an area of w by h in the offscreen - * Parameters. - * pScrni :Screen handler pointer having screen information. - * - * Returns :None - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ -static int +static int LXAllocateSurface(ScrnInfoPtr pScrni, int id, unsigned short w, - unsigned short h, XF86SurfacePtr surface) + unsigned short h, XF86SurfacePtr surface) { - FBAreaPtr area; - int pitch, fbpitch, numlines; - OffscreenPrivRec *pPriv; + GeodeRec *pGeode = GEODEPTR(pScrni); + void * area = NULL; + int pitch, fbpitch, lines; + unsigned offset; + struct OffscreenPrivRec *pPriv; - DBLOG(1, "LXAllocateSurface(id %d, %dx%d)\n", id, w, h); + if (w > 1024 || h > 1024) + return BadAlloc; - if ((w > 1024) || (h > 1024)) - return BadAlloc; + /* The width needs to be word aligned */ + w = (w + 1) & ~1; - w = (w + 1) & ~1; - pitch = ((w << 1) + 15) & ~15; - fbpitch = pScrni->bitsPerPixel * pScrni->displayWidth >> 3; - numlines = ((pitch * h) + fbpitch - 1) / fbpitch; + pitch = ((w << 1) + 15) & ~15; + lines = ((pitch * h) + (pGeode->Pitch - 1)) / pGeode->Pitch; + + if (!(offset = LXVidAllocMem(pScrni, &area, lines))) + return BadAlloc; - if (!(area = LXAllocateMemory(pScrni, NULL, numlines))) - return BadAlloc; + surface->width = w; + surface->height = h; + + surface->pitches = xalloc(sizeof(int)); - surface->width = w; - surface->height = h; + surface->offsets = xalloc(sizeof(int)); - if (!(surface->pitches = xalloc(sizeof(int)))) - return BadAlloc; - if (!(surface->offsets = xalloc(sizeof(int)))) { - xfree(surface->pitches); - return BadAlloc; - } - if (!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) { - xfree(surface->pitches); - xfree(surface->offsets); - return BadAlloc; - } + pPriv = xalloc(sizeof(struct OffscreenPrivRec)); + if (pPriv && surface->pitches && surface->offsets) { + pPriv->area = area; + pPriv->offset = offset; + pPriv->isOn = FALSE; - + surface->pScrn = pScrni; surface->id = id; surface->pitches[0] = pitch; - surface->offsets[0] = area->box.y1 * fbpitch; + surface->offsets[0] = offset; surface->devPrivate.ptr = (pointer) pPriv; - + return Success; + } + + if (surface->offsets) + xfree(surface->offsets); + + if (surface->pitches) + xfree(surface->pitches); + + if (area) + exaOffscreenFree(pScrni->pScreen, area); + + return BadAlloc; } static int -LXStopSurface(XF86SurfacePtr surface) +LXStopSurface(XF86SurfacePtr surface) { - OffscreenPrivRec *pPriv = (OffscreenPrivRec *) surface->devPrivate.ptr; + struct OffscreenPrivRec *pPriv = (struct OffscreenPrivRec *) + surface->devPrivate.ptr; - DBLOG(1, "LXStopSurface()\n"); - - if (pPriv->isOn) { - pPriv->isOn = FALSE; - } - - return Success; + pPriv->isOn = FALSE; + return Success; } static int LXFreeSurface(XF86SurfacePtr surface) { - OffscreenPrivRec *pPriv = (OffscreenPrivRec *) surface->devPrivate.ptr; - - DBLOG(1, "LXFreeSurface()\n"); + struct OffscreenPrivRec *pPriv = (struct OffscreenPrivRec *) + surface->devPrivate.ptr; + ScrnInfoPtr pScrni = surface->pScrn; - if (pPriv->isOn) - LXStopSurface(surface); + if (pPriv->isOn) + LXStopSurface(surface); - xf86FreeOffscreenArea(pPriv->area); - xfree(surface->pitches); - xfree(surface->offsets); - xfree(surface->devPrivate.ptr); + if (pPriv->area) + exaOffscreenFree(pScrni->pScreen, pPriv->area); - return Success; + xfree(surface->pitches); + xfree(surface->offsets); + xfree(surface->devPrivate.ptr); + + return Success; } static int @@ -1375,98 +906,78 @@ LXSetSurfaceAttribute(ScrnInfoPtr pScrni, Atom attribute, INT32 value) (pointer) (GET_PORT_PRIVATE(pScrni))); } -static int -LXDisplaySurface(XF86SurfacePtr surface, short src_x, short src_y, - short drw_x, short drw_y, short src_w, short src_h, - short drw_w, short drw_h, RegionPtr clipBoxes) -{ - OffscreenPrivRec *pPriv = (OffscreenPrivRec *) surface->devPrivate.ptr; - ScrnInfoPtr pScrni = surface->pScrn; - GeodePortPrivRec *portPriv = GET_PORT_PRIVATE(pScrni); - INT32 x1, y1, x2, y2; - BoxRec dstBox; - - DBLOG(1, "LXDisplaySurface(src %d,%d %dx%d, dst %d,%d %dx%d)\n", - src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h); - - DEBUGMSG(0, (0, X_NONE, "DisplaySuface\n")); - x1 = src_x; - x2 = src_x + src_w; - y1 = src_y; - y2 = src_y + src_h; - - dstBox.x1 = drw_x; - dstBox.x2 = drw_x + drw_w; - dstBox.y1 = drw_y; - dstBox.y2 = drw_y + drw_h; - - if ((x1 >= x2) || (y1 >= y2)) - return Success; - - dstBox.x1 -= pScrni->frameX0; - dstBox.x2 -= pScrni->frameX0; - dstBox.y1 -= pScrni->frameY0; - dstBox.y2 -= pScrni->frameY0; - - xf86XVFillKeyHelper(pScrni->pScreen, portPriv->colorKey, clipBoxes); - - LXDisplayVideo(pScrni, surface->id, surface->offsets[0], - surface->width, surface->height, surface->pitches[0], - x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); - - pPriv->isOn = TRUE; - if (portPriv->videoStatus & CLIENT_VIDEO_ON) { - REGION_EMPTY(pScrni->pScreen, &portPriv->clip); - UpdateCurrentTime(); - portPriv->videoStatus = FREE_TIMER; - portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; - } - - return Success; -} -/*---------------------------------------------------------------------------- - * LXInitOffscreenImages - * - * Description :This function sets up the offscreen memory management.It fills - * in the XF86OffscreenImagePtr structure with functions to handle - * offscreen memory operations. - * - * Parameters. - * pScrn :Screen handler pointer having screen information. - * - * Returns : None - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ static void -LXInitOffscreenImages(ScreenPtr pScrn) +LXInitOffscreenImages(ScreenPtr pScrn) { - XF86OffscreenImagePtr offscreenImages; - - DBLOG(1, "LXInitOffscreenImages()\n"); - - /* need to free this someplace */ - if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) - return; - - offscreenImages[0].image = &Images[0]; - offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; - offscreenImages[0].alloc_surface = LXAllocateSurface; - offscreenImages[0].free_surface = LXFreeSurface; - offscreenImages[0].display = LXDisplaySurface; - offscreenImages[0].stop = LXStopSurface; - offscreenImages[0].setAttribute = LXSetSurfaceAttribute; - offscreenImages[0].getAttribute = LXGetSurfaceAttribute; - offscreenImages[0].max_width = 1024; - offscreenImages[0].max_height = 1024; - offscreenImages[0].num_attributes = NUM_ATTRIBUTES; - offscreenImages[0].attributes = Attributes; - - xf86XVRegisterOffscreenImages(pScrn, offscreenImages, 1); + XF86OffscreenImagePtr offscreenImages; + + /* need to free this someplace */ + if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) + return; + + offscreenImages[0].image = &Images[0]; + offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + offscreenImages[0].alloc_surface = LXAllocateSurface; + offscreenImages[0].free_surface = LXFreeSurface; + offscreenImages[0].display = LXDisplaySurface; + offscreenImages[0].stop = LXStopSurface; + offscreenImages[0].setAttribute = LXSetSurfaceAttribute; + offscreenImages[0].getAttribute = LXGetSurfaceAttribute; + offscreenImages[0].max_width = 1024; + offscreenImages[0].max_height = 1024; + offscreenImages[0].num_attributes = ARRAY_SIZE(Attributes); + offscreenImages[0].attributes = Attributes; + + xf86XVRegisterOffscreenImages(pScrn, offscreenImages, 1); +} + +void +LXInitVideo(ScreenPtr pScrn) +{ + GeodeRec *pGeode; + ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; + XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; + XF86VideoAdaptorPtr newAdaptor = NULL; + int num_adaptors; + + pGeode = GEODEPTR(pScrni); + + if (pGeode->NoAccel) { + ErrorF("Cannot run Xv without accelerations!\n"); + return; + } + + if (!(newAdaptor = LXSetupImageVideo(pScrn))) { + ErrorF("Error while setting up the adaptor.\n"); + return; + } + + LXInitOffscreenImages(pScrn); + + num_adaptors = xf86XVListGenericAdaptors(pScrni, &adaptors); + + if (!num_adaptors) { + num_adaptors = 1; + adaptors = &newAdaptor; + } else { + newAdaptors = + xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr *)); + + if (newAdaptors) { + memcpy(newAdaptors, adaptors, num_adaptors * + sizeof(XF86VideoAdaptorPtr)); + newAdaptors[num_adaptors] = newAdaptor; + adaptors = newAdaptors; + num_adaptors++; + } + else + ErrorF("Memory error while setting up the adaptor\n"); + } + + if (num_adaptors) + xf86XVScreenInit(pScrn, adaptors, num_adaptors); + + if (newAdaptors) + xfree(newAdaptors); } - -#endif /* !XvExtension */ -#endif /* !AMD_V4L2_VIDEO */ diff --git a/src/cim/cim_gp.c b/src/cim/cim_gp.c index fc105c9..04c901e 100644 --- a/src/cim/cim_gp.c +++ b/src/cim/cim_gp.c @@ -1151,6 +1151,7 @@ gp_screen_to_screen_blt(unsigned long dstoffset, unsigned long srcoffset, gp3_cmd_current = gp3_cmd_next; } + /*--------------------------------------------------------------------------- * gp_screen_to_screen_convert * @@ -3390,3 +3391,192 @@ gp_restore_state(GP_SAVE_RESTORE * gp_state) gp_set_command_buffer_base(gp_state->cmd_base, gp_state->cmd_top, gp_state->cmd_bottom); } + +/* This is identical to gp_antialiased_text, except we support all one + pass alpha operations similar to gp_set_alpha_operation */ + + +void +gp_blend_mask_blt(unsigned long dstoffset, unsigned long srcx, + unsigned long width, unsigned long height, + unsigned char *data, long stride, int operation, + int fourbpp) +{ + unsigned long indent, temp; + unsigned long total_dwords, size_dwords; + unsigned long dword_count, byte_count; + unsigned long size = ((width << 16) | height); + unsigned long ch3_offset, srcoffset; + unsigned long base, depth_flag; + + base = ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)) | + (gp3_base_register & ~GP3_BASE_OFFSET_DSTMASK); + + /* ENABLE ALL RELEVANT REGISTERS */ + /* We override the raster mode register to force the */ + /* correct alpha blend */ + + gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE | + GP3_BLT_HDR_DST_OFF_ENABLE | + GP3_BLT_HDR_WIDHI_ENABLE | + GP3_BLT_HDR_CH3_OFF_ENABLE | + GP3_BLT_HDR_CH3_STR_ENABLE | + GP3_BLT_HDR_CH3_WIDHI_ENABLE | + GP3_BLT_HDR_BASE_OFFSET_ENABLE | GP3_BLT_HDR_BLT_MODE_ENABLE; + + /* CALCULATIONS BASED ON ALPHA DEPTH */ + /* Although most antialiased text is 4BPP, the hardware supports */ + /* a full 8BPP. Either case is supported by this routine. */ + + if (fourbpp) { + depth_flag = GP3_CH3_SRC_4BPP_ALPHA; + indent = (srcx >> 1); + srcoffset = (indent & ~3L); + indent &= 3; + ch3_offset = indent | ((srcx & 1) << 25); + + temp = ((width + (srcx & 1) + 1) >> 1) + indent; + } else { + depth_flag = GP3_CH3_SRC_8BPP_ALPHA; + indent = srcx; + srcoffset = (indent & ~3L); + indent &= 3; + ch3_offset = indent; + + temp = width + indent; + } + + total_dwords = (temp + 3) >> 2; + size_dwords = (total_dwords << 2) + 8; + dword_count = (temp >> 2); + byte_count = (temp & 3); + + /* SET RASTER MODE REGISTER */ + /* Alpha blending will only apply to RGB when no alpha component is present. */ + /* As 8BPP is not supported for this routine, the only alpha-less mode is */ + /* 5:6:5. */ + + if (gp3_bpp == GP3_RM_BPPFMT_565) { + WRITE_COMMAND32(GP3_BLT_RASTER_MODE, + gp3_bpp | + GP3_RM_ALPHA_TO_RGB | + GP3_RM_ALPHA_A_PLUS_BETA_B | GP3_RM_SELECT_ALPHA_CHAN_3); + } else { + WRITE_COMMAND32(GP3_BLT_RASTER_MODE, + gp3_bpp | + GP3_RM_ALPHA_ALL | + ((unsigned long) operation << 20) | GP3_RM_SELECT_ALPHA_CHAN_3); + } + + /* WRITE ALL REMAINING REGISTERS */ + + WRITE_COMMAND32(GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF)); + WRITE_COMMAND32(GP3_BLT_CH3_OFFSET, ch3_offset); + WRITE_COMMAND32(GP3_BLT_WID_HEIGHT, size); + WRITE_COMMAND32(GP3_BLT_CH3_WIDHI, size); + WRITE_COMMAND32(GP3_BLT_BASE_OFFSET, base); + WRITE_COMMAND32(GP3_BLT_CH3_MODE_STR, GP3_CH3_C3EN | + GP3_CH3_HST_SRC_ENABLE | + depth_flag | ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20)); + WRITE_COMMAND32(GP3_BLT_MODE, gp3_blt_mode | GP3_BM_DST_REQ); + + /* START THE BLT */ + + WRITE_COMMAND32(GP3_BLT_CMD_HEADER, gp3_cmd_header); + WRITE_GP32(GP3_CMD_WRITE, gp3_cmd_next); + gp3_cmd_current = gp3_cmd_next; + + /* WRITE DATA LINE BY LINE + * Each line will be created as a separate command buffer entry to allow + * line-by-line wrapping and to allow simultaneous rendering by the HW. + */ + + if (((total_dwords << 2) * height) <= GP3_BLT_1PASS_SIZE && + (gp3_cmd_bottom - gp3_cmd_current) > (GP3_BLT_1PASS_SIZE + 72)) { + /* UPDATE THE COMMAND POINTER */ + + cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current; + + /* CHECK IF A WRAP WILL BE NEEDED */ + + gp3_cmd_next = gp3_cmd_current + ((total_dwords << 2) * height) + 8; + + if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE) { + gp3_cmd_next = gp3_cmd_top; + + GP3_WAIT_WRAP(temp); + WRITE_COMMAND32(0, + GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP | + GP3_DATA_LOAD_HDR_ENABLE); + } else { + GP3_WAIT_PRIMITIVE(temp); + WRITE_COMMAND32(0, + GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE); + } + + /* WRITE DWORD COUNT */ + + WRITE_COMMAND32(4, + GP3_CH3_HOST_SOURCE_TYPE | (total_dwords * height)); + + while (height--) { + /* WRITE DATA */ + + WRITE_COMMAND_STRING32(8, data, srcoffset, dword_count); + WRITE_COMMAND_STRING8(8 + (dword_count << 2), data, + srcoffset + (dword_count << 2), byte_count); + + srcoffset += stride; + cim_cmd_ptr += total_dwords << 2; + } + + WRITE_GP32(GP3_CMD_WRITE, gp3_cmd_next); + gp3_cmd_current = gp3_cmd_next; + } else { + while (height--) { + /* UPDATE THE COMMAND POINTER + * The WRITE_COMMANDXX macros use a pointer to the current buffer + * space. This is created by adding gp3_cmd_current to the base + * pointer. + */ + + cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current; + + /* CHECK IF A WRAP WILL BE NEEDED */ + + gp3_cmd_next = gp3_cmd_current + size_dwords; + if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE) { + gp3_cmd_next = gp3_cmd_top; + + /* WAIT FOR HARDWARE */ + + GP3_WAIT_WRAP(temp); + WRITE_COMMAND32(0, + GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP | + GP3_DATA_LOAD_HDR_ENABLE); + } else { + /* WAIT FOR AVAILABLE SPACE */ + + GP3_WAIT_PRIMITIVE(temp); + WRITE_COMMAND32(0, + GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE); + } + + /* WRITE DWORD COUNT */ + + WRITE_COMMAND32(4, GP3_CH3_HOST_SOURCE_TYPE | total_dwords); + + /* WRITE DATA */ + + WRITE_COMMAND_STRING32(8, data, srcoffset, dword_count); + WRITE_COMMAND_STRING8(8 + (dword_count << 2), data, + srcoffset + (dword_count << 2), byte_count); + + /* UPDATE POINTERS */ + + srcoffset += stride; + WRITE_GP32(GP3_CMD_WRITE, gp3_cmd_next); + gp3_cmd_current = gp3_cmd_next; + } + } +} diff --git a/src/cim/cim_rtns.h b/src/cim/cim_rtns.h index ce149cd..6fecb4b 100644 --- a/src/cim/cim_rtns.h +++ b/src/cim/cim_rtns.h @@ -125,7 +125,10 @@ extern "C" void gp_antialiased_text(unsigned long dstoffset, unsigned long srcx, unsigned long width, unsigned long height, unsigned char *data, long stride, int fourbpp); - void gp_masked_blt(unsigned long dstoffset, unsigned long width, + void gp_blend_mask_blt(unsigned long dstoffset, unsigned long srcx, + unsigned long width, unsigned long height, unsigned char *data, + long stride, int operation, int fourbpp); + void gp_masked_blt(unsigned long dstoffset, unsigned long width, unsigned long height, unsigned long mono_srcx, unsigned long color_srcx, unsigned char *mono_mask, unsigned char *color_data, long mono_pitch, long color_pitch); |