smi.h revision 5788ca14
1/* Header:   //Mercury/Projects/archives/XFree86/4.0/smi.h-arc   1.51   29 Nov 2000 17:45:16   Frido  $ */
2
3/*
4Copyright (C) 1994-1999 The XFree86 Project, Inc.  All Rights Reserved.
5Copyright (C) 2000 Silicon Motion, Inc.  All Rights Reserved.
6
7Permission is hereby granted, free of charge, to any person obtaining a copy of
8this software and associated documentation files (the "Software"), to deal in
9the Software without restriction, including without limitation the rights to
10use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11of the Software, and to permit persons to whom the Software is furnished to do
12so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
19NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
20XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24Except as contained in this notice, the names of the XFree86 Project and
25Silicon Motion shall not be used in advertising or otherwise to promote the
26sale, use or other dealings in this Software without prior written
27authorization from the XFree86 Project and Silicon Motion.
28*/
29
30#ifndef _SMI_H
31#define _SMI_H
32
33#include "smi_pcirename.h"
34
35#include <string.h>
36#include <stdio.h>
37
38#include "xf86.h"
39#include "xf86_OSproc.h"
40#include "xf86PciInfo.h"
41#include "xf86Pci.h"
42#include "xf86Cursor.h"
43#include "vgaHW.h"
44
45#include "compiler.h"
46
47#include "mipointer.h"
48#include "micmap.h"
49
50#include "fb.h"
51
52#ifdef HAVE_XAA_H
53#include "xaa.h"
54#endif
55#include "xf86fbman.h"
56#include "exa.h"
57#include "xf86cmap.h"
58#include "xf86i2c.h"
59
60#include "xf86int10.h"
61#include "vbe.h"
62
63#include "xf86xv.h"
64#include <X11/extensions/Xv.h>
65
66#include "compat-api.h"
67/******************************************************************************/
68/*			D E F I N I T I O N S				      */
69/******************************************************************************/
70
71#ifndef SMI_DEBUG
72#define SMI_DEBUG		0
73#endif
74
75#define SMI_USE_IMAGE_WRITES	0
76#define SMI_USE_VIDEO		1
77#define SMI_USE_CAPTURE		0
78#define SMI501_CLI_DEBUG	0
79
80/*
81 *   Leaving attempt implementation of an argb cursor using alpha plane
82 * for the smi 501/502 under this ifdef for now. Maybe it will be fixed
83 * in a subsequent hardware revision.
84 *   The problem is that the alpha plane will only work (that is, become
85 * visible) if alpha_plane_tl is set to top:=0 and left:=0.
86 *   Also, if alpha_plane_br does not match panel dimensions, the alpha
87 * plane will be displayed tilled in the "first" row, with corruption on
88 * on all odd columns.
89 *   Since setting the alpha fb_address works, to implement an argb cursor
90 * using the alpha plane, with the current hardware bugs, it would be
91 * required to:
92 *	o allocate an offscreen area of pSmi->lcdWidth * pSmi->lcdHeight * 2
93 *	o set statically tl/tr to 0,0,pSmi->lcdWidth-1,pSmi->lcdHeight-1
94 *	o use alpha format 3 (argb 4:4:4:4), or alternatively format 1
95 *	  (rgb 5:6:5), and in the last case, a global 50% alpha is the
96 *	  best bet, and for the argb cursors being used at the time of this
97 *	  writing, they look correct, while 100% opaque looks wrong.
98 *	o when positioning the pointer, first erase it from the offscreen
99 *	  area, then repaint it at the proper offset in the alpha offscreen
100 *	  area.
101 *  .... argb software cursor works way better
102 *   (There are some other alternatives, like using 8 bits indexed mode,
103 * but when using a global alpha value, instead of per pixel, most argb
104 * cursors will not look correctly, regardless of the alpha value, that
105 * should be from 50 to 100% transparency).
106 *   But still there would be the problem of memory requiring a 128 bit
107 * alignment, what would require either moving the image in the memory,
108 * and/or some trick with the vsync pixel panning.
109 *
110 *   Until the alpha layer is corrected in some newer revision (or removed?),
111 * it could be used as something like an alternate crt, that happens to be
112 * on top of the panel (and has 16 transparency levels).
113 */
114#define SMI_CURSOR_ALPHA_PLANE	0
115
116/******************************************************************************/
117/*			S T R U C T U R E S				      */
118/******************************************************************************/
119
120/* Driver data structure; this should contain all needed info for a mode */
121typedef struct
122{
123    CARD16 mode;
124
125    CARD8 SR17, SR18;
126    CARD8 SR20, SR21, SR22, SR23, SR24;
127    CARD8 SR30, SR31, SR32, SR34;
128    CARD8 SR40, SR41, SR42, SR43, SR44, SR45, SR48, SR49, SR4A, SR4B, SR4C;
129    CARD8 SR50, SR51, SR52, SR53, SR54, SR55, SR56, SR57, SR5A;
130    CARD8 SR66, SR68, SR69, SR6A, SR6B, SR6C, SR6D, SR6E, SR6F;
131    CARD8 SR81, SRA0;
132
133    CARD8 CR30, CR33, CR33_2, CR3A;
134    CARD8 CR40[14], CR40_2[14];
135    CARD8 CR90[15], CR9F, CR9F_2;
136    CARD8 CRA0[14];
137
138    CARD8	smiDACMask, smiDacRegs[256][3];
139    CARD8	smiFont[8192];
140
141    CARD32	DPR10, DPR1C, DPR20, DPR24, DPR28, DPR2C, DPR30, DPR3C, DPR40,
142		DPR44;
143    CARD32	VPR00, VPR0C, VPR10;
144    CARD32	CPR00;
145    CARD32	FPR00_, FPR0C_, FPR10_;
146} SMIRegRec, *SMIRegPtr;
147
148/* Global PDEV structure. */
149typedef struct
150{
151    int			Bpp;		/* Bytes per pixel */
152    int			MCLK;		/* Memory Clock  */
153    int			MXCLK;		/* MSOC Clock for local sdram */
154    ClockRange		clockRange;	/* Allowed pixel clock range */
155    CloseScreenProcPtr	CloseScreen;	/* Pointer used to save wrapped
156					   CloseScreen function */
157
158    I2CBusPtr		I2C;		/* Pointer into I2C module */
159    xf86Int10InfoPtr	pInt10;		/* Pointer to INT10 module */
160    vbeInfoPtr          pVbe;           /* Pointer to VBE module */
161
162    pciVideoPtr		PciInfo;	/* PCI info vars */
163#ifndef XSERVER_LIBPCIACCESS
164    PCITAG		PciTag;
165#endif
166    int			Chipset;	/* Chip info, set using PCI
167					   above */
168    int			ChipRev;
169
170    OptionInfoPtr	Options;
171    Bool		Dualhead;
172
173    /* Don't attempt to program a video mode. Use kernel framebuffer
174     * mode instead. */
175    Bool		UseFBDev;
176
177    /* CSC video uses color space conversion to render video directly to
178     * the framebuffer, without using an overlay. */
179    Bool		CSCVideo;
180
181    Bool		PCIBurst;	/* Enable PCI burst mode for
182					   reads? */
183    Bool		PCIRetry;	/* Enable PCI retries */
184    Bool		HwCursor;	/* hardware cursor enabled */
185
186    CARD8		DACmask;
187    int			vgaCRIndex, vgaCRReg;
188    Bool		PrimaryVidMapped;	/* Flag indicating if
189						   vgaHWMapMem was used
190						   successfully for
191						   this screen */
192    Bool		ModeStructInit;	/* Flag indicating ModeReg has
193					   been duped from console
194					   state */
195
196    /* Hardware state */
197    void		(*Save)(ScrnInfoPtr pScrn); /* Function used to save the
198						       current register state */
199    CARD8		SR18Value;	/* PDR#521: original SR18
200					   value */
201    CARD8		SR21Value;	/* PDR#521: original SR21
202					   value */
203    void		*save;		/* console saved mode
204					   registers */
205    void		*mode;		/* XServer video state mode
206					   registers */
207
208    /* Memory layout */
209    int			videoRAMBytes;	/* In units as noted, set in
210					   PreInit  */
211    int			videoRAMKBytes;	/* In units as noted, set in
212					   PreInit */
213    unsigned char *	MapBase;	/* Base of mapped memory */
214    int			MapSize;	/* Size of mapped memory */
215    CARD8 *		DPRBase;	/* Base of DPR registers */
216    CARD8 *		VPRBase;	/* Base of VPR registers */
217    CARD8 *		CPRBase;	/* Base of CPR registers */
218    CARD8 *		FPRBase;    /* Base of FPR registers - for 0730 chipset */
219    CARD8 *		DCRBase;		/* Base of DCR registers - for 0501 chipset */
220    CARD8 *		SCRBase;        /* Base of SCR registers - for 0501 chipset */
221    CARD8 *		DataPortBase;	/* Base of data port */
222    int			DataPortSize;	/* Size of data port */
223    CARD8 *		IOBase;		/* Base of MMIO VGA ports */
224    IOADDRESS		PIOBase;	/* Base of I/O ports */
225    unsigned char *	FBBase;		/* Base of FB */
226    CARD32		fbMapOffset;    /* offset for fb mapping */
227    CARD32		FBOffset;	/* Current visual FB starting
228					   location */
229    CARD32		FBCursorOffset;	/* Cursor storage location */
230    CARD32		FBReserved;	/* Reserved memory in frame
231					   buffer */
232
233    /* accel additions */
234    CARD32		AccelCmd;	/* Value for DPR0C */
235    Bool		NoAccel;	/* Disable Acceleration */
236    CARD32		ScissorsLeft;	/* Left/top of current
237					   scissors */
238    CARD32		ScissorsRight;	/* Right/bottom of current
239					   scissors */
240    Bool		ClipTurnedOn;	/* Clipping was turned on by
241					   the previous command */
242    int			GEResetCnt;	/* Limit the number of errors
243					   printed using a counter */
244
245    Bool		useBIOS;	/* Use BIOS for mode sets */
246#ifdef HAVE_XAA_H
247    XAAInfoRecPtr	XAAInfoRec;	/* XAA info Rec */
248#endif
249
250    /* EXA */
251    ExaDriverPtr	EXADriverPtr;
252    Bool		useEXA;		/* enable exa acceleration */
253    ExaOffscreenArea*	fbArea;		/* EXA offscreen area used
254					   as framebuffer */
255    PictTransformPtr	renderTransform;
256
257    /* DPMS */
258    int			CurrentDPMS;	/* Current DPMS state */
259
260    /* Panel information */
261    Bool		lcd;		/* LCD active, 1=DSTN, 2=TFT */
262    int			lcdWidth;	/* LCD width */
263    int			lcdHeight;	/* LCD height */
264
265    /* XvExtension */
266    int			videoKey;	/* Video chroma key */
267    Bool		ByteSwap;	/* Byte swap for ZV port */
268    Bool		interlaced;	/* True: Interlaced Video */
269    XF86VideoAdaptorPtr	ptrAdaptor;	/* Pointer to VideoAdapter
270					   structure */
271    void (*BlockHandler)(int i, pointer blockData, pointer pTimeout,
272					 pointer pReadMask);
273#if SMI501_CLI_DEBUG
274    /* SMI 501/502 Command List Interpreter */
275    Bool		 batch_active;
276    int64_t		*batch_handle;	/* Virtual address */
277    int			 batch_offset;	/* Physical smi 501 address */
278    int			 batch_length;	/* Length in 8 byte units */
279    int			 batch_finish;	/* Last finish command offset */
280    int			 batch_index;
281#endif
282} SMIRec, *SMIPtr;
283
284#define SMIPTR(p) ((SMIPtr)((p)->driverPrivate))
285
286/******************************************************************************/
287/*			M A C R O S					      */
288/******************************************************************************/
289
290#if SMI_DEBUG
291extern int smi_indent;
292# define VERBLEV	1
293# define ENTER()	xf86ErrorFVerb(VERBLEV, "%*c %s\n",\
294				       smi_indent++, '>', __FUNCTION__)
295# define LEAVE(...)							\
296    do {								\
297	xf86ErrorFVerb(VERBLEV, "%*c %s\n",				\
298		       --smi_indent, '<', __FUNCTION__);		\
299	return __VA_ARGS__;						\
300    } while (0)
301# define DEBUG(...)	xf86ErrorFVerb(VERBLEV, __VA_ARGS__)
302#else
303# define VERBLEV	4
304# define ENTER()	/**/
305# define LEAVE(...)	return __VA_ARGS__
306# define DEBUG(...)	/**/
307#endif
308
309/* Some Silicon Motion structs & registers */
310#include "regsmi.h"
311
312#if !defined (MetroLink) && !defined (VertDebug)
313#define VerticalRetraceWait()						\
314do									\
315{									\
316    if (VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x17) & 0x80)		\
317    {									\
318	while ((VGAIN8(pSmi, vgaIOBase + 0x0A) & 0x08) == 0x00);	\
319	while ((VGAIN8(pSmi, vgaIOBase + 0x0A) & 0x08) == 0x08);	\
320	while ((VGAIN8(pSmi, vgaIOBase + 0x0A) & 0x08) == 0x00);	\
321    }									\
322} while (0)
323#else
324#define SPIN_LIMIT 1000000
325#define VerticalRetraceWait()						\
326do									\
327{									\
328    if (VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x17) & 0x80)		\
329    {									\
330	volatile unsigned long _spin_me;				\
331	for (_spin_me = SPIN_LIMIT;					\
332	     ((VGAIN8(pSmi, vgaIOBase + 0x0A) & 0x08) == 0x00) && 	\
333	     _spin_me;							\
334	     _spin_me--);						\
335	if (!_spin_me)							\
336	    ErrorF("smi: warning: VerticalRetraceWait timed out.\n");	\
337	for (_spin_me = SPIN_LIMIT;					\
338	     ((VGAIN8(pSmi, vgaIOBase + 0x0A) & 0x08) == 0x08) && 	\
339	     _spin_me;							\
340	     _spin_me--);						\
341	if (!_spin_me)							\
342	    ErrorF("smi: warning: VerticalRetraceWait timed out.\n");	\
343	for (_spin_me = SPIN_LIMIT;					\
344	     ((VGAIN8(pSmi, vgaIOBase + 0x0A) & 0x08) == 0x00) && 	\
345	     _spin_me;							\
346	     _spin_me--);						\
347	if (!_spin_me)							\
348	    ErrorF("smi: warning: VerticalRetraceWait timed out.\n");	\
349	}								\
350} while (0)
351#endif
352
353/******************************************************************************/
354/*			F U N C T I O N   P R O T O T Y P E S		      */
355/******************************************************************************/
356
357/* smi_dac.c */
358void SMI_CommonCalcClock(int scrnIndex, long freq, int min_m, int min_n1,
359			 int max_n1, int min_n2, int max_n2, long freq_min,
360			 long freq_max, unsigned char * mdiv,
361			 unsigned char * ndiv);
362
363/* smi_i2c */
364Bool SMI_I2CInit(ScrnInfoPtr pScrn);
365
366/* smi_accel.c */
367void SMI_AccelSync(ScrnInfoPtr pScrn);
368void SMI_GEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file);
369void SMI_EngineReset(ScrnInfoPtr);
370void SMI_SetClippingRectangle(ScrnInfoPtr, int, int, int, int);
371void SMI_DisableClipping(ScrnInfoPtr);
372CARD32 SMI_DEDataFormat(int bpp);
373
374/* smi_xaa.c */
375Bool SMI_XAAInit(ScreenPtr pScrn);
376
377/* smi_exa.c */
378Bool SMI_EXAInit(ScreenPtr pScrn);
379
380/* smi_hwcurs.c */
381Bool SMI_HWCursorInit(ScreenPtr pScrn);
382
383/* smi_driver.c */
384Bool SMI_MapMem(ScrnInfoPtr pScrn);
385void SMI_UnmapMem(ScrnInfoPtr pScrn);
386void SMI_AdjustFrame(int scrnIndex, int x, int y, int flags);
387Bool SMI_SwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
388void SMI_LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies,
389		     LOCO *colors, VisualPtr pVisual);
390xf86MonPtr SMI_ddc1(ScrnInfoPtr pScrn);
391void SMI_PrintRegs(ScrnInfoPtr pScrn);
392
393/* smi_video.c */
394void SMI_InitVideo(ScreenPtr pScreen);
395CARD32 SMI_AllocateMemory(ScrnInfoPtr pScrn, void **mem_struct, int size);
396void SMI_FreeMemory(ScrnInfoPtr pScrn, void *mem_struct);
397
398
399#endif  /*_SMI_H*/
400