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