diff options
author | Jordan Crouse <jordan.crouse@amd.com> | 2008-09-10 17:33:30 -0600 |
---|---|---|
committer | Jordan Crouse <jordan.crouse@amd.com> | 2008-09-10 17:33:30 -0600 |
commit | f66c9d1928ec9bcde57009c7263f6c8575ad0d0c (patch) | |
tree | 2ce0a6775393bae11547d9d9517f7168f5242698 | |
parent | 85d2103a90e6ab422246b66d252dbee19c96a0d7 (diff) | |
parent | 62d2b0ede08042147ca528be9ab1e392886a10ff (diff) |
Merge branch 'randr12-branch'
Conflicts:
src/geode_ddc.c
src/gx_randr.c
src/lx_randr.c
src/lx_rotate.c
-rw-r--r-- | src/Makefile.am | 7 | ||||
-rw-r--r-- | src/geode.h | 295 | ||||
-rw-r--r-- | src/geode_dcon.c | 28 | ||||
-rw-r--r-- | src/geode_ddc.c | 53 | ||||
-rw-r--r-- | src/geode_driver.c | 5 | ||||
-rw-r--r-- | src/gx_accel.c | 4 | ||||
-rw-r--r-- | src/gx_driver.c | 21 | ||||
-rw-r--r-- | src/gx_randr.c | 6 | ||||
-rw-r--r-- | src/gx_video.c | 4 | ||||
-rw-r--r-- | src/lx_cursor.c | 196 | ||||
-rw-r--r-- | src/lx_display.c | 499 | ||||
-rw-r--r-- | src/lx_driver.c | 749 | ||||
-rw-r--r-- | src/lx_exa.c | 405 | ||||
-rw-r--r-- | src/lx_memory.c | 297 | ||||
-rw-r--r-- | src/lx_output.c | 272 | ||||
-rw-r--r-- | src/lx_panel.c | 142 | ||||
-rw-r--r-- | src/lx_randr.c | 370 | ||||
-rw-r--r-- | src/lx_regacc.c | 65 | ||||
-rw-r--r-- | src/lx_rotate.c | 282 | ||||
-rw-r--r-- | src/lx_vga.c | 2 | ||||
-rw-r--r-- | src/lx_video.c | 108 |
21 files changed, 1827 insertions, 1983 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 15c9f66..a162d26 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -59,10 +59,11 @@ geode_drv_la_SOURCES = \ panel.c \ lx_driver.c \ lx_cursor.c \ + lx_memory.c \ + lx_panel.c \ + lx_output.c \ + lx_display.c \ lx_video.c \ - lx_regacc.c \ - lx_rotate.c \ - lx_randr.c \ lx_exa.c \ cimarron.c \ geode_pcirename.h diff --git a/src/geode.h b/src/geode.h index 2c2ce89..3a281f2 100644 --- a/src/geode.h +++ b/src/geode.h @@ -1,5 +1,5 @@ /* - * (c) 2006 Advanced Micro Devices, Inc. + * (c) 2006-2008 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"), @@ -88,46 +88,13 @@ #define GFX2(func) gfx2_##func #endif -#ifdef HAVE_LX -#define LX_FILL_RECT_SUPPORT 1 -#define LX_BRES_LINE_SUPPORT 1 -#define LX_DASH_LINE_SUPPORT 1 -#define LX_MONO_8X8_PAT_SUPPORT 1 -#define LX_CLREXP_8X8_PAT_SUPPORT 1 -#define LX_SCR2SCREXP_SUPPORT 1 -#define LX_SCR2SCRCPY_SUPPORT 1 -#define LX_CPU2SCREXP_SUPPORT 1 -#define LX_SCANLINE_SUPPORT 1 -#define LX_USE_OFFSCRN_MEM 1 -#define LX_WRITE_PIXMAP_SUPPORT 1 -#endif - -#define DEBUGTIM 0 -#define DEBUGLVL 0 - -#ifndef DEBUGTIM -#define DEBUGTIM 0 -#endif -#ifndef DEBUGLVL -#define DEBUGLVL 0 -#endif - #define GEODEPTR(p) ((GeodeRec *)((p)->driverPrivate)) -#define DEFAULT_IMG_LINE_BUFS 20 -#define DEFAULT_CLR_LINE_BUFS 20 #define DEFAULT_EXA_SCRATCH_BFRSZ 0x40000 -/* 64x64 cursor used as 32x32 */ -#define HW_CURSOR_W 64 -#define HW_CURSOR_H 64 +/* FIXME: Get rid of this from GX */ -#define MYDBG 1 -#if defined(MYDBG) -#define DEBUGMSG(cond, drv_msg) if((cond)) xf86DrvMsg drv_msg -#else #define DEBUGMSG(cond, drv_msg) -#endif #ifdef HAVE_LX extern unsigned char cim_inb(unsigned short port); @@ -139,17 +106,13 @@ extern void cim_outd(unsigned short port, unsigned long data); #include "cim_rtns.h" -#define CIM_CMD_BFR_SZ 0x200000L -#define CIM_CMD_BFR_MIN 0x20000L - -typedef struct tag_CIM_DISPLAYTIMING +typedef struct _CIM_DISPLAYTIMING { unsigned short wPitch; unsigned short wBpp; - VG_DISPLAY_MODE vgDisplayMode; -} -CIM_DISPLAYTIMING; +} CIM_DISPLAYTIMING; + #endif #ifdef HAVE_GX @@ -172,18 +135,6 @@ extern void gfx_outd(unsigned short port, unsigned long data); #undef Q_WORD #include "panel.h" -typedef struct __TVPARAMS -{ - unsigned int dwFlags; - unsigned short wWidth; - unsigned short wHeight; - unsigned short wStandard; - unsigned short wType; - unsigned short wOutput; - unsigned short wResolution; - Bool bState; -} TVPARAMS; - typedef struct tag_GFX_DISPLAYTIMING { unsigned int dwDotClock; @@ -204,31 +155,20 @@ typedef struct tag_GFX_DISPLAYTIMING unsigned short wPolarity; } GFX_DISPLAYTIMING; -/* TV Timings */ -typedef struct __TVTIMING -{ - unsigned long HorzTim; - unsigned long HorzSync; - unsigned long VertSync; - unsigned long LineEnd; - unsigned long VertDownscale; - unsigned long HorzScaling; - unsigned long TimCtrl1; - unsigned long TimCtrl2; - unsigned long Subfreq; - unsigned long DispPos; - unsigned long DispSize; - unsigned long Debug; - unsigned long DacCtrl; - unsigned int DotClock; -} TVTIMING; #endif typedef struct _VESARec { xf86Int10InfoPtr pInt; -} -VESARec; +} VESARec; + +typedef struct _GeodeMemRec +{ + struct _GeodeMemRec *next; + struct _GeodeMemRec *prev; + unsigned int offset; + int size; +} GeodeMemRec, *GeodeMemPtr; #define OUTPUT_PANEL 0x01 #define OUTPUT_CRT 0x02 @@ -238,10 +178,8 @@ VESARec; typedef struct _geodeRec { - /* Common */ - + /* Common for both GX and LX */ int Output; /* Bitmask indicating the valid output options */ - Bool HWCursor; Bool NoAccel; Bool useVGA; @@ -254,55 +192,16 @@ typedef struct _geodeRec Bool starting; Bool tryCompression; Bool tryHWCursor; - unsigned int shadowSize; - unsigned int shadowOffset; - - ExaOffscreenArea *shadowArea; - - 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 */ @@ -310,13 +209,6 @@ typedef struct _geodeRec unsigned int exaBfrOffset; unsigned int exaBfrSz; - /* XAA structures */ - unsigned char **AccelImageWriteBuffers; - int NoOfImgBuffers; - unsigned char **AccelColorExpandBuffers; - int NoOfColorExpandLines; - XAAInfoRecPtr AccelInfoRec; - /* Other structures */ EntityInfoPtr pEnt; @@ -324,25 +216,14 @@ typedef struct _geodeRec 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; @@ -350,41 +231,53 @@ typedef struct _geodeRec /* 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 */ + /* ===== LX specific items ===== */ + + /* Flags */ + Bool Scale; + + DisplayModePtr panelMode; /* The mode for the panel (if attached) */ + /* Command buffer information */ unsigned long CmdBfrOffset; unsigned long CmdBfrSize; -#ifdef HAVE_TVSUPPORT - Bool TVSupport; - int tv_encoder; - int tv_bus_fmt; - int tv_flags; - int tv_601_fmt; - int tv_601_flags; - int tv_conversion; - int tv_vsync_shift; - int tv_vsync_shift_count; - int tv_vsync_select; - int tvox, tvoy; - - TVPARAMS TvParam; - - int TVOx, TVOy, TVOw, TVOh; - Bool TV_Overscan_On; -#endif + /* Memory Management */ + GeodeMemPtr offscreenList; + unsigned int offscreenStart; + unsigned int offscreenSize; + + /* Save state */ + VG_COMPRESSION_DATA CBData; + VG_COMPRESSION_DATA FBCBData; + CIM_DISPLAYTIMING FBcimdisplaytiming; + + /* ===== GX specific items ===== */ + + /* Flags */ + Bool Panel; + + int PanelX; + int PanelY; + + int displayPitch; /* The pitch ofthe visible area */ + int displayOffset; /* The offset of the visible area */ - /* To be killed! */ + DisplayModePtr curMode; + + unsigned int shadowSize; + unsigned int shadowOffset; int FBVGAActive; + + xf86CursorInfoPtr CursorInfo; + + /* XAA structures */ + unsigned int cpySrcOffset; int cpySrcPitch, cpySrcBpp; int cpyDx, cpyDy; @@ -393,8 +286,36 @@ typedef struct _geodeRec unsigned int cmpSrcFmt, cmpDstFmt; int cmpOp; - Bool Panel; + unsigned char **AccelImageWriteBuffers; + int NoOfImgBuffers; + unsigned char **AccelColorExpandBuffers; + int NoOfColorExpandLines; + XAAInfoRecPtr AccelInfoRec; + /* Save state */ + unsigned long FBCompressionOffset; + unsigned short FBCompressionPitch; + unsigned short FBCompressionSize; + GFX_DISPLAYTIMING FBgfxdisplaytiming; + + /* 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); + + /* 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; } GeodeRec, *GeodePtr; @@ -406,16 +327,14 @@ enum LX_OPTION_HW_CURSOR, LX_OPTION_NOCOMPRESSION, LX_OPTION_NOACCEL, - LX_OPTION_ACCEL_METHOD, LX_OPTION_EXA_SCRATCH_BFRSZ, LX_OPTION_TV_SUPPORT, LX_OPTION_TV_OUTPUT, LX_OPTION_TV_OVERSCAN, LX_OPTION_ROTATE, LX_OPTION_NOPANEL, - LX_OPTION_COLOR_KEY, LX_OPTION_FBSIZE, - LX_OPTION_PANEL_GEOMETRY, + LX_OPTION_PANEL_MODE, LX_OPTION_DONT_PROGRAM } LX_GeodeOpts; @@ -435,10 +354,6 @@ enum GX_OPTION_TV_OVERSCAN, GX_OPTION_ROTATE, GX_OPTION_NOPANEL, - GX_OPTION_FLATPANEL_INFO, - GX_OPTION_FLATPANEL_IN_BIOS, - GX_OPTION_COLOR_KEY, - GX_OPTION_OSM, GX_OPTION_OSM_IMG_BUFS, GX_OPTION_OSM_CLR_BUFS, GX_OPTION_FBSIZE, @@ -448,16 +363,9 @@ enum GX_GeodeOpts; #endif -/* OLPC defines */ - -#define DCON_DEFAULT_XRES 1200 -#define DCON_DEFAULT_YRES 900 -#define DCON_DEFAULT_BPP 16 -#define DCON_DEFAULT_REFRESH 50 - /* geode_dcon.c */ extern Bool dcon_init(ScrnInfoPtr pScrni); -extern int DCONDPMSSet(ScrnInfoPtr pScrni, int mode, int flags); +extern int DCONDPMSSet(ScrnInfoPtr pScrni, int mode); /* geode_common.c */ @@ -479,6 +387,8 @@ Bool RegionsEqual(RegionPtr A, RegionPtr B); void GeodeProbeDDC(ScrnInfoPtr pScrni, int index); xf86MonPtr GeodeDoDDC(ScrnInfoPtr pScrni, int index); +Bool GeodeI2CInit(ScrnInfoPtr pScrni, I2CBusPtr * ptr, char *name); + int GeodeGetFPGeometry(const char *str, int *width, int *height); void GeodePointerMoved(int index, int x, int y); void GeodeFreeScreen(int scrnIndex, int flags); @@ -498,7 +408,8 @@ void GXShowCursor(ScrnInfoPtr pScrni); /* gx_randr.c */ Rotation GXGetRotation(ScreenPtr pScreen); Bool GXRandRInit(ScreenPtr pScreen, int rotation); -Bool GXRandRSetConfig(ScreenPtr pScreen, Rotation rotation, int rate, RRScreenSizePtr pSize); +Bool GXRandRSetConfig(ScreenPtr pScreen, Rotation rotation, int rate, + RRScreenSizePtr pSize); /* gx_rotate.c */ Bool GXRotate(ScrnInfoPtr pScrni, DisplayModePtr mode); @@ -519,20 +430,32 @@ void LXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src); void LXHideCursor(ScrnInfoPtr pScrni); void LXShowCursor(ScrnInfoPtr pScrni); -/* lx_randr.c */ -Rotation LXGetRotation(ScreenPtr pScreen); -Bool LXRandRInit(ScreenPtr pScreen, int rotation); -Bool LXRandRSetConfig(ScreenPtr pScreen, Rotation rotation, int rate, RRScreenSizePtr pSize); - -/* lx_rotate.c */ -Bool LXSetRotatePitch(ScrnInfoPtr pScrni); -Bool LXRotate(ScrnInfoPtr pScrni, DisplayModePtr mode); -Bool LXAllocShadow(ScrnInfoPtr pScrni); - /* lx_exa.c */ Bool LXExaInit(ScreenPtr pScreen); /* lx_video.c */ void LXInitVideo(ScreenPtr pScrn); +/* lx_output.c */ +void LXSetupOutput(ScrnInfoPtr); + +/* lx_panel.c */ +DisplayModePtr LXGetLegacyPanelMode(void); +DisplayModePtr LXGetManualPanelMode(char *modestr); + +void LXAdjustFrame(int scrnIndex, int x, int y, int flags); + +/* lx_display.c */ +void LXSetupCrtc(ScrnInfoPtr pScrni); + +/* lx_memory.c */ +GeodeMemPtr GeodeAllocOffscreen(GeodeRec * pGeode, int size, int align); +void GeodeFreeOffscreen(GeodeRec * pGeode, GeodeMemPtr ptr); +void LXInitOffscreen(ScrnInfoPtr pScrni); +void GeodeCloseOffscreen(ScrnInfoPtr pScrni); +unsigned int GeodeOffscreenFreeSize(GeodeRec * pGeode); + +/* lx_cursor.c */ +Bool LXCursorInit(ScreenPtr pScrn); + #endif diff --git a/src/geode_dcon.c b/src/geode_dcon.c index fc887f7..b7fba00 100644 --- a/src/geode_dcon.c +++ b/src/geode_dcon.c @@ -51,7 +51,7 @@ dcon_present(void) } int -DCONDPMSSet(ScrnInfoPtr pScrni, int mode, int flags) +DCONDPMSSet(ScrnInfoPtr pScrni, int mode) { static int failed = -1; int fd; @@ -97,14 +97,28 @@ dcon_init(ScrnInfoPtr pScrni) return FALSE; } + pGeode->panelMode = xnfcalloc(1, sizeof(DisplayModeRec)); + if (pGeode->panelMode == NULL) + return FALSE; + + /* Set up the panel mode structure automagically */ + + pGeode->panelMode->type = M_T_DRIVER; + pGeode->panelMode->Clock = 57275; + pGeode->panelMode->HDisplay = 1200; + pGeode->panelMode->HSyncStart = 1208; + pGeode->panelMode->HSyncEnd = 1216; + pGeode->panelMode->HTotal = 1240; + pGeode->panelMode->VDisplay = 900; + pGeode->panelMode->VSyncStart = 905; + pGeode->panelMode->VSyncEnd = 908; + pGeode->panelMode->VTotal = 912; + pGeode->panelMode->Flags = V_NHSYNC | V_NVSYNC; + + xf86SetModeDefaultName(pGeode->panelMode); + /* TODO: Print board revision once sysfs exports it. */ xf86DrvMsg(pScrni->scrnIndex, X_DEFAULT, "DCON detected.\n"); - /* Panel size setup */ - pGeode->PanelX = DCON_DEFAULT_XRES; - pGeode->PanelY = DCON_DEFAULT_YRES; - - /* FIXME: Mode setup should go here */ - /* FIXME: Controller setup should go here */ return TRUE; } diff --git a/src/geode_ddc.c b/src/geode_ddc.c index c167df7..2533488 100644 --- a/src/geode_ddc.c +++ b/src/geode_ddc.c @@ -65,6 +65,8 @@ geode_gpio_iobase(void) struct pci_device *pci; /* The CS5536 GPIO device is always in the same slot: 00:0f.0 */ + /* The CS5535 device should be in same slot as well */ + pci = pci_device_find_by_slot(0, 0, 0xF, 0x0); if (pci == NULL) @@ -111,19 +113,18 @@ geode_ddc_getbits(I2CBusPtr b, int *scl, int *sda) *sda = (dat & DDC_DATA_HIGH) ? 1 : 0; } -static xf86MonPtr -GeodeGetDDC(ScrnInfoPtr pScrni) +Bool +GeodeI2CInit(ScrnInfoPtr pScrni, I2CBusPtr * ptr, char *name) { - xf86MonPtr mon = NULL; I2CBusPtr bus; - unsigned long ddciobase; + unsigned int ddciobase; ddciobase = geode_gpio_iobase(); if (ddciobase == 0) { xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "Could not find the GPIO I/O base\n"); - return NULL; + return FALSE; } /* The GPIO pins for DDC are multiplexed with a @@ -135,43 +136,49 @@ GeodeGetDDC(ScrnInfoPtr pScrni) (inl(ddciobase + GPIO_OUT_AUX1) & DDC_DATA_HIGH)) { xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "GPIO pins are in serial mode. Assuming no DDC\n"); - return NULL; + return FALSE; } - /* Set up the pins */ - outl(ddciobase + GPIO_OUT_ENABLE, DDC_DATA_HIGH | DDC_CLK_HIGH); outl(ddciobase + GPIO_IN_ENABLE, DDC_DATA_HIGH | DDC_CLK_HIGH); bus = xf86CreateI2CBusRec(); - if (bus == NULL) { - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, - "Could not create the I2C structre\n"); - goto err; - } + if (!bus) + return FALSE; - bus->BusName = "CS5536 DDC BUS"; + bus->BusName = name; bus->scrnIndex = pScrni->scrnIndex; + bus->I2CGetBits = geode_ddc_getbits; bus->I2CPutBits = geode_ddc_putbits; bus->DriverPrivate.ptr = (void *)(ddciobase); - if (xf86I2CBusInit(bus)) { - mon = xf86DoEDID_DDC2(pScrni->scrnIndex, bus); + if (!xf86I2CBusInit(bus)) + return FALSE; + + *ptr = bus; + return TRUE; +} + +static xf86MonPtr +GeodeGetDDC(ScrnInfoPtr pScrni) +{ + xf86MonPtr mon = NULL; + I2CBusPtr bus; + + if (!GeodeI2CInit(pScrni, &bus, "CS5536 DDC BUS")) + return NULL; + + mon = xf86DoEDID_DDC2(pScrni->scrnIndex, bus); #if (XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,4,99,0,0)) - if (mon) - xf86DDCApplyQuirks(pScrni->scrnIndex, mon); + if (mon) + xf86DDCApplyQuirks(pScrni->scrnIndex, mon); #endif - } xf86DestroyI2CBusRec(bus, FALSE, FALSE); - err: - outl(ddciobase + GPIO_OUT_ENABLE, DDC_DATA_LOW | DDC_CLK_LOW); - outl(ddciobase + GPIO_IN_ENABLE, DDC_DATA_LOW | DDC_CLK_LOW); - return mon; } diff --git a/src/geode_driver.c b/src/geode_driver.c index 8e467ec..e374a40 100644 --- a/src/geode_driver.c +++ b/src/geode_driver.c @@ -191,16 +191,14 @@ 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_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_NOPANEL, "NoPanel", OPTV_BOOLEAN, {0}, FALSE}, - {LX_OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {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}, + {LX_OPTION_PANEL_MODE, "PanelMode", OPTV_STRING, {0}, FALSE}, {-1, NULL, OPTV_NONE, {0}, FALSE} }; @@ -219,7 +217,6 @@ OptionInfoRec GX_GeodeOptions[] = { {GX_OPTION_TV_OVERSCAN, "TVOverscan", OPTV_ANYSTR, {0}, FALSE}, {GX_OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE}, {GX_OPTION_NOPANEL, "NoPanel", OPTV_BOOLEAN, {0}, FALSE}, - {GX_OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE}, {GX_OPTION_OSM_IMG_BUFS, "OSMImageBuffers", OPTV_INTEGER, {0}, FALSE}, {GX_OPTION_OSM_CLR_BUFS, "OSMColorExpBuffers", OPTV_INTEGER, {0}, FALSE}, {GX_OPTION_FBSIZE, "FBSize", OPTV_INTEGER, {0}, FALSE}, diff --git a/src/gx_accel.c b/src/gx_accel.c index 025b06a..34df4df 100644 --- a/src/gx_accel.c +++ b/src/gx_accel.c @@ -1757,8 +1757,8 @@ amd_gx_exa_Composite(PixmapPtr pxDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int width, int height) { int op, current_line, max_lines, lines, pass, scratchPitch; - unsigned int srcOffset, srcOfs=0, srcPitch, srcPch=0, srcBpp; - unsigned int dstOffset, dstOfs=0, dstPitch, dstPch=0, dstBpp; + unsigned int srcOffset, srcOfs = 0, srcPitch, srcPch = 0, srcBpp; + unsigned int dstOffset, dstOfs = 0, dstPitch, dstPch = 0, dstBpp; unsigned int sizes, strides, blt_mode = 0, rop = 0; GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst); diff --git a/src/gx_driver.c b/src/gx_driver.c index 928a59a..46b04f5 100644 --- a/src/gx_driver.c +++ b/src/gx_driver.c @@ -68,6 +68,9 @@ #define GX_GP_REG_SIZE 0x4000 #define GX_VID_REG_SIZE 0x4000 +#define DEFAULT_IMG_LINE_BUFS 20 +#define DEFAULT_CLR_LINE_BUFS 20 + extern OptionInfoRec GX_GeodeOptions[]; extern const char *amdVgahwSymbols[]; @@ -200,12 +203,11 @@ GXAllocateMemory(ScreenPtr pScrn, ScrnInfoPtr pScrni, int rotate) } if (pGeode->tryHWCursor) { - pGeode->CursorSize = 1024; - if (pGeode->CursorSize <= fbavail) { + if (fbavail >= 1024) { pGeode->CursorStartOffset = fboffset; - fboffset += pGeode->CursorSize; - fbavail -= pGeode->CursorSize; + fboffset += 1024; + fbavail -= 1024; pGeode->HWCursor = TRUE; } else { xf86DrvMsg(pScrni->scrnIndex, X_ERROR, @@ -652,9 +654,6 @@ GXPreInit(ScrnInfoPtr pScrni, int flags) else pScrni->videoRam = pGeode->pEnt->device->videoRam; - pGeode->maxWidth = GX_MAX_WIDTH; - pGeode->maxHeight = GX_MAX_HEIGHT; - GeodeClockRange = (ClockRangePtr) xnfcalloc(sizeof(ClockRange), 1); GeodeClockRange->next = NULL; GeodeClockRange->minClock = 25175; @@ -789,9 +788,7 @@ GXAdjustFrame(int scrnIndex, int x, int y, int flags) GeodeRec *pGeode = GEODEPTR(pScrni); unsigned long offset; - offset = - pGeode->FBOffset + y * pGeode->Pitch + - x * (pScrni->bitsPerPixel >> 3); + offset = y * pGeode->Pitch + x * (pScrni->bitsPerPixel >> 3); gfx_set_display_offset(offset); } @@ -1269,8 +1266,8 @@ GXScreenInit(int scrnIndex, ScreenPtr pScrn, int argc, char **argv) pExa->pixmapOffsetAlign = 32; pExa->pixmapPitchAlign = 32; pExa->flags = EXA_OFFSCREEN_PIXMAPS; - pExa->maxX = pGeode->maxWidth - 1; - pExa->maxY = pGeode->maxHeight - 1; + pExa->maxX = GX_MAX_WIDTH - 1; + pExa->maxY = GX_MAX_HEIGHT - 1; } } else { pGeode->AccelImageWriteBuffers = diff --git a/src/gx_randr.c b/src/gx_randr.c index 2b5a97c..6cdd244 100644 --- a/src/gx_randr.c +++ b/src/gx_randr.c @@ -209,7 +209,7 @@ GXRandRSetMode(ScreenPtr pScreen, * Get the new Screen pixmap ptr as SwitchMode might have called * ModifyPixmapHeader and xf86EnableDisableFBAccess will put it back... * Unfortunately. - + */ pspix = (*pScreen->GetScreenPixmap) (pScreen); @@ -308,9 +308,7 @@ GXRandRSetConfig(ScreenPtr pScreen, Rotation rotation, #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3 inputInfo.pointer, #endif - pScreen, - px, py, - FALSE); + pScreen, px, py, FALSE); } return TRUE; diff --git a/src/gx_video.c b/src/gx_video.c index aecb0ff..354e179 100644 --- a/src/gx_video.c +++ b/src/gx_video.c @@ -406,7 +406,7 @@ GXSetupImageVideo(ScreenPtr pScrn) adapt->QueryImageAttributes = GeodeQueryImageAttributes; pPriv->filter = 0; - pPriv->colorKey = pGeode->videoKey; + pPriv->colorKey = 0; pPriv->colorKeyMode = 0; pPriv->videoStatus = 0; #if DBUF @@ -809,7 +809,7 @@ GXSetVideoPosition(int x, int y, int width, int height, /* Take care of panning when panel is present */ - startAddress = gfx_get_display_offset() - pGeode->FBOffset; + startAddress = gfx_get_display_offset(); DeltaY = startAddress / pGeode->Pitch; DeltaX = startAddress & (pGeode->Pitch - 1); DeltaX /= (pScrni->bitsPerPixel >> 3); diff --git a/src/lx_cursor.c b/src/lx_cursor.c index f97c271..64ea9c9 100644 --- a/src/lx_cursor.c +++ b/src/lx_cursor.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2003-2007 Advanced Micro Devices, Inc. +/* Copyright (c) 2003-2008 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 @@ -28,193 +28,57 @@ #endif #include "xf86.h" -#include "xf86_OSproc.h" -#include "xf86Pci.h" -#include "xf86PciInfo.h" +#include "xf86i2c.h" +#include "xf86Crtc.h" #include "geode.h" -/* Forward declarations of the functions */ -static void LXSetCursorColors(ScrnInfoPtr pScrni, int bg, int fg); -static void LXSetCursorPosition(ScrnInfoPtr pScrni, int x, int y); -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 pScrn); - Bool -LXHWCursorInit(ScreenPtr pScrn) +LXCursorInit(ScreenPtr pScrn) { - ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; - GeodeRec *pGeode = GEODEPTR(pScrni); - xf86CursorInfoPtr infoPtr; - - infoPtr = xf86CreateCursorInfoRec(); - if (!infoPtr) - return FALSE; - /* the geode structure is intiallized with the cursor infoRec */ - pGeode->CursorInfo = infoPtr; - infoPtr->MaxWidth = 32; - infoPtr->MaxHeight = 32; - /* seeting up the cursor flags */ - infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | + return xf86_cursors_init(pScrn, 32, 32, HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | - HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED; - - infoPtr->SetCursorColors = LXSetCursorColors; - infoPtr->SetCursorPosition = LXSetCursorPosition; - infoPtr->LoadCursorImage = LXLoadCursorImage; - infoPtr->HideCursor = LXHideCursor; - infoPtr->ShowCursor = LXShowCursor; - infoPtr->UseHWCursor = LXUseHWCursor; - - return (xf86InitCursor(pScrn, infoPtr)); + HARDWARE_CURSOR_INVERT_MASK | + HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32); } -static void -LXSetCursorColors(ScrnInfoPtr pScrni, int bg, int fg) +static int +_getrow(unsigned char *src, int stride, int x, int y) { - vg_set_mono_cursor_colors(bg, fg); + x = ((x & ~31) << 1) | (x & 31); + src += y * stride; + return (src[x >> 3] >> (x & 7)) & 1; } -static void -LXSetCursorPosition(ScrnInfoPtr pScrni, int x, int y) +static int +_getmask(unsigned char *src, int stride, int x, int y) { - GeodeRec *pGeode = GEODEPTR(pScrni); - int savex, savey; - int newX, newY; - int hsx, hsy; - - /* Adjust xf86HWCursor messing about */ - - savex = x + pScrni->frameX0; - savey = y + pScrni->frameY0; - - switch (pGeode->rotation) { - default: - ErrorF("%s:%d invalid rotation %d\n", __func__, __LINE__, - pGeode->rotation); - case RR_Rotate_0: - newX = savex; - newY = savey; - hsx = 31; - hsy = 31; - break; - - case RR_Rotate_270: - 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_90: - newX = pScrni->pScreen->height - savey; - newY = savex; - hsx = 0; - hsy = 31; - break; - } - - newX -= pScrni->frameX0; - newY -= pScrni->frameY0; - - { - VG_PANNING_COORDINATES panning; - - vg_set_cursor_position(newX + hsx, newY + hsy, &panning); - } - - vg_set_cursor_enable(1); - - /* FIXME: Adjust for video panning? */ + x = ((x & ~31) << 1) | (1 << 5) | (x & 31); + src += y * stride; + return (src[x >> 3] >> (x & 7)) & 1; } void LXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src) { - int i, n, x, y, newX, newY; - unsigned long andMask[32], xorMask[32]; GeodeRec *pGeode = GEODEPTR(pScrni); - unsigned long mskb, rowb; - unsigned char *rowp = &src[0]; - unsigned char *mskp = &src[128]; - - if (src != NULL) { - mskb = rowb = 0; - for (y = 32; --y >= 0;) - andMask[y] = xorMask[y] = 0; - for (y = 0; y < 32; ++y) { - for (x = 0; x < 32; ++x) { - if ((i = x & 7) == 0) { - rowb = (*rowp & *mskp); - mskb = ~(*mskp); - ++rowp; - ++mskp; - } + unsigned long andMask[32], xorMask[32]; + int y, x; - switch (pGeode->rotation) { - default: - ErrorF("%s:%d invalid rotation %d\n", __func__, __LINE__, - pGeode->rotation); - case RR_Rotate_0: - newX = x; - newY = y; - break; - case RR_Rotate_270: - newX = y; - newY = 31 - x; - break; - case RR_Rotate_180: - newX = 31 - x; - newY = 31 - y; - break; - case RR_Rotate_90: - newX = 31 - y; - newY = x; - break; - } + for (y = 0; y < 32; y++) { + andMask[y] = (src) ? 0 : ~0; + xorMask[y] = 0; + } - i = 7 - i; - n = 31 - newX; - andMask[newY] |= (((mskb >> i) & 1) << n); - xorMask[newY] |= (((rowb >> i) & 1) << n); + if (src != NULL) { + for (y = 0; y < 32; y++) { + for (x = 0; x < 32; x++) { + xorMask[y] |= _getrow(src, 8, x, y) << (31 - x); + andMask[y] |= _getmask(src, 8, x, y) << (31 - x); } } - } else { - for (y = 32; --y >= 0;) { - andMask[y] = ~0; - xorMask[y] = 0; - } } vg_set_mono_cursor_shape32(pGeode->CursorStartOffset, &andMask[0], - &xorMask[0], 31, 31); -} - -void -LXHideCursor(ScrnInfoPtr pScrni) -{ - vg_set_cursor_enable(0); -} - -void -LXShowCursor(ScrnInfoPtr pScrni) -{ - vg_set_cursor_enable(1); -} - -static Bool -LXUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs) -{ - ScrnInfoPtr pScrni = XF86SCRNINFO(pScrn); - GeodeRec *pGeode = GEODEPTR(pScrni); - - return pGeode->HWCursor; + &xorMask[0], 32, 32); } diff --git a/src/lx_display.c b/src/lx_display.c new file mode 100644 index 0000000..38932a6 --- /dev/null +++ b/src/lx_display.c @@ -0,0 +1,499 @@ +/* Copyright (c) 2008 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 "geode.h" +#include "xf86Crtc.h" +#include "cim/cim_defs.h" +#include "cim/cim_regs.h" + +typedef struct _LXOutputPrivateRec +{ + int video_enable; + unsigned long video_flags; + GeodeMemPtr rotate_mem; +} LXCrtcPrivateRec, *LXCrtcPrivatePtr; + +static void +lx_enable_dac_power(ScrnInfoPtr pScrni, int option) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + + 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 void +lx_disable_dac_power(ScrnInfoPtr pScrni, int option) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + + if (pGeode->Output & OUTPUT_PANEL) + df_set_panel_enable(0); + + if (pGeode->Output & OUTPUT_CRT) { + + /* 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 void +lx_set_panel_mode(VG_DISPLAY_MODE * mode, DisplayModePtr pMode) +{ + int hsync, vsync; + + mode->mode_width = mode->panel_width = pMode->HDisplay; + mode->mode_height = mode->panel_height = pMode->VDisplay; + + mode->hactive = pMode->HDisplay; + mode->hblankstart = pMode->HDisplay; + mode->hsyncstart = pMode->HSyncStart; + mode->hsyncend = pMode->HSyncEnd; + mode->hblankend = pMode->HTotal; + mode->htotal = pMode->HTotal; + + mode->vactive = pMode->VDisplay; + mode->vblankstart = pMode->VDisplay; + mode->vsyncstart = pMode->VSyncStart; + mode->vsyncend = pMode->VSyncEnd; + mode->vblankend = pMode->VTotal; + mode->vtotal = pMode->VTotal; + + mode->vactive_even = pMode->VDisplay; + mode->vblankstart_even = pMode->VDisplay; + mode->vsyncstart_even = pMode->VSyncStart; + mode->vsyncend_even = pMode->VSyncEnd; + mode->vblankend_even = pMode->VTotal; + mode->vtotal_even = pMode->VTotal; + + mode->frequency = (int)((pMode->Clock / 1000.0) * 0x10000); + + /* In panel mode, Cimarron purposely swizzles these, + * so we swizzle them first */ + + hsync = (pMode->Flags & V_NHSYNC) ? 0 : 1; + vsync = (pMode->Flags & V_NVSYNC) ? 0 : 1; + + mode->flags |= (hsync) ? VG_MODEFLAG_NEG_HSYNC : 0; + mode->flags |= (vsync) ? VG_MODEFLAG_NEG_VSYNC : 0; +} + +static void +lx_set_crt_mode(VG_DISPLAY_MODE * mode, DisplayModePtr pMode) +{ + int hsync, vsync; + + mode->mode_width = mode->panel_width = pMode->HDisplay; + mode->mode_height = mode->panel_height = pMode->VDisplay; + + 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->Clock / 1000.0) * 0x10000); + + hsync = (pMode->Flags & V_NHSYNC) ? 1 : 0; + vsync = (pMode->Flags & V_NVSYNC) ? 1 : 0; + + mode->flags |= (hsync) ? VG_MODEFLAG_NEG_HSYNC : 0; + mode->flags |= (vsync) ? VG_MODEFLAG_NEG_VSYNC : 0; +} + +static int +lx_set_mode(ScrnInfoPtr pScrni, DisplayModePtr pMode, int bpp) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + VG_DISPLAY_MODE mode; + int ret; + + memset(&mode, 0, sizeof(mode)); + + mode.flags |= pGeode->Output & OUTPUT_CRT ? VG_MODEFLAG_CRT_AND_FP : 0; + + if (pGeode->Output & OUTPUT_PANEL) { + mode.flags |= VG_MODEFLAG_PANELOUT; + if (pGeode->Output & OUTPUT_CRT) + mode.flags |= VG_MODEFLAG_CRT_AND_FP; + } + + if (pGeode->Output & OUTPUT_PANEL && pGeode->Scale) + lx_set_panel_mode(&mode, pGeode->panelMode); + else + lx_set_crt_mode(&mode, pMode); + + mode.src_width = pMode->HDisplay; + mode.src_height = pMode->VDisplay; + + ret = vg_set_custom_mode(&mode, bpp); + return (ret == CIM_STATUS_OK) ? 0 : -1; +} + +static void +lx_crtc_dpms(xf86CrtcPtr crtc, int mode) +{ + ScrnInfoPtr pScrni = crtc->scrn; + GeodeRec *pGeode = GEODEPTR(pScrni); + + if (pGeode->Output & OUTPUT_DCON) + DCONDPMSSet(pScrni, mode); + + switch (mode) { + case DPMSModeOn: + lx_enable_dac_power(pScrni, 1); + break; + + case DPMSModeStandby: + lx_disable_dac_power(pScrni, DF_CRT_STANDBY); + break; + + case DPMSModeSuspend: + lx_disable_dac_power(pScrni, DF_CRT_SUSPEND); + break; + + case DPMSModeOff: + lx_disable_dac_power(pScrni, DF_CRT_DISABLE); + break; + } +} + +static Bool +lx_crtc_lock(xf86CrtcPtr crtc) +{ + /* Wait until the GPU is idle */ + gp_wait_until_idle(); + return TRUE; +} + +static void +lx_crtc_unlock(xf86CrtcPtr crtc) +{ + /* Nothing to do here */ +} + +static void +lx_crtc_prepare(xf86CrtcPtr crtc) +{ + LXCrtcPrivatePtr lx_crtc = crtc->driver_private; + + /* Disable the video */ + df_get_video_enable(&lx_crtc->video_enable, &lx_crtc->video_flags); + + if (lx_crtc->video_enable) + df_set_video_enable(0, 0); + + /* Turn off compression */ + vg_set_compression_enable(0); + + /* Hide the cursor */ + crtc->funcs->hide_cursor(crtc); + + /* Turn off the display */ + crtc->funcs->dpms(crtc, DPMSModeOff); +} + +static Bool +lx_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + return TRUE; +} + +static void +lx_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjusted_mode, int x, int y) +{ + ScrnInfoPtr pScrni = crtc->scrn; + GeodeRec *pGeode = GEODEPTR(pScrni); + DF_VIDEO_SOURCE_PARAMS vs_odd, vs_even; + + df_get_video_source_configuration(&vs_odd, &vs_even); + + /* Note - the memory gets adjusted when virtualX/virtualY + * gets changed - so we don't need to worry about it here + */ + + if (lx_set_mode(pScrni, adjusted_mode, pScrni->bitsPerPixel)) + ErrorF("ERROR! Unable to set the mode!\n"); + + /* The output gets turned in in the output code as + * per convention */ + + vg_set_display_pitch(pGeode->Pitch); + gp_set_bpp(pScrni->bitsPerPixel); + + /* Set the acceleration offset if we are drawing to a shadow */ + if (crtc->rotatedData != NULL) + vg_set_display_offset((unsigned int)((char *)crtc->rotatedData - + (char *)pGeode->FBBase)); + else + vg_set_display_offset(0); + + /* FIXME: Whats up with X and Y? Does that come into play + * here? */ + + df_configure_video_source(&vs_odd, &vs_even); + + vg_wait_vertical_blank(); +} + +static void +lx_crtc_commit(xf86CrtcPtr crtc) +{ + LXCrtcPrivatePtr lx_crtc = crtc->driver_private; + ScrnInfoPtr pScrni = crtc->scrn; + GeodeRec *pGeode = GEODEPTR(pScrni); + + /* Turn back on the sreen */ + crtc->funcs->dpms(crtc, DPMSModeOn); + + /* Turn on compression */ + + if (pGeode->Compression) { + vg_configure_compression(&(pGeode->CBData)); + vg_set_compression_enable(1); + } + + /* Load the cursor */ + if (crtc->scrn->pScreen != NULL) + xf86_reload_cursors(crtc->scrn->pScreen); + + /* Renable the video */ + + if (lx_crtc->video_enable) + df_set_video_enable(lx_crtc->video_enable, lx_crtc->video_flags); + + lx_crtc->video_enable = 0; + lx_crtc->video_flags = 0; +} + +static void +lx_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, + CARD16 * blue, int size) +{ + unsigned int dcfg; + int i; + + assert(size == 256); + + for (i = 0; i < 256; i++) { + unsigned int val = (*red << 8) | *green | (*blue >> 8); + + df_set_video_palette_entry(i, val); + } + + /* df_set_video_palette_entry automatically turns on + * gamma for video - if this gets called, we assume that + * RandR wants it set for graphics, so reverse cimarron + */ + + dcfg = READ_VID32(DF_DISPLAY_CONFIG); + dcfg &= ~DF_DCFG_GV_PAL_BYP; + WRITE_VID32(DF_DISPLAY_CONFIG, dcfg); +} + +static void * +lx_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) +{ + ScrnInfoPtr pScrni = crtc->scrn; + GeodePtr pGeode = GEODEPTR(pScrni); + LXCrtcPrivatePtr lx_crtc = crtc->driver_private; + unsigned int rpitch, size; + + rpitch = pScrni->displayWidth * (pScrni->bitsPerPixel / 8); + size = rpitch * height; + + lx_crtc->rotate_mem = GeodeAllocOffscreen(pGeode, size, 4); + + if (lx_crtc->rotate_mem == NULL) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Couldn't allocate the shadow memory for rotation\n"); + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + " You need 0x%x bytes, but only 0x%x bytes are available\n", + size, GeodeOffscreenFreeSize(pGeode)); + + return NULL; + } + + memset(pGeode->FBBase + lx_crtc->rotate_mem->offset, 0, size); + return pGeode->FBBase + lx_crtc->rotate_mem->offset; +} + +static PixmapPtr +lx_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) +{ + ScrnInfoPtr pScrni = crtc->scrn; + GeodeRec *pGeode = GEODEPTR(pScrni); + PixmapPtr rpixmap; + + if (!data) + data = lx_crtc_shadow_allocate(crtc, width, height); + + rpixmap = GetScratchPixmapHeader(pScrni->pScreen, + width, height, pScrni->depth, pScrni->bitsPerPixel, pGeode->Pitch, + data); + + if (rpixmap == NULL) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Couldn't allocate shadow pixmap for rotated CRTC\n"); + } + + return rpixmap; +} + +static void +lx_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rpixmap, void *data) +{ + ScrnInfoPtr pScrni = crtc->scrn; + GeodeRec *pGeode = GEODEPTR(pScrni); + LXCrtcPrivatePtr lx_crtc = crtc->driver_private; + + if (rpixmap) + FreeScratchPixmapHeader(rpixmap); + + if (data) { + gp_wait_until_idle(); + GeodeFreeOffscreen(pGeode, lx_crtc->rotate_mem); + lx_crtc->rotate_mem = NULL; + } +} + +static void +lx_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg) +{ + vg_set_mono_cursor_colors(bg, fg); +} + +static void +lx_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y) +{ + VG_PANNING_COORDINATES panning; + + /* FIXME: Do I need to worry about rotation adjustment here? */ + + switch (crtc->rotation) { + case RR_Rotate_0: + x += 31; + y += 31; + } + + vg_set_cursor_position(x, y, &panning); +} + +static void +lx_crtc_show_cursor(xf86CrtcPtr crtc) +{ + vg_set_cursor_enable(1); +} + +static void +lx_crtc_hide_cursor(xf86CrtcPtr crtc) +{ + vg_set_cursor_enable(0); +} + +static void +lx_crtc_load_cursor_image(xf86CrtcPtr crtc, unsigned char *src) +{ + LXLoadCursorImage(crtc->scrn, src); +} + +static const xf86CrtcFuncsRec lx_crtc_funcs = { + .dpms = lx_crtc_dpms, + .lock = lx_crtc_lock, + .unlock = lx_crtc_unlock, + .mode_fixup = lx_crtc_mode_fixup, + .prepare = lx_crtc_prepare, + .mode_set = lx_crtc_mode_set, + .commit = lx_crtc_commit, + .gamma_set = lx_crtc_gamma_set, + .shadow_create = lx_crtc_shadow_create, + .shadow_allocate = lx_crtc_shadow_allocate, + .shadow_destroy = lx_crtc_shadow_destroy, + .set_cursor_colors = lx_crtc_set_cursor_colors, + .set_cursor_position = lx_crtc_set_cursor_position, + .show_cursor = lx_crtc_show_cursor, + .hide_cursor = lx_crtc_hide_cursor, + .load_cursor_image = lx_crtc_load_cursor_image, +}; + +void +LXSetupCrtc(ScrnInfoPtr pScrni) +{ + xf86CrtcPtr crtc; + LXCrtcPrivatePtr lxpriv; + + crtc = xf86CrtcCreate(pScrni, &lx_crtc_funcs); + + if (crtc == NULL) { + ErrorF("ERROR - failed to create a CRTC\n"); + return; + } + + lxpriv = xnfcalloc(sizeof(LXCrtcPrivateRec), 1); + + if (!lxpriv) { + xf86CrtcDestroy(crtc); + ErrorF("unable to allocate memory for lxpriv\n"); + return; + } + + crtc->driver_private = lxpriv; +} diff --git a/src/lx_driver.c b/src/lx_driver.c index e8477db..2ee6a1a 100644 --- a/src/lx_driver.c +++ b/src/lx_driver.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2003-2007 Advanced Micro Devices, Inc. +/* Copyright (c) 2003-2008 Advanced Micro Devices, Inc. * * Portioned modeled from xf86-video-intel/src/i830_driver.c * Copyright 2001 VA Linux Systems Inc., Fremont, California. @@ -27,21 +27,6 @@ * software without specific prior written permission. */ -/* 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 @@ -52,17 +37,16 @@ #include "xf86.h" #include "xf86_OSproc.h" #include "xf86Resources.h" +#include "xf86i2c.h" +#include "xf86Crtc.h" #include "xf86cmap.h" #include "compiler.h" #include "mipointer.h" -#include <shadow.h> /* setupShadow() */ -#include <X11/extensions/randr.h> #include "fb.h" #include "miscstruct.h" #include "micmap.h" #include "vbe.h" #include "fb.h" -#include "randrstr.h" #include "cim_defs.h" #include "cim_regs.h" #include "geode.h" @@ -70,269 +54,28 @@ /* Bring in VGA functions */ #include "lx_vga.c" -/* Chipset types */ - -#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 + +/* Size of the register blocks */ #define LX_GP_REG_SIZE 0x4000 #define LX_VG_REG_SIZE 0x4000 #define LX_VID_REG_SIZE 0x4000 #define LX_VIP_REG_SIZE 0x4000 +/* Size of the Cimarron command buffer */ +#define CIM_CMD_BFR_SZ 0x200000 + extern OptionInfoRec LX_GeodeOptions[]; extern const char *amdVgahwSymbols[]; -extern const char *amdVbeSymbols[]; extern const char *amdInt10Symbols[]; extern const char *amdFbSymbols[]; extern const char *amdExaSymbols[]; -extern const char *amdRamdacSymbols[]; 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)) - -static inline void -lx_enable_dac_power(ScrnInfoPtr pScrni, int option) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - 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) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - if (pGeode->Output & OUTPUT_PANEL) - df_set_panel_enable(0); - - if (pGeode->Output & OUTPUT_CRT) { - - /* 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_get_panel(int *xres, int *yres) -{ - 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; -} - -static int -lx_set_custom_mode(GeodeRec * pGeode, DisplayModePtr pMode, int bpp) -{ - VG_DISPLAY_MODE mode; - int hsync, vsync; - - memset(&mode, 0, sizeof(mode)); - - /* Cimarron purposely swaps the sync when panels are enabled -this is - * presumably to allow for "default" panels which are normally active - * low, so we need to swizzle the flags - */ - - hsync = (pMode->Flags & V_NHSYNC) ? 1 : 0; - vsync = (pMode->Flags & V_NVSYNC) ? 1 : 0; - - if (pGeode->Output & OUTPUT_PANEL) { - hsync = !vsync; - vsync = !vsync; - } - - mode.flags |= (hsync) ? VG_MODEFLAG_NEG_HSYNC : 0; - mode.flags |= (vsync) ? VG_MODEFLAG_NEG_VSYNC : 0; - - 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); -} - -static Bool -LXAllocateMemory(ScreenPtr pScrn, ScrnInfoPtr pScrni, int rotate) -{ - 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->displayWidth = pGeode->displayPitch / bytpp; - - /* Sets pGeode->Pitch and pScrni->displayWidth based on the rotate settings */ - LXSetRotatePitch(pScrni); - - 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; - pGeode->CBData.size = LX_CB_PITCH; - pGeode->CBData.pitch = LX_CB_PITCH; - 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->exaBfrOffset = 0; - - if (!pGeode->NoAccel) { - if (pGeode->exaBfrSz > 0 && pGeode->exaBfrSz <= fbavail) { - pGeode->exaBfrOffset = fboffset; - fboffset += pGeode->exaBfrSz; - fbavail -= pGeode->exaBfrSz; - } - } - - /* Adjust the available EXA offscreen space to account for the buffer */ - - if (!pGeode->NoAccel && pGeode->pExa) { - pGeode->pExa->offScreenBase = fboffset; - pGeode->pExa->memorySize = fboffset + fbavail; - } - - return ret; -} - static Bool LXSaveScreen(ScreenPtr pScrn, int mode) { @@ -398,6 +141,18 @@ LXWriteMSR(unsigned long addr, unsigned long lo, unsigned long hi) LX_MSR_WRITE(addr, lo, hi); } +static unsigned int +LXCalcPitch(ScrnInfoPtr pScrni) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + + if (pGeode->tryCompression) + return + GeodeCalculatePitchBytes(pScrni->virtualX, pScrni->bitsPerPixel); + else + return ((pScrni->virtualX + 3) & ~3) * (pScrni->bitsPerPixel >> 3); +} + #ifdef XSERVER_LIBPCIACCESS static inline void * map_pci_mem(ScrnInfoPtr pScrni, int vram, @@ -422,7 +177,7 @@ map_pci_mem(ScrnInfoPtr pScrni, int vram, static inline int unmap_pci_mem(ScrnInfoPtr pScrni, struct pci_device *dev, void *ptr, int size) { - return pci_device_unmap_range(dev, ptr, size); + return pci_device_unmap_range(dev, ptr, size); } #endif @@ -517,14 +272,22 @@ LXCheckVGA(ScrnInfoPtr pScrni) } static Bool +LXCrtcResize(ScrnInfoPtr pScrni, int width, int height) +{ + return TRUE; +} + +static const xf86CrtcConfigFuncsRec lx_xf86crtc_config_funcs = { + LXCrtcResize, +}; + +static Bool LXPreInit(ScrnInfoPtr pScrni, int flags) { GeodePtr pGeode; - ClockRangePtr GeodeClockRange; EntityInfoPtr pEnt; OptionInfoRec *GeodeOptions = &LX_GeodeOptions[0]; rgb defaultWeight = { 0, 0, 0 }; - int modecnt; char *s; if (pScrni->numEntities != 1) @@ -679,24 +442,30 @@ LXPreInit(ScrnInfoPtr pScrni, int flags) /* Panel detection code - * 1. See if an OLPC DCON is attached - we can make some assumptions * about the panel if so. - * 2. Use override options specified in the config + * 2. Use panel mode specified in the config * 3. "Autodetect" the panel through VSA */ if (dcon_init(pScrni)) { pGeode->Output = OUTPUT_PANEL | OUTPUT_DCON; } else if (pGeode->Output & OUTPUT_PANEL) { - char *panelgeo = - xf86GetOptValString(GeodeOptions, LX_OPTION_PANEL_GEOMETRY); - - if (panelgeo != NULL) - GeodeGetFPGeometry(panelgeo, &pGeode->PanelX, &pGeode->PanelY); - else { - if (!lx_get_panel(&pGeode->PanelX, &pGeode->PanelY)) - pGeode->Output &= ~OUTPUT_PANEL; - } + char *pmode = xf86GetOptValString(GeodeOptions, LX_OPTION_PANEL_MODE); + + if (pmode != NULL) + pGeode->panelMode = LXGetManualPanelMode(pmode); + + if (pGeode->panelMode == NULL) + pGeode->panelMode = LXGetLegacyPanelMode(); + + if (pGeode->panelMode == NULL) + pGeode->Output &= ~OUTPUT_PANEL; } + /* Default to turn scaling on for panels */ + + if (pGeode->Output & OUTPUT_PANEL) + pGeode->Scale = TRUE; + xf86DrvMsg(pScrni->scrnIndex, X_INFO, "LX output options:\n"); xf86DrvMsg(pScrni->scrnIndex, X_INFO, " CRT: %s\n", pGeode->Output & OUTPUT_CRT ? "YES" : "NO"); @@ -711,6 +480,7 @@ LXPreInit(ScrnInfoPtr pScrni, int flags) pGeode->useVGA ? "YES" : "NO"); /* Set up VGA */ + if (pGeode->useVGA) { xf86LoaderReqSymLists(amdVgahwSymbols, NULL); @@ -763,49 +533,28 @@ LXPreInit(ScrnInfoPtr pScrni, int flags) pGeode->CmdBfrOffset = pGeode->FBAvail; - pGeode->maxWidth = LX_MAX_WIDTH; - pGeode->maxHeight = LX_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; + /* Allocate a a CRTC config structure */ + xf86CrtcConfigInit(pScrni, &lx_xf86crtc_config_funcs); - if (pGeode->Output & OUTPUT_CRT) - pScrni->monitor->DDC = GeodeDoDDC(pScrni, pGeode->pEnt->index); - else - pScrni->monitor->DDC = NULL; + /* Set up the GPU CRTC */ + LXSetupCrtc(pScrni); - /* I'm still not 100% sure this uses the right values */ + xf86CrtcSetSizeRange(pScrni, 320, 200, LX_MAX_WIDTH, LX_MAX_HEIGHT); - 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); + /* Setup the output */ + LXSetupOutput(pScrni); - if (modecnt <= 0) { - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes were found\n"); + if (!xf86InitialConfiguration(pScrni, FALSE)) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes.\n"); return FALSE; } - xf86PruneDriverModes(pScrni); - - if (pScrni->modes == NULL) { - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes were found\n"); - return FALSE; - } + xf86PrintModes(pScrni); - xf86SetCrtcForModes(pScrni, 0); pScrni->currentMode = pScrni->modes; - xf86PrintModes(pScrni); + pGeode->Pitch = LXCalcPitch(pScrni); + xf86SetDpi(pScrni, 0, 0); /* Load the modules we'll need */ @@ -823,14 +572,6 @@ LXPreInit(ScrnInfoPtr pScrni, int flags) xf86LoaderReqSymLists(&amdExaSymbols[0], NULL); } - if (pGeode->tryHWCursor == TRUE) { - if (!xf86LoadSubModule(pScrni, "ramdac")) { - return FALSE; - } - - xf86LoaderReqSymLists(amdRamdacSymbols, NULL); - } - if (xf86RegisterResources(pGeode->pEnt->index, NULL, ResExclusive)) { xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "Couldn't register the resources.\n"); @@ -858,7 +599,6 @@ static Bool LXUnmapMem(ScrnInfoPtr pScrni) { GeodeRec *pGeode = GEODEPTR(pScrni); - pciVideoPtr pci = xf86GetPciInfoForEntity(pGeode->pEnt->index); #ifndef XSERVER_LIBPCIACCESS xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_gp_ptr, LX_GP_REG_SIZE); @@ -868,6 +608,8 @@ LXUnmapMem(ScrnInfoPtr pScrni) xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_vip_ptr, LX_VIP_REG_SIZE); #else + pciVideoPtr pci = xf86GetPciInfoForEntity(pGeode->pEnt->index); + unmap_pci_mem(pScrni, pci, cim_gp_ptr, LX_GP_REG_SIZE); unmap_pci_mem(pScrni, pci, cim_vg_ptr, LX_VG_REG_SIZE); unmap_pci_mem(pScrni, pci, cim_vid_ptr, LX_VID_REG_SIZE); @@ -882,7 +624,7 @@ LXUnmapMem(ScrnInfoPtr pScrni) /* These should be correctly accounted for rotation */ -static void +void LXAdjustFrame(int scrnIndex, int x, int y, int flags) { ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; @@ -890,145 +632,20 @@ LXAdjustFrame(int scrnIndex, int x, int y, int flags) unsigned long offset; - /* XXX: Is pitch correct here? */ - - offset = pGeode->FBOffset + (y * pGeode->Pitch); + offset = (y * pGeode->Pitch); offset += x * (pScrni->bitsPerPixel >> 3); vg_set_display_offset(offset); } static Bool -LXSetVideoMode(ScrnInfoPtr pScrni, DisplayModePtr pMode) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - DF_VIDEO_SOURCE_PARAMS vs_odd, vs_even; - int flags = 0; - int video_enable; - unsigned long video_flags; - - 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); - - /* If the mode is a default one, then set the mode with the Cimarron - * tables */ - - if ((pMode->type & M_T_BUILTIN) || (pMode->type & M_T_DEFAULT)) { - 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); - } - } else { - /* For anything other then a default mode - use the passed in - * timings */ - - lx_set_custom_mode(pGeode, pMode, pScrni->bitsPerPixel); - } - - 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(0); - vg_wait_vertical_blank(); - - if (pGeode->Compression) { - vg_configure_compression(&(pGeode->CBData)); - vg_set_compression_enable(1); - } - - if (pGeode->HWCursor && !(pMode->Flags & V_DBLSCAN)) { - VG_PANNING_COORDINATES panning; - - LXLoadCursorImage(pScrni, NULL); - vg_set_cursor_position(0, 0, &panning); - LXShowCursor(pScrni); - } else { - vg_set_cursor_enable(0); - pGeode->HWCursor = FALSE; - } - - 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); - - lx_enable_dac_power(pScrni, 1); - - return TRUE; -} - -static Bool LXSwitchMode(int index, DisplayModePtr pMode, int flags) { ScrnInfoPtr pScrni = xf86Screens[index]; GeodeRec *pGeode = GEODEPTR(pScrni); - int ret = TRUE; - int rotate; - - /* Syn the engine and shutdown the DAC momentarily */ - gp_wait_until_idle(); - - /* Set up the memory for the new mode */ - rotate = LXGetRotation(pScrni->pScreen); - ret = LXAllocateMemory(pScrni->pScreen, pScrni, rotate); - - if (ret) { - if (pGeode->curMode != pMode) - ret = LXSetVideoMode(pScrni, pMode); - } - if (ret) - ret = LXRotate(pScrni, pMode); - - /* Go back the way it was */ - - if (ret == FALSE) { - if (!LXSetVideoMode(pScrni, pGeode->curMode)) - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, - "Could not restore the previous mode\n"); - } else - pGeode->curMode = pMode; - - return ret; + /* Set the new mode */ + return xf86SetSingleMode(pScrni, pMode, pGeode->rotation); } static void @@ -1039,8 +656,6 @@ LXLeaveGraphics(ScrnInfoPtr pScrni) gp_wait_until_idle(); - lx_disable_dac_power(pScrni, DF_CRT_DISABLE); - vg_set_custom_mode(&(pGeode->FBcimdisplaytiming.vgDisplayMode), pGeode->FBcimdisplaytiming.wBpp); @@ -1069,7 +684,6 @@ LXLeaveGraphics(ScrnInfoPtr pScrni) vg_delay_milliseconds(3); } - lx_enable_dac_power(pScrni, 1); pScrni->vtSema = FALSE; } @@ -1088,6 +702,9 @@ LXCloseScreen(int scrnIndex, ScreenPtr pScrn) pGeode->pExa = NULL; } + /* Unmap the offscreen allocations */ + GeodeCloseOffscreen(pScrni); + LXUnmapMem(pScrni); if (pGeode->useVGA) @@ -1108,19 +725,13 @@ LXEnterGraphics(ScreenPtr pScrn, ScrnInfoPtr pScrni) int bpp; GeodeRec *pGeode = GEODEPTR(pScrni); - pGeode->curMode = NULL; - 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(); @@ -1170,17 +781,13 @@ LXEnterGraphics(ScreenPtr pScrn, ScrnInfoPtr pScrni) 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); + memset(pGeode->FBBase, 0, pGeode->displaySize); - /* Set the video mode */ - LXSetVideoMode(pScrni, pScrni->currentMode); + /* Set the modes */ + if (!xf86SetDesiredModes(pScrni)) + return FALSE; - pGeode->curMode = pScrni->currentMode; pScrni->vtSema = TRUE; return TRUE; @@ -1202,86 +809,13 @@ LXLoadPalette(ScrnInfoPtr pScrni, } } -#ifdef DPMSExtension - -static void -LXDPMSSet(ScrnInfoPtr pScrni, int mode, int flags) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - if (!pScrni->vtSema) - return; - - if (pGeode->Output & OUTPUT_DCON) { - if (DCONDPMSSet(pScrni, mode, flags)) - return; - } - - switch (mode) { - case DPMSModeOn: - lx_enable_dac_power(pScrni, 1); - break; - - case DPMSModeStandby: - lx_disable_dac_power(pScrni, DF_CRT_STANDBY); - break; - - case DPMSModeSuspend: - lx_disable_dac_power(pScrni, DF_CRT_SUSPEND); - break; - - case DPMSModeOff: - lx_disable_dac_power(pScrni, DF_CRT_DISABLE); - break; - } -} - -#endif - -static Bool -LXCreateScreenResources(ScreenPtr pScreen) -{ - ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; - GeodeRec *pGeode = GEODEPTR(pScrni); - - pScreen->CreateScreenResources = pGeode->CreateScreenResources; - if (!(*pScreen->CreateScreenResources) (pScreen)) - 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->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; - - LXRandRSetConfig = LoaderSymbol("LXRandRSetConfig"); - if (LXRandRSetConfig) { - pGeode->starting = TRUE; - (*LXRandRSetConfig) (pScreen, requestedRotation, 0, &p); - pGeode->starting = FALSE; - } - } - - return TRUE; -} - 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; + int ret; + unsigned int dwidth; pGeode->starting = TRUE; @@ -1301,17 +835,14 @@ LXScreenInit(int scrnIndex, ScreenPtr pScrn, int argc, char **argv) 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; + pGeode->pExa->maxX = LX_MAX_WIDTH - 1; + pGeode->pExa->maxY = LX_MAX_HEIGHT - 1; } else { xf86DrvMsg(scrnIndex, X_ERROR, "Couldn't allocate the EXA structure.\n"); @@ -1324,6 +855,8 @@ LXScreenInit(int scrnIndex, ScreenPtr pScrn, int argc, char **argv) if (!LXMapMem(pScrni)) return FALSE; + LXInitOffscreen(pScrni); + /* XXX FIXME - Take down any of the structures on failure? */ if (!LXEnterGraphics(pScrn, pScrni)) return FALSE; @@ -1347,12 +880,21 @@ LXScreenInit(int scrnIndex, ScreenPtr pScrn, int argc, char **argv) miSetPixmapDepths(); + if (pScrni->virtualX > pScrni->displayWidth) + pScrni->displayWidth = pScrni->virtualX; + /* Point at the visible area to start */ - ret = fbScreenInit(pScrn, pGeode->FBBase + pGeode->displayOffset, + /* fbScreenInit assumes that the stride is display width * + * bytes per pixel. If compression is on, then our stride might + * be completely different, so we divide the pitch by the + * bytes per pixel to fake fbScreenInit into doing the right thing */ + + dwidth = pGeode->Pitch / ((pScrni->bitsPerPixel + 7) / 8); + + ret = fbScreenInit(pScrn, pGeode->FBBase, pScrni->virtualX, pScrni->virtualY, - pScrni->xDpi, pScrni->yDpi, pGeode->displayWidth, - pScrni->bitsPerPixel); + pScrni->xDpi, pScrni->yDpi, dwidth, pScrni->bitsPerPixel); if (!ret) return FALSE; @@ -1390,7 +932,7 @@ LXScreenInit(int scrnIndex, ScreenPtr pScrn, int argc, char **argv) /* Set up the HW cursor - must follow the soft cursor init */ if (pGeode->tryHWCursor) { - if (!LXHWCursorInit(pScrn)) + if (!LXCursorInit(pScrn)) xf86DrvMsg(scrnIndex, X_ERROR, "Hardware cursor initialization failed.\n"); } @@ -1409,48 +951,22 @@ LXScreenInit(int scrnIndex, ScreenPtr pScrn, int argc, char **argv) return FALSE; } } -#ifdef DPMSExtension - xf86DPMSInit(pScrn, LXDPMSSet, 0); -#endif + xf86DPMSInit(pScrn, xf86DPMSSet, 0); 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; + if (!xf86CrtcScreenInit(pScrn)) { + xf86DrvMsg(scrnIndex, X_ERROR, "CRTCScreenInit failed.\n"); + return FALSE; + } + if (serverGeneration == 1) xf86ShowUnusedOptions(pScrni->scrnIndex, pScrni->options); @@ -1462,71 +978,13 @@ LXScreenInit(int scrnIndex, ScreenPtr pScrn, int argc, char **argv) static int LXValidMode(int scrnIndex, DisplayModePtr pMode, Bool Verbose, int flags) { - ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; - GeodeRec *pGeode = GEODEPTR(pScrni); - int p, ret; - VG_QUERY_MODE vgQueryMode; - - memset(&vgQueryMode, 0, sizeof(vgQueryMode)); - - /* For builtin and default modes, try to look up the mode in Cimarron */ - - if ((pMode->type & M_T_BUILTIN) || (pMode->type & M_T_DEFAULT)) { - - 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; } -/* XXX - Way more to do here */ - static Bool LXEnterVT(int scrnIndex, int flags) { - ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; - Bool ret = LXEnterGraphics(NULL, pScrni); - - /* Reallocate a shadow area, if we need it */ - - if (ret == TRUE) - ret = LXAllocShadow(pScrni); - - return ret; + return LXEnterGraphics(NULL, xf86Screens[scrnIndex]); } static void @@ -1536,14 +994,7 @@ LXLeaveVT(int scrnIndex, int flags) GeodeRec *pGeode = GEODEPTR(pScrni); pGeode->PrevDisplayOffset = vg_get_display_offset(); - LXLeaveGraphics(xf86Screens[scrnIndex]); - - /* Destroy any shadow area, if we have it */ - - if (pGeode->shadowArea != NULL) { - exaOffscreenFree(pScrni->pScreen, pGeode->shadowArea); - pGeode->shadowArea = NULL; - } + LXLeaveGraphics(pScrni); } void diff --git a/src/lx_exa.c b/src/lx_exa.c index f6978d8..5d636ea 100644 --- a/src/lx_exa.c +++ b/src/lx_exa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Advanced Micro Devices, Inc. + * Copyright (c) 2007-2008 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"), @@ -30,6 +30,8 @@ support multiple pass operations? */ +/* To support PictOptAdd with a mask */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -43,6 +45,9 @@ #include "geode_blend.h" +#define F(x) IntToxFixed(x) +#define I(x) xFixedToInt(x) + static const struct exa_format_t { int exa; @@ -68,6 +73,7 @@ static const struct exa_format_t #define COMP_TYPE_MASK 0 #define COMP_TYPE_ONEPASS 1 #define COMP_TYPE_TWOPASS 3 +#define COMP_TYPE_ROTATE 5 static struct { @@ -86,6 +92,10 @@ static struct unsigned int bufferOffset; struct exa_format_t *srcFormat; struct exa_format_t *dstFormat; + + int rotate; + PictTransform *transform; + } exaScratch; static const int SDfn[16] = { @@ -285,6 +295,7 @@ lx_prepare_solid(PixmapPtr pxMap, int alu, Pixel planemask, Pixel fg) exaScratch.op = op; gp_set_solid_source(fg); + gp_set_strides(pitch, pitch); gp_write_parameters(); return TRUE; @@ -340,15 +351,11 @@ lx_do_copy(PixmapPtr pxDst, int srcX, int srcY, 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; + dstOffset = exaGetPixmapOffset(pxDst) + + (dstPitch * dstY) + (dstBpp * dstX); if (dstX > srcX) flags |= CIMGP_NEGXDIR; @@ -461,19 +468,71 @@ lx_get_format(PicturePtr p) 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_process_transform(PicturePtr pSrc) +{ + PictTransformPtr t = pSrc->transform; + xFixed c0 = t->matrix[0][0]; + xFixed s0 = t->matrix[0][1]; + xFixed s1 = t->matrix[1][0]; + xFixed c1 = t->matrix[1][1]; + + /* If the transform doesn't have any rotation + * or scaling components, then just grab the + * translate coordinates */ + + if (t->matrix[0][0] == 0 && + t->matrix[0][1] == 0 && + t->matrix[1][0] == 0 && t->matrix[1][1] == 0) { + exaScratch.transform = pSrc->transform; + return TRUE; + } + + /* Otherwise, see if this is a simple + * rotate transform - if it isn't, then + * we have to punt back to software */ + + if (t->matrix[2][2] != F(1)) + return FALSE; + + /* The rotate matrix looks like this: + * [ cos X -sin x + * sin X cos X ] + * + * Where X is the angle. We do a simple + * check first - if [0,0] != [1,1], then + * scaling was specified too, and we can + * bail, and if [0,1] != -[1,1] then this + * isn't scaling that we can handle. + */ + + if ((c0 != c1) || (s0 != -s1)) + return FALSE; + + /* Now, figure out what angle we want - we + * can only accelerate right angle rotations, + * so this turns into an easy set of if statements */ + + if (c0 == F(1) && s1 == F(0)) + exaScratch.rotate = RR_Rotate_0; + else if (c0 == F(0) && s1 == F(1)) + exaScratch.rotate = RR_Rotate_90; + else if (c0 == F(-1) && s1 == F(0)) + exaScratch.rotate = RR_Rotate_180; + else if (c0 == F(0) && s1 == F(-1)) + exaScratch.rotate = RR_Rotate_270; + else + return FALSE; + + exaScratch.transform = pSrc->transform; + + return TRUE; +} + +static Bool lx_check_composite(int op, PicturePtr pSrc, PicturePtr pMsk, PicturePtr pDst) { GeodeRec *pGeode = GEODEPTR_FROM_PICTURE(pDst); @@ -488,6 +547,9 @@ lx_check_composite(int op, PicturePtr pSrc, PicturePtr pMsk, PicturePtr pDst) return FALSE; } + if (pMsk && op == PictOpAdd) + return FALSE; + /* Check that the filter matches what we support */ switch (pSrc->filter) { @@ -498,13 +560,17 @@ lx_check_composite(int op, PicturePtr pSrc, PicturePtr pMsk, PicturePtr pDst) break; default: - ErrorF("invalid filter %d\n", pSrc->filter); + /* WE don't support bilinear or convolution filters */ return FALSE; } - /* We don't handle transforms */ + /* Keep an eye out for rotation transforms - those we can + * do something about */ - if (pSrc->transform) + exaScratch.rotate = RR_Rotate_0; + exaScratch.transform = NULL; + + if (pSrc->transform && !lx_process_transform(pSrc)) return FALSE; /* XXX - I don't understand PICT_a8 enough - so I'm punting */ @@ -537,21 +603,25 @@ lx_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMsk, /* 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"); + if (!pMsk && (!srcFmt->alphabits && usesSrcAlpha(op))) return FALSE; - } - if (!pMsk && (!dstFmt->alphabits && usesDstAlpha(op))) { - ErrorF("EXA: Dest needs alpha bits\n"); + if (!pMsk && (!dstFmt->alphabits && usesDstAlpha(op))) return FALSE; - } /* FIXME: See a way around this! */ if (srcFmt->alphabits == 0 && dstFmt->alphabits != 0) return FALSE; + /* If this is a rotate operation, then make sure the src and dst + * formats are the same */ + + if (exaScratch.rotate != RR_Rotate_0 && srcFmt != dstFmt) { + ErrorF("EXA: Can't rotate and convert formats at the same time\n"); + return FALSE; + } + /* Set up the scratch buffer with the information we need */ exaScratch.srcFormat = (struct exa_format_t *)srcFmt; @@ -612,6 +682,8 @@ lx_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMsk, } else { if (usesPasses(op)) exaScratch.type = COMP_TYPE_TWOPASS; + else if (exaScratch.rotate != RR_Rotate_0) + exaScratch.type = COMP_TYPE_ROTATE; else exaScratch.type = COMP_TYPE_ONEPASS; @@ -685,8 +757,6 @@ get_op_type(struct exa_format_t *src, struct exa_format_t *dst, int type) * ifdefed out until such time that we are sure its not needed */ -#if 1 - static void lx_composite_onepass(PixmapPtr pxDst, unsigned long dstOffset, unsigned long srcOffset, int width, int height) @@ -715,99 +785,6 @@ lx_composite_onepass(PixmapPtr pxDst, unsigned long dstOffset, 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, type; - 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); - - type = - get_op_type(exaScratch.srcFormat, exaScrach.dstFormat, opPtr->type); - - gp_set_alpha_operation(opPtr->operation, 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 */ - - 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 @@ -877,6 +854,39 @@ lx_composite_multipass(PixmapPtr pxDst, unsigned long dstOffset, } static void +lx_composite_rotate(PixmapPtr pxDst, unsigned long dstOffset, + unsigned int srcOffset, int width, int height) +{ + int degrees = 0; + + 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_raster_operation(0xCC); + + /* RandR rotation is counter-clockwise, our rotation + * is clockwise, so adjust the numbers accordingly */ + + switch (exaScratch.rotate) { + case RR_Rotate_90: + degrees = 270; + break; + case RR_Rotate_180: + degrees = 180; + break; + case RR_Rotate_270: + degrees = 90; + break; + } + + gp_rotate_blt(dstOffset, srcOffset, width, height, degrees); +} + +static void lx_do_composite_mask(PixmapPtr pxDst, unsigned long dstOffset, unsigned int maskOffset, int width, int height) { @@ -897,46 +907,114 @@ lx_do_composite_mask(PixmapPtr pxDst, unsigned long dstOffset, (exaGetPixmapPitch((px)) * (y)) + \ ((((px)->drawable.bitsPerPixel + 7) / 8) * (x)) ) +#define GetSrcOffset(_x, _y) (exaScratch.srcOffset + ((_y) * exaScratch.srcPitch) + \ + ((_x) * exaScratch.srcBpp)) + +static void +transformPoint(PictTransform * t, xPointFixed * point) +{ + PictVector v; + + v.vector[0] = point->x; + v.vector[1] = point->y; + v.vector[2] = xFixed1; + + if (t != NULL) + PictureTransformPoint(t, &v); + + point->x = v.vector[0]; + point->y = v.vector[1]; +} + 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 dstOffset, srcOffset; + unsigned int dstOffset, srcOffset = 0; - unsigned int opX = dstX; - unsigned int opY = dstY; - unsigned int opWidth = width; - unsigned int opHeight = height; + xPointFixed srcPoint; - 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); + int opX = dstX; + int opY = dstY; + int opWidth = width; + int opHeight = height; + + /* Transform the source coordinates */ + + if (exaScratch.type == COMP_TYPE_MASK) { + srcPoint.x = F(maskX); + srcPoint.y = F(maskY); + } else { + srcPoint.x = F(srcX); + srcPoint.y = F(srcY); + } + + /* srcX, srcY point to the upper right side of the bounding box + * in the unrotated coordinate space. Depending on the orientation, + * we have to translate the coordinates to point to the origin of + * the rectangle in the source pixmap */ + + switch (exaScratch.rotate) { + case RR_Rotate_270: + srcPoint.x += F(width); + + opWidth = height; + opHeight = width; + break; + + case RR_Rotate_180: + srcPoint.x += F(width); + srcPoint.y += F(height); + + srcX += width; + srcY += height; + break; + + case RR_Rotate_90: + srcPoint.y += F(height); + + opWidth = height; + opHeight = width; + break; + } - /* Adjust the width / height of the operation the size of the source */ + transformPoint(exaScratch.transform, &srcPoint); - if (exaScratch.srcWidth < width) + /* Adjust the point to fit into the pixmap */ + + if (I(srcPoint.x) < 0) { + opWidth += I(srcPoint.x); + srcPoint.x = F(0); + } + + if (I(srcPoint.y) < 0) { + opHeight += I(srcPoint.y); + srcPoint.y = F(0); + } + + srcOffset = GetSrcOffset(I(srcPoint.x), I(srcPoint.y)); + + if (exaScratch.srcWidth < opWidth) opWidth = exaScratch.srcWidth; - if (exaScratch.srcHeight < height) + if (exaScratch.srcHeight < opHeight) opHeight = exaScratch.srcHeight; while (1) { + dstOffset = GetPixmapOffset(pxDst, opX, opY); 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); + GetPixmapOffset(exaScratch.srcPixmap, opX, opY); lx_do_composite_mask(exaScratch.srcPixmap, dstOffset, srcOffset, opWidth, opHeight); } else { @@ -954,6 +1032,10 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX, case COMP_TYPE_TWOPASS: lx_composite_multipass(pxDst, dstOffset, srcOffset, opWidth, opHeight); + + case COMP_TYPE_ROTATE: + lx_composite_rotate(pxDst, dstOffset, srcOffset, opWidth, + opHeight); break; } @@ -988,6 +1070,50 @@ lx_done(PixmapPtr ptr) { } +#if 0 +static void +lx_upload_to_screen(PixmapPtr pxDst, int x, int y, int w, int h, + char *src, int src_pitch) +{ + GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst); + int dst_pitch = exaGetPixmapPitch(pxDst); + int cpp = (pxDst->drawable.bitsPerPixel + 7) / 8; + + char *dst; + int offset = exaGetPixmapOffset(pxDst); + + dst = (char *)(pGeode->FBBase + offset + (y * dst_pitch) + (x * cpp)); + int i; + + for (i = 0; i < h; i++) { + memcpy(dst, src, w * cpp); + dst += dst_pitch; + src += src_pitch; + } +} +#endif + +#if EXA_VERSION_MINOR >= 2 + +static Bool +lx_exa_pixmap_is_offscreen(PixmapPtr pPixmap) +{ + ScrnInfoPtr pScrni = xf86Screens[pPixmap->drawable.pScreen->myNum]; + GeodeRec *pGeode = GEODEPTR(pScrni); + void *start = (void *)(pGeode->FBBase); + void *end = + (void *)(pGeode->FBBase + pGeode->offscreenStart + + pGeode->offscreenSize); + + if ((void *)pPixmap->devPrivate.ptr >= start && + (void *)pPixmap->devPrivate.ptr < end) + return TRUE; + + return FALSE; +} + +#endif + Bool LXExaInit(ScreenPtr pScreen) { @@ -1013,6 +1139,13 @@ LXExaInit(ScreenPtr pScreen) pExa->PrepareComposite = lx_prepare_composite; pExa->Composite = lx_do_composite; pExa->DoneComposite = lx_done; + //pExa->UploadToScreen = lx_upload_to_screen; + +#if EXA_VERSION_MINOR >= 2 + pExa->PixmapIsOffscreen = lx_exa_pixmap_is_offscreen; +#endif + + //pExa->flags = EXA_OFFSCREEN_PIXMAPS; return exaDriverInit(pScreen, pGeode->pExa); } diff --git a/src/lx_memory.c b/src/lx_memory.c new file mode 100644 index 0000000..4f4c4de --- /dev/null +++ b/src/lx_memory.c @@ -0,0 +1,297 @@ +/* Copyright (c) 2008 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 "geode.h" +#include "cim/cim_regs.h" + +#define ALIGN(x,y) (((x) + (y) - 1) / (y) * (y)) +#define LX_CB_PITCH 544 + +/* Geode offscreen memory allocation functions. This is + overengineered for the simple hardware that we have, but + there are multiple functions that may want to independently + allocate and free memory (crtc->shadow_alloc and Xv). This + provides a semi-robust mechanism for doing that. +*/ + +/* Return the number of free bytes */ + +unsigned int +GeodeOffscreenFreeSize(GeodeRec * pGeode) +{ + GeodeMemPtr ptr = pGeode->offscreenList; + + if (ptr == NULL) + return pGeode->offscreenSize; + + for (; ptr->next; ptr = ptr->next) ; + return pGeode->offscreenSize - (ptr->offset + ptr->size); +} + +void +GeodeFreeOffscreen(GeodeRec * pGeode, GeodeMemPtr ptr) +{ + /* There is a clear memory leak here, but + * but it is unlikely that the first block of + * "allocated" memory is going to be released + * individually. + */ + + if (ptr->prev == NULL) + pGeode->offscreenList = ptr->next; + else + ptr->prev->next = ptr->next; + + if (ptr->next) + ptr->next->prev = ptr->prev; + + xfree(ptr); +} + +/* Allocate the "rest" of the offscreen memory - this is for + situations where we have very little video memory, and we + want to take as much of it as we can for EXA +*/ + +static GeodeMemPtr +GeodeAllocRemainder(GeodeRec * pGeode) +{ + GeodeMemPtr nptr, ptr = pGeode->offscreenList; + + if (!pGeode->offscreenList) { + pGeode->offscreenList = xcalloc(1, sizeof(*nptr)); + pGeode->offscreenList->offset = pGeode->offscreenStart; + pGeode->offscreenList->size = pGeode->offscreenSize; + pGeode->offscreenList->next = NULL; + pGeode->offscreenList->prev = NULL; + + return pGeode->offscreenList; + } + + /* Go to the end of the list of allocated stuff */ + for (; ptr->next; ptr = ptr->next) ; + + nptr = xcalloc(1, sizeof(*nptr)); + nptr->offset = ptr->offset + ptr->size; + nptr->size = pGeode->offscreenSize - nptr->offset; + nptr->next = ptr->next; + nptr->prev = ptr; + ptr->next = nptr; + + return nptr; +} + +/* Allocate 'size' bytes of offscreen memory. +*/ + +GeodeMemPtr +GeodeAllocOffscreen(GeodeRec * pGeode, int size, int align) +{ + GeodeMemPtr ptr = pGeode->offscreenList; + GeodeMemPtr nptr; + + unsigned int offset; + + if (!pGeode->offscreenList) { + + if (size > pGeode->offscreenSize) + return NULL; + + offset = ALIGN(pGeode->offscreenStart, align); + + pGeode->offscreenList = xcalloc(1, sizeof(*nptr)); + pGeode->offscreenList->offset = offset; + pGeode->offscreenList->size = size; + pGeode->offscreenList->next = NULL; + + return pGeode->offscreenList; + } + + while (ptr) { + unsigned int gap; + + if (ptr->next == NULL) + gap = pGeode->offscreenSize; + + else + gap = ptr->next->offset; + + gap = gap - (ptr->offset + ptr->size); + gap = ALIGN(gap, align); + + if (size < gap) { + offset = ptr->offset + ptr->size; + offset = ALIGN(ptr->offset + ptr->size, align); + + nptr = xcalloc(1, sizeof(*nptr)); + nptr->offset = offset; + nptr->size = size; + nptr->next = ptr->next; + nptr->prev = ptr; + ptr->next = nptr; + + return nptr; + } + + ptr = ptr->next; + } + + return NULL; +} + +/* Carve out the space for the visible screen, and carve out + the usual suspects that need offscreen memory +*/ + +#define MAX(a,b) ((a) > (b) ? (a) : (b)) + +void +LXInitOffscreen(ScrnInfoPtr pScrni) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + unsigned int fbavail; + GeodeMemPtr ptr; + + /* The scratch buffer is always used */ + fbavail = pGeode->FBAvail - GP3_SCRATCH_BUFFER_SIZE; + + pGeode->displaySize = MAX(pScrni->virtualX, pScrni->virtualY) + * pGeode->Pitch; + + pGeode->offscreenStart = pGeode->displaySize; + pGeode->offscreenSize = fbavail - pGeode->displaySize; + + /* Allocate the usual memory suspects */ + if (pGeode->tryCompression) { + int size = pScrni->virtualY * LX_CB_PITCH; + + /* The compression buffer needs to be 16 byte aligned */ + ptr = GeodeAllocOffscreen(pGeode, size, 16); + + if (ptr != NULL) { + pGeode->CBData.compression_offset = ptr->offset; + pGeode->CBData.size = LX_CB_PITCH; + pGeode->CBData.pitch = LX_CB_PITCH; + + pGeode->Compression = TRUE; + } else { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Not enough memory for compression\n"); + pGeode->Compression = FALSE; + } + } + + if (pGeode->tryHWCursor) { + ptr = GeodeAllocOffscreen(pGeode, 1024, 4); + if (ptr != NULL) { + pGeode->CursorStartOffset = ptr->offset; + pGeode->HWCursor = TRUE; + } else { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Not enough memory for the hardware cursor\n"); + pGeode->HWCursor = FALSE; + } + } + + if (!pGeode->NoAccel && pGeode->pExa) { + int size; + + /* Try to get the scratch buffer for blending */ + pGeode->exaBfrOffset = 0; + + if (pGeode->exaBfrSz > 0) { + ptr = GeodeAllocOffscreen(pGeode, pGeode->exaBfrSz, 4); + if (ptr != NULL) + pGeode->exaBfrOffset = ptr->offset; + } + + pGeode->pExa->offScreenBase = 0; + pGeode->pExa->memorySize = 0; + + /* In a break from the previous behavior, we will + * allocate 3 screens worth of offscreen memory. + * (that means, 3 * y * (x * bpp) - not the compressed + * pitch if it is enabled). */ + + /* FIXME: Make this configurable */ + + size = 3 * (pScrni->virtualY * + ((pScrni->virtualX + 3) & ~3) * (pScrni->bitsPerPixel >> 3)); + + ptr = GeodeAllocOffscreen(pGeode, size, 4); + + if (ptr == NULL) { + /* If we couldn't allocate what we wanted, + * then allocate whats left */ + + ptr = GeodeAllocRemainder(pGeode); + } + + if (ptr != NULL) { + pGeode->pExa->offScreenBase = ptr->offset; + pGeode->pExa->memorySize = ptr->offset + ptr->size; + } + } + + /* Show the memory map for diagnostic purposes */ + + xf86DrvMsg(pScrni->scrnIndex, X_INFO, "LX video memory:\n"); + xf86DrvMsg(pScrni->scrnIndex, X_INFO, " Display: 0x%x bytes\n", + pGeode->displaySize); + + if (pGeode->Compression) + xf86DrvMsg(pScrni->scrnIndex, X_INFO, " Compression: 0x%x bytes\n", + pScrni->virtualY * LX_CB_PITCH); + + if (pGeode->HWCursor) + xf86DrvMsg(pScrni->scrnIndex, X_INFO, " Cursor: 0x400 bytes\n"); + + if (pGeode->pExa->offScreenBase) + xf86DrvMsg(pScrni->scrnIndex, X_INFO, " EXA: 0x%x bytes\n", + (unsigned int)(pGeode->pExa->memorySize - + pGeode->pExa->offScreenBase)); + + xf86DrvMsg(pScrni->scrnIndex, X_INFO, " FREE: 0x%x bytes\n", + GeodeOffscreenFreeSize(pGeode)); +} + +/* Called as we go down, so blitz everybody */ + +void +GeodeCloseOffscreen(ScrnInfoPtr pScrni) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + GeodeMemPtr ptr = pGeode->offscreenList; + GeodeMemPtr nptr; + + while (ptr) { + nptr = ptr->next; + xfree(ptr); + ptr = nptr; + } + + pGeode->offscreenList = NULL; +} diff --git a/src/lx_output.c b/src/lx_output.c new file mode 100644 index 0000000..53a538a --- /dev/null +++ b/src/lx_output.c @@ -0,0 +1,272 @@ +/* Copyright (c) 2008 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 "X11/Xatom.h" +#include "geode.h" +#include "xf86Modes.h" +#include "xf86Crtc.h" +#include "cim/cim_defs.h" +#include "cim/cim_regs.h" + +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) + +typedef struct _LXOutputPrivateRec +{ + I2CBusPtr pDDCBus; +} LXOutputPrivateRec, *LXOutputPrivatePtr; + +static Atom scale_atom; + +static void +lx_create_resources(xf86OutputPtr output) +{ + int ret; + char *s; + ScrnInfoPtr pScrni = output->scrn; + GeodeRec *pGeode = GEODEPTR(pScrni); + + /* Scaling is only used for panels */ + + if (!(pGeode->Output & OUTPUT_PANEL)) + return; + + scale_atom = MAKE_ATOM("scale"); + ret = RRConfigureOutputProperty(output->randr_output, + scale_atom, FALSE, FALSE, FALSE, 0, NULL); + + if (ret) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "RRConfigureOutputProperty error %d\n", ret); + } + + s = "on"; + ret = RRChangeOutputProperty(output->randr_output, scale_atom, + XA_STRING, 8, PropModeReplace, strlen(s), (pointer) s, FALSE, FALSE); + + if (ret) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "RRCharOutputProperty error %d\n", ret); + } +} + +static Bool +lx_output_set_property(xf86OutputPtr output, Atom property, + RRPropertyValuePtr value) +{ + ScrnInfoPtr pScrni = output->scrn; + GeodeRec *pGeode = GEODEPTR(pScrni); + Bool scale = pGeode->Scale; + char *s; + int ret; + + if (property != scale_atom) + return FALSE; + + if (value->type != XA_STRING || value->format != 8) + return FALSE; + + s = (char *)value->data; + + if (value->size == 2 && !strncmp("on", s, 2)) + pGeode->Scale = TRUE; + else if (value->size == 3 && !strncmp("off", s, 3)) + pGeode->Scale = FALSE; + + if (pGeode->Scale != scale && output->crtc) { + xf86CrtcPtr crtc = output->crtc; + + if (crtc->enabled) { + ret = xf86CrtcSetMode(crtc, &crtc->desiredMode, + crtc->desiredRotation, crtc->desiredX, crtc->desiredY); + + if (!ret) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Failed to set mode after propery change!\n"); + + pGeode->Scale = scale; + return FALSE; + } + } + } + + return TRUE; +} + +static void +lx_output_dpms(xf86OutputPtr output, int mode) +{ + /* DPMS is handled by the CRTC */ +} + +static void +lx_output_prepare(xf86OutputPtr output) +{ + /* Nothing to do */ +} + +static void +lx_output_commit(xf86OutputPtr output) +{ + /* Nothing to do */ +} + +static void +lx_output_save(xf86OutputPtr output) +{ + /* Nothing to do */ +} + +static void +lx_output_restore(xf86OutputPtr output) +{ + /* Nothing to do */ +} + +static int +lx_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) +{ + ScrnInfoPtr pScrni = output->scrn; + GeodeRec *pGeode = GEODEPTR(pScrni); + + /* No scaling > for modes with > 1024 width */ + + if (pGeode->Output & OUTPUT_PANEL) { + if ((pMode->HDisplay != pGeode->panelMode->HDisplay) && + pMode->HDisplay > 1024) + return MODE_BAD; + } + + return MODE_OK; +} + +static Bool +lx_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + return TRUE; +} + +static void +lx_output_mode_set(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + ScrnInfoPtr pScrni = output->scrn; + GeodeRec *pGeode = GEODEPTR(pScrni); + + /* Configure the output path */ + + 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); +} + +static xf86OutputStatus +lx_output_detect(xf86OutputPtr output) +{ + /* We assume that there is always something + * out there */ + + return XF86OutputStatusConnected; +} + +static DisplayModePtr +lx_output_get_modes(xf86OutputPtr output) +{ + ScrnInfoPtr pScrni = output->scrn; + GeodeRec *pGeode = GEODEPTR(pScrni); + LXOutputPrivatePtr lx_output = output->driver_private; + + xf86MonPtr mon; + DisplayModePtr modes; + + if (!(pGeode->Output & OUTPUT_PANEL)) { + mon = xf86OutputGetEDID(output, lx_output->pDDCBus); + xf86OutputSetEDID(output, mon); + modes = xf86OutputGetEDIDModes(output); + } else { + modes = xf86DuplicateMode(pGeode->panelMode); + } + + return modes; +} + +static void +lx_output_destroy(xf86OutputPtr output) +{ + if (output->driver_private) + xfree(output->driver_private); + + output->driver_private = NULL; +} + +static const xf86OutputFuncsRec lx_output_funcs = { + .create_resources = lx_create_resources, + .dpms = lx_output_dpms, + .save = lx_output_save, + .restore = lx_output_restore, + .mode_valid = lx_output_mode_valid, + .mode_fixup = lx_output_mode_fixup, + .prepare = lx_output_prepare, + .mode_set = lx_output_mode_set, + .commit = lx_output_commit, + .detect = lx_output_detect, + .get_modes = lx_output_get_modes, + .set_property = lx_output_set_property, + .destroy = lx_output_destroy, +}; + +void +LXSetupOutput(ScrnInfoPtr pScrni) +{ + xf86OutputPtr output; + LXOutputPrivatePtr lxpriv; + + output = xf86OutputCreate(pScrni, &lx_output_funcs, "default"); + + lxpriv = xnfcalloc(1, sizeof(LXOutputPrivateRec)); + + if (!lxpriv) { + xf86OutputDestroy(output); + return; + } + + output->driver_private = lxpriv; + output->interlaceAllowed = TRUE; + output->doubleScanAllowed = TRUE; + + /* Set up the DDC bus */ + + GeodeI2CInit(pScrni, &lxpriv->pDDCBus, "CS5536 DDC"); + + /* We only have one CRTC, and this output is tied to it */ + output->possible_crtcs = 1; +} diff --git a/src/lx_panel.c b/src/lx_panel.c new file mode 100644 index 0000000..3a0e363 --- /dev/null +++ b/src/lx_panel.c @@ -0,0 +1,142 @@ +/* Copyright (c) 2008 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. + */ + +/* Reference: Video Graphics Suite Specification: + * VG Config Register (0x00) page 16 + * VG FP Register (0x02) page 18 + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> + +#include "xf86.h" +#include "compiler.h" +#include "xf86Modes.h" +#include "geode.h" + +#define LX_READ_VG(reg) \ + (outw(0xAC1C,0xFC53), outw(0xAC1C,0x0200|(reg)), inw(0xAC1E)) + +/* This is borrowed from xerver/hw/xfree86/modes */ + +#define MODEPREFIX NULL, NULL, NULL, 0, M_T_DRIVER +#define MODESUFFIX 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0 + +DisplayModeRec lx_panel_modes[] = { + {MODEPREFIX, 31200, 320, 354, 384, 400, 0, 240, 249, 253, 260, 0, + V_NHSYNC | V_NVSYNC, MODESUFFIX} + , /* 320x200@75 */ + {MODEPREFIX, 25175, 640, 656, 744, 800, 0, 480, 490, 492, 525, 0, + V_NHSYNC | V_NVSYNC, MODESUFFIX} + , /* 640x480@60 */ + {MODEPREFIX, 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0, + V_NHSYNC | V_NVSYNC, MODESUFFIX} + , /* 880x600@60 */ + {MODEPREFIX, 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, + V_NHSYNC | V_NVSYNC, MODESUFFIX} + , /* 1024x768@60 */ + {MODEPREFIX, 81600, 1152, 1216, 1336, 1520, 0, 864, 865, 868, 895, 0, + V_NHSYNC | V_NVSYNC, MODESUFFIX} + , /* 1152x864@60 */ + {MODEPREFIX, 108000, 1028, 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, + V_NHSYNC | V_NVSYNC, MODESUFFIX} + , /* 1280x1024@60 */ + {MODEPREFIX, 162000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, + V_NHSYNC | V_NVSYNC, MODESUFFIX} + , /* 1600x100@60 */ +}; + +/* Get the legacy panel size from VSA, and return the associated mode rec */ + +DisplayModePtr +LXGetLegacyPanelMode(void) +{ + 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) + return &lx_panel_modes[ret]; + + } + + return NULL; +} + +/* Construct a moderec from the specified panel mode */ + +DisplayModePtr +LXGetManualPanelMode(char *modestr) +{ + int clock; + int hactive, hsstart, hsend, htotal; + int vactive, vsstart, vsend, vtotal; + DisplayModePtr mode; + char sname[32]; + + int ret = sscanf(modestr, "%d %d %d %d %d %d %d %d %d", + &clock, + &hactive, &hsstart, &hsend, &htotal, + &vactive, &vsstart, &vsend, &vtotal); + + if (ret != 9) + return NULL; + + mode = xnfcalloc(1, sizeof(DisplayModeRec)); + + if (mode == NULL) + return NULL; + + sprintf(sname, "%dx%d", hactive, vactive); + + mode->name = xnfalloc(strlen(sname) + 1); + + mode->type = M_T_DRIVER | M_T_PREFERRED; + mode->Clock = clock; + mode->HDisplay = hactive; + mode->HSyncStart = hsstart; + mode->HSyncEnd = hsend; + mode->HTotal = htotal; + mode->VDisplay = vactive; + mode->VSyncStart = vsstart; + mode->VSyncEnd = vsend; + mode->VTotal = vtotal; + + mode->prev = mode->next = NULL; + + return mode; +} diff --git a/src/lx_randr.c b/src/lx_randr.c deleted file mode 100644 index 0604727..0000000 --- a/src/lx_randr.c +++ /dev/null @@ -1,370 +0,0 @@ -/* 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 "geode.h" - -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 AMD_OLDPRIV (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 4) -#if AMD_OLDPRIV - -static int LXRandRIndex; - -#define XF86RANDRINFO(p) ((XF86RandRInfoPtr) (p)->devPrivates[LXRandRIndex].ptr) - -#else - -static DevPrivateKey LXRandRKey; - -#define XF86RANDRINFO(p) ((XF86RandRInfoPtr) \ - dixLookupPrivate(&(p)->devPrivates, LXRandRKey)); - -#endif - -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; - } - -/* FIXME: we don't have a new video ABI yet */ -#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3 - miPointerGetPosition(inputInfo.pointer, &px, &py); -#else - miPointerPosition(&px, &py); -#endif - - 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; - } - -/* FIXME: we don't have a new video ABI yet */ -#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3 - if (pScreen == miPointerGetScreen(inputInfo.pointer)) -#else - if (pScreen == miPointerCurrentScreen()) -#endif - { - px = (px >= pScreen->width ? (pScreen->width - 1) : px); - py = (py >= pScreen->height ? (pScreen->height - 1) : py); - - xf86SetViewport(pScreen, px, py); - - (*pScreen->SetCursorPosition) ( -/* FIXME: we don't have a new video ABI yet */ -#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3 - inputInfo.pointer, -#endif - pScreen, - px, py, - FALSE); - } - - return TRUE; -} - -Rotation -LXGetRotation(ScreenPtr pScreen) -{ - XF86RandRInfoPtr pRandr = XF86RANDRINFO(pScreen); - - return pRandr ? pRandr->rotation : RR_Rotate_0; -} - -Bool -LXRandRInit(ScreenPtr pScreen, int rotation) -{ - XF86RandRInfoPtr pRandr; - rrScrPrivPtr rp; - - if (LXRandRGeneration != serverGeneration) { - LXRandRGeneration = serverGeneration; - } -#if AMD_OLDPRIV - LXRandRIndex = AllocateScreenPrivateIndex(); -#else - LXRandRKey = &LXRandRKey; -#endif - - 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; - -#if AMD_OLDPRIV - pScreen->devPrivates[LXRandRIndex].ptr = pRandr; -#else - dixSetPrivate(&pScreen->devPrivates, LXRandRKey, pRandr); -#endif - return TRUE; -} diff --git a/src/lx_regacc.c b/src/lx_regacc.c deleted file mode 100644 index 4a5a89b..0000000 --- a/src/lx_regacc.c +++ /dev/null @@ -1,65 +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. - */ - -/* - * This is the main file used to add Cimarron graphics support to a software - * project. The main reason to have a single file include the other files - * is that it centralizes the location of the compiler options. This file - * should be tuned for a specific implementation, and then modified as needed - * for new Cimarron releases. The releases.txt file indicates any updates to - * this main file, such as a new definition for a new hardware platform. - * - * In other words, this file should be copied from the Cimarron source files - * once when a software project starts, and then maintained as necessary. - * It should not be recopied with new versions of Cimarron unless the - * developer is willing to tune the file again for the specific project. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cim_defs.h" - -extern unsigned char *cim_vid_ptr; - -void cim_write_vid32(unsigned long offset, unsigned long value); -unsigned long cim_read_vid32(unsigned long offset); - -void -cim_write_vid32(unsigned long offset, unsigned long value) -{ - WRITE_VID32(offset, value); -} - -unsigned long -cim_read_vid32(unsigned long offset) -{ - unsigned long value; - - value = READ_VID32(offset); - return value; -} diff --git a/src/lx_rotate.c b/src/lx_rotate.c deleted file mode 100644 index bc29f26..0000000 --- a/src/lx_rotate.c +++ /dev/null @@ -1,282 +0,0 @@ -/* 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 "geode.h" - -static void -LXShadowSave(ScreenPtr pScreen, ExaOffscreenArea * area) -{ - ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; - GeodeRec *pGeode = GEODEPTR(pScrni); - - if (area == pGeode->shadowArea) - pGeode->shadowArea = NULL; -} - -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; -} - -static 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 = 0; - FbStride shaStride; - FbBits *shaBits; - int shaBpp, dx = 0, dy = 0, dw, dh; - int shaXoff, shaYoff; - unsigned int srcOffset, dstOffset; - PixmapPtr pShadow = pBuf->pPixmap; - ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; - GeodeRec *pGeode = GEODEPTR(pScrni); - - /* shaBits isn't reliable here, because we are outside of - * the EXA access boundaries - we'll just use the offset from - * the pixmap and hope for the best - we stil use fbGetDrawable - * for the other variables - */ - - fbGetDrawable(&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, - shaYoff); - - /* Set up the blt */ - - gp_wait_until_idle(); - gp_declare_blt(0); - - gp_set_bpp(pScrni->bitsPerPixel); - - 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 24: - case 32: - gp_set_source_format(CIMGP_SOURCE_FMT_8_8_8_8); - break; - } - - 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 = pGeode->shadowArea->offset; - srcOffset += (y * pGeode->Pitch) + (x * (shaBpp >> 3)); - - switch (pGeode->rotation) { - case RR_Rotate_0: - dx = x; - dy = y; - dw = w; - dh = h; - degrees = 0; - break; - - 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(CIMGP_BLTFLAGS_HAZARD); - gp_set_strides(pGeode->displayPitch, pGeode->Pitch); - gp_rotate_blt(dstOffset, srcOffset, w, h, degrees); - pbox++; - } -} - -Bool -LXSetRotatePitch(ScrnInfoPtr pScrni) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - pScrni->displayWidth = pGeode->displayWidth; - - if (pGeode->Compression) - pGeode->Pitch = GeodeCalculatePitchBytes(pScrni->displayWidth, - pScrni->bitsPerPixel); - else - pGeode->Pitch = (pScrni->displayWidth * (pScrni->bitsPerPixel >> 3)); - return TRUE; -} - -Bool -LXAllocShadow(ScrnInfoPtr pScrni) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - PixmapPtr pPixmap; - - int size; - - if (pGeode->rotation == RR_Rotate_0) { - - if (pGeode->shadowArea) { - exaOffscreenFree(pScrni->pScreen, pGeode->shadowArea); - pGeode->shadowArea = NULL; - } - - pScrni->fbOffset = pGeode->displayOffset; - } else { - if (pGeode->rotation == RR_Rotate_90 - || pGeode->rotation == RR_Rotate_270) - size = pGeode->displayPitch * pScrni->virtualX; - else - size = pGeode->displayPitch * pScrni->virtualY; - - if (pGeode->shadowArea) { - - if (pGeode->shadowArea->size < size) { - exaOffscreenFree(pScrni->pScreen, pGeode->shadowArea); - pGeode->shadowArea = NULL; - } - } - - if (pGeode->shadowArea == NULL) { - pGeode->shadowArea = - exaOffscreenAlloc(pScrni->pScreen, size, 32, TRUE, - LXShadowSave, pGeode); - - if (pGeode->shadowArea == NULL) - return FALSE; - } - - pScrni->fbOffset = pGeode->shadowArea->offset; - } - - pPixmap = pScrni->pScreen->GetScreenPixmap(pScrni->pScreen); - - 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)); - - return TRUE; -} - -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); - - LXSetRotatePitch(pScrni); - - if (pGeode->rotation != RR_Rotate_0) { - - ret = shadowAdd(pScrni->pScreen, pPixmap, LXUpdateFunc, - LXWindowLinear, pGeode->rotation, NULL); - - if (!ret) - goto error; - } - - if (LXAllocShadow(pScrni)) - 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/lx_vga.c b/src/lx_vga.c index 78317e5..2a101df 100644 --- a/src/lx_vga.c +++ b/src/lx_vga.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 Advanced Micro Devices, Inc. + * Copyright (c) 2006-2008 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"), diff --git a/src/lx_video.c b/src/lx_video.c index dbda9f9..8bdb006 100644 --- a/src/lx_video.c +++ b/src/lx_video.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007 Advanced Micro Devices, Inc. +/* Copyright (c) 2007-2008 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 @@ -100,8 +100,7 @@ static XF86ImageRec Images[] = { typedef struct { - void *area; - int offset; + GeodeMemPtr vidmem; RegionRec clip; CARD32 filter; CARD32 colorKey; @@ -131,38 +130,6 @@ LXCopyFromSys(GeodeRec * pGeode, unsigned char *src, unsigned int dst, } static void -LXVideoSave(ScreenPtr pScreen, ExaOffscreenArea * area) -{ - ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; - - GeodePortPrivRec *pPriv = GET_PORT_PRIVATE(pScrni); - - if (area == pPriv->area) - pPriv->area = NULL; - - LXStopVideo(pScrni, (void *)pPriv, TRUE); -} - -static unsigned int -LXAllocateVidMem(ScrnInfoPtr pScrni, void **memp, int size) -{ - 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; -} - -static void LXSetColorkey(ScrnInfoPtr pScrni, GeodePortPrivRec * pPriv) { int red, green, blue; @@ -252,10 +219,10 @@ LXCopyPlanar(ScrnInfoPtr pScrni, int id, unsigned char *buf, size = YDstPitch * height; size += UVDstPitch * height; - pPriv->offset = LXAllocateVidMem(pScrni, &pPriv->area, size); + pPriv->vidmem = GeodeAllocOffscreen(pGeode, size, 4); - if (pPriv->offset == 0) { - ErrorF("Error allocating an offscreen region.\n"); + if (pPriv->vidmem == NULL) { + ErrorF("Could not allocate memory for the video\n"); return FALSE; } @@ -282,19 +249,21 @@ LXCopyPlanar(ScrnInfoPtr pScrni, int id, unsigned char *buf, /* Copy Y */ - LXCopyFromSys(pGeode, buf + YSrcOffset, pPriv->offset + YDstOffset, - YDstPitch, YSrcPitch, lines, pixels); + LXCopyFromSys(pGeode, buf + YSrcOffset, + pPriv->vidmem->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); + LXCopyFromSys(pGeode, buf + USrcOffset, + pPriv->vidmem->offset + UDstOffset, UVDstPitch, UVSrcPitch, lines, + pixels >> 1); - videoScratch.dstOffset = pPriv->offset + YDstOffset; + videoScratch.dstOffset = pPriv->vidmem->offset + YDstOffset; videoScratch.dstPitch = YDstPitch; videoScratch.UVPitch = UVDstPitch; - videoScratch.UDstOffset = pPriv->offset + UDstOffset; - videoScratch.VDstOffset = pPriv->offset + VDstOffset; + videoScratch.UDstOffset = pPriv->vidmem->offset + UDstOffset; + videoScratch.VDstOffset = pPriv->vidmem->offset + VDstOffset; return TRUE; } @@ -315,9 +284,9 @@ LXCopyPacked(ScrnInfoPtr pScrni, int id, unsigned char *buf, lines = ((dstPitch * height) + pGeode->Pitch - 1) / pGeode->Pitch; - pPriv->offset = LXAllocateVidMem(pScrni, &pPriv->area, height * dstPitch); + pPriv->vidmem = GeodeAllocOffscreen(pGeode, lines, 4); - if (pPriv->offset == 0) { + if (pPriv->vidmem == NULL) { ErrorF("Error while allocating an offscreen region.\n"); return FALSE; } @@ -335,7 +304,7 @@ LXCopyPacked(ScrnInfoPtr pScrni, int id, unsigned char *buf, srcOffset = (top * srcPitch) + left; /* Calculate the destination offset */ - dstOffset = pPriv->offset + (top * dstPitch) + left; + dstOffset = pPriv->vidmem->offset + (top * dstPitch) + left; /* Make the copy happen */ @@ -542,7 +511,6 @@ LXPutImage(ScrnInfoPtr pScrni, } pPriv->videoStatus = CLIENT_VIDEO_ON; - pGeode->OverlayON = TRUE; return Success; } @@ -622,15 +590,14 @@ LXStopVideo(ScrnInfoPtr pScrni, pointer data, Bool exit) WRITE_VID32(DF_VID_MISC, val | DF_GAMMA_BYPASS_BOTH); } - if (pPriv->area) { - exaOffscreenFree(pScrni->pScreen, pPriv->area); - pPriv->area = NULL; + if (pPriv->vidmem) { + GeodeFreeOffscreen(pGeode, pPriv->vidmem); + pPriv->vidmem = NULL; } pPriv->videoStatus = 0; /* Eh? */ - pGeode->OverlayON = FALSE; } else if (pPriv->videoStatus & CLIENT_VIDEO_ON) { pPriv->videoStatus |= OFF_TIMER; pPriv->offTime = currentTime.milliseconds + OFF_DELAY; @@ -684,9 +651,10 @@ LXVidBlockHandler(int i, pointer blockData, pointer pTimeout, } } else { if (pPriv->freeTime < now) { - if (pPriv->area) { - exaOffscreenFree(pScrni->pScreen, pPriv->area); - pPriv->area = NULL; + + if (pPriv->vidmem) { + GeodeFreeOffscreen(pGeode, pPriv->vidmem); + pPriv->vidmem = NULL; } pPriv->videoStatus = 0; @@ -741,7 +709,7 @@ LXSetupImageVideo(ScreenPtr pScrn) adapt->QueryImageAttributes = GeodeQueryImageAttributes; pPriv->filter = 0; - pPriv->colorKey = pGeode->videoKey; + pPriv->colorKey = 0; pPriv->colorKeyMode = 0; pPriv->videoStatus = 0; pPriv->pwidth = 0; @@ -767,8 +735,7 @@ LXSetupImageVideo(ScreenPtr pScrn) struct OffscreenPrivRec { - void *area; - int offset; + GeodeMemPtr vidmem; Bool isOn; }; @@ -825,9 +792,8 @@ LXAllocateSurface(ScrnInfoPtr pScrni, int id, unsigned short w, unsigned short h, XF86SurfacePtr surface) { GeodeRec *pGeode = GEODEPTR(pScrni); - void *area = NULL; int pitch, lines; - unsigned offset; + GeodeMemPtr vidmem; struct OffscreenPrivRec *pPriv; if (w > 1024 || h > 1024) @@ -839,9 +805,9 @@ LXAllocateSurface(ScrnInfoPtr pScrni, int id, unsigned short w, pitch = ((w << 1) + 15) & ~15; lines = ((pitch * h) + (pGeode->Pitch - 1)) / pGeode->Pitch; - offset = LXAllocateVidMem(pScrni, &area, lines); + vidmem = GeodeAllocOffscreen(pGeode, lines, 4); - if (offset == 0) { + if (vidmem == NULL) { ErrorF("Error while allocating an offscreen region.\n"); return BadAlloc; } @@ -857,15 +823,14 @@ LXAllocateSurface(ScrnInfoPtr pScrni, int id, unsigned short w, if (pPriv && surface->pitches && surface->offsets) { - pPriv->area = area; - pPriv->offset = offset; + pPriv->vidmem = vidmem; pPriv->isOn = FALSE; surface->pScrn = pScrni; surface->id = id; surface->pitches[0] = pitch; - surface->offsets[0] = offset; + surface->offsets[0] = vidmem->offset; surface->devPrivate.ptr = (pointer) pPriv; return Success; @@ -877,8 +842,8 @@ LXAllocateSurface(ScrnInfoPtr pScrni, int id, unsigned short w, if (surface->pitches) xfree(surface->pitches); - if (area) - exaOffscreenFree(pScrni->pScreen, area); + if (vidmem) + GeodeFreeOffscreen(pGeode, vidmem); return BadAlloc; } @@ -899,13 +864,14 @@ LXFreeSurface(XF86SurfacePtr surface) struct OffscreenPrivRec *pPriv = (struct OffscreenPrivRec *) surface->devPrivate.ptr; ScrnInfoPtr pScrni = surface->pScrn; + GeodeRec *pGeode = GEODEPTR(pScrni); if (pPriv->isOn) LXStopSurface(surface); - if (pPriv->area) { - exaOffscreenFree(pScrni->pScreen, pPriv->area); - pPriv->area = NULL; + if (pPriv->vidmem) { + GeodeFreeOffscreen(pGeode, pPriv->vidmem); + pPriv->vidmem = NULL; } xfree(surface->pitches); |