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