1/* $OpenBSD: wsfb_driver.c,v 1.18 2003/04/02 16:42:13 jason Exp $ */
2/* $NetBSD: igs.h,v 1.8 2022/07/15 04:30:05 mrg Exp $ */
3/*
4 * Copyright (c) 2001 Matthieu Herrb
5 *		 2009 Michael Lorenz
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 *    - Redistributions of source code must retain the above copyright
13 *      notice, this list of conditions and the following disclaimer.
14 *    - Redistributions in binary form must reproduce the above
15 *      copyright notice, this list of conditions and the following
16 *      disclaimer in the documentation and/or other materials provided
17 *      with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34/*
35 * Based on fbdev.c written by:
36 *
37 * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
38 *	     Michel Dänzer, <michdaen@iiic.ethz.ch>
39 */
40
41#include <fcntl.h>
42#include <sys/types.h>
43#include <sys/time.h>
44#include <dev/wscons/wsconsio.h>
45
46/* all driver need this */
47#include "xorg-server.h"
48#include "xf86.h"
49#include "xf86_OSproc.h"
50#include "compiler.h"
51
52#if ABI_VIDEODRV_VERSION < SET_ABI_VERSION(25, 2)
53#include "xf86RamDac.h"
54#else
55#include "xf86Cursor.h"
56#endif
57#include "exa.h"
58
59#ifndef IGS_H
60#define IGS_H
61
62/* private data */
63typedef struct {
64	int			fd; /* file descriptor of open device */
65	struct wsdisplay_fbinfo info; /* frame buffer characteristics */
66	int			linebytes; /* number of bytes per row */
67	volatile uint8_t	*reg;
68	unsigned char*		fbstart;
69	unsigned char*		fbmem;
70	size_t			fbmem_len;
71	unsigned long		fb_paddr;
72	Bool			shadowFB;
73	Bool			HWCursor;
74	Bool			no_accel;
75	CloseScreenProcPtr	CloseScreen;
76	CreateScreenResourcesProcPtr CreateScreenResources;
77	EntityInfoPtr		pEnt;
78
79	struct wsdisplay_cursor cursor;
80	int			maskoffset;
81	int			Chipset;
82	xf86CursorInfoPtr	CursorInfoRec;
83	ExaDriverPtr 		pExa;
84	int			shift, srcoff, srcpitch;
85	uint32_t		cmd;
86#ifdef XFreeXDGA
87	/* DGA info */
88	DGAModePtr		pDGAMode;
89	int			nDGAMode;
90#endif
91	OptionInfoPtr		Options;
92	uint8_t			mapfmt;
93} IgsRec, *IgsPtr;
94
95#define IGSPTR(p) ((IgsPtr)((p)->driverPrivate))
96
97Bool IgsSetupCursor(ScreenPtr);
98
99/* register definitions, from NetBSD's igsfbreg.h */
100
101/* right now we only care about the extended VGA registers */
102#define IGS_EXT_IDX		0x3ce
103#define IGS_EXT_PORT		0x3cf
104
105/* [3..0] -> [19..16] of start addr if IGS_EXT_START_ADDR_ON is set */
106#define   IGS_EXT_START_ADDR		0x10
107#define     IGS_EXT_START_ADDR_ON		0x10
108
109/*
110 * COPREN   - enable direct access to coprocessor registers
111 * COPASELB - select IGS_COP_BASE_B for COP address
112 */
113#define   IGS_EXT_BIU_MISC_CTL		0x33
114#define     IGS_EXT_BIU_LINEAREN		0x01
115#define     IGS_EXT_BIU_LIN2MEM			0x02
116#define     IGS_EXT_BIU_COPREN			0x04
117#define     IGS_EXT_BIU_COPASELB		0x08
118#define     IGS_EXT_BIU_SEGON			0x10
119#define     IGS_EXT_BIU_SEG2MEM			0x20
120
121/*
122 * Linear Address registers
123 *   PCI: don't write directly, just use nomral PCI configuration
124 *   ISA: only bits [23..20] are programmable, the rest MBZ
125 */
126#define   IGS_EXT_LINA_LO		0x34	/* [3..0] -> [23..20] */
127#define   IGS_EXT_LINA_HI		0x35	/* [7..0] -> [31..24] */
128
129/* Hardware cursor on-screen location and hot spot */
130#define   IGS_EXT_SPRITE_HSTART_LO	0x50
131#define   IGS_EXT_SPRITE_HSTART_HI	0x51	/* bits [2..0] */
132#define   IGS_EXT_SPRITE_HPRESET	0x52	/* bits [5..0] */
133
134#define   IGS_EXT_SPRITE_VSTART_LO	0x53
135#define   IGS_EXT_SPRITE_VSTART_HI	0x54	/* bits [2..0] */
136#define   IGS_EXT_SPRITE_VPRESET	0x55	/* bits [5..0] */
137
138/* Hardware cursor control */
139#define   IGS_EXT_SPRITE_CTL		0x56
140#define     IGS_EXT_SPRITE_VISIBLE		0x01
141#define     IGS_EXT_SPRITE_64x64		0x02
142#define     IGS_EXT_SPRITE_DAC_PEL		0x04
143	  /* bits unrelated to sprite control */
144#define     IGS_EXT_COP_RESET			0x08
145
146/* chip ID */
147#define   IGS_EXT_CHIP_ID0		0x91 /* 0xa4 for 2010 */
148#define   IGS_EXT_CHIP_ID1		0x92 /* 0x08 for 2010 */
149#define   IGS_EXT_CHIP_REV		0x92
150/* DAC registers */
151
152/* IGS_EXT_SPRITE_CTL/IGS_EXT_SPRITE_DAC_PEL (3cf/56[2]) == 0 */
153#define IGS_PEL_MASK		IGS_REG_(0x3c6)
154
155/* IGS_EXT_SPRITE_CTL/IGS_EXT_SPRITE_DAC_PEL 3cf/56[2] == 1 */
156#define IGS_DAC_CMD		IGS_REG_(0x3c6)
157
158
159/*
160 * Palette Read/Write: write palette index to the index port.
161 * Read/write R/G/B in three consecutive accesses to data port.
162 * After third access to data the index is autoincremented and you can
163 * proceed with reading/writing data port for the next entry.
164 *
165 * When IGS_EXT_SPRITE_DAC_PEL bit in sprite control is set, these
166 * registers are used to access sprite (i.e. cursor) 2-color palette.
167 * (NB: apparently, in this mode index autoincrement doesn't work).
168 */
169#define IGS_DAC_PEL_READ_IDX	IGS_REG_(0x3c7)
170#define IGS_DAC_PEL_WRITE_IDX	IGS_REG_(0x3c8)
171#define IGS_DAC_PEL_DATA	IGS_REG_(0x3c9)
172
173/* blitter registers */
174
175#define IGS_MEM_MMIO_SELECT	0x00800000 /* memory mapped i/o */
176#define IGS_MEM_BE_SELECT	0x00400000 /* endian select */
177
178#define IGS_COP_BASE_A	0xaf000		/* COPASELB == 0 */
179#define IGS_COP_BASE_B	0xbf000		/* COPASELB == 1 */
180
181/*
182 * NB: Loaded width values should be 1 less than the actual width!
183 */
184
185/*
186 * Coprocessor control.
187 */
188#define IGS_COP_CTL_REG		0x011
189#define   IGS_COP_CTL_HBRDYZ		0x01
190#define   IGS_COP_CTL_HFEMPTZ		0x02
191#define   IGS_COP_CTL_CMDFF		0x04
192#define   IGS_COP_CTL_SOP		0x08 /* rw */
193#define   IGS_COP_CTL_OPS		0x10
194#define   IGS_COP_CTL_TER		0x20 /* rw */
195#define   IGS_COP_CTL_HBACKZ		0x40
196#define   IGS_COP_CTL_BUSY		0x80
197
198
199/*
200 * Source(s) and destination widths.
201 * 16 bit registers.  Only bits [11..0] are used.
202 */
203#define IGS_COP_SRC_MAP_WIDTH_REG  0x018
204#define IGS_COP_SRC2_MAP_WIDTH_REG 0x118
205#define IGS_COP_DST_MAP_WIDTH_REG  0x218
206
207
208/*
209 * Bitmap depth.
210 */
211#define IGS_COP_MAP_FMT_REG	0x01c
212#define   IGS_COP_MAP_8BPP		0x00
213#define   IGS_COP_MAP_16BPP		0x01
214#define   IGS_COP_MAP_24BPP		0x02
215#define   IGS_COP_MAP_32BPP		0x03
216
217
218/*
219 * Binary operations are defined below.  S - source, D - destination,
220 * N - not; a - and, o - or, x - xor.
221 *
222 * For ternary operations, foreground mix function is one of 256
223 * ternary raster operations defined by Win32 API; background mix is
224 * ignored.
225 */
226#define IGS_COP_FG_MIX_REG	0x048
227#define IGS_COP_BG_MIX_REG	0x049
228
229#define   IGS_COP_MIX_0			0x0
230#define   IGS_COP_MIX_SaD		0x1
231#define   IGS_COP_MIX_SaND		0x2
232#define   IGS_COP_MIX_S			0x3
233#define   IGS_COP_MIX_NSaD		0x4
234#define   IGS_COP_MIX_D			0x5
235#define   IGS_COP_MIX_SxD		0x6
236#define   IGS_COP_MIX_SoD		0x7
237#define   IGS_COP_MIX_NSaND		0x8
238#define   IGS_COP_MIX_SxND		0x9
239#define   IGS_COP_MIX_ND		0xa
240#define   IGS_COP_MIX_SoND		0xb
241#define   IGS_COP_MIX_NS		0xc
242#define   IGS_COP_MIX_NSoD		0xd
243#define   IGS_COP_MIX_NSoND		0xe
244#define   IGS_COP_MIX_1			0xf
245
246#define   IGS_PLANE_MASK_REG		0x50
247/*
248 * Foreground/background colours (24 bit).
249 * Selected by bits in IGS_COP_PIXEL_OP_3_REG.
250 */
251#define IGS_COP_FG_REG		0x058
252#define IGS_COP_BG_REG		0x05C
253
254
255/*
256 * Horizontal/vertical dimensions of pixel blit function.
257 * 16 bit registers.  Only [11..0] are used.
258 */
259#define IGS_COP_WIDTH_REG	0x060
260#define IGS_COP_HEIGHT_REG	0x062
261
262
263/*
264 * Only bits [21..0] are used.
265 */
266#define IGS_COP_SRC_BASE_REG	0x070 /* only for 24bpp Src Color Tiling */
267#define IGS_COP_SRC_START_REG	0x170
268#define IGS_COP_SRC2_START_REG	0x174
269#define IGS_COP_DST_START_REG	0x178
270
271/*
272 * Destination phase angle for 24bpp.
273 */
274#define IGS_COP_DST_X_PHASE_REG	0x078
275#define   IGS_COP_DST_X_PHASE_MASK	0x07
276
277
278/*
279 * Pixel operation: Direction and draw mode.
280 * When an octant bit is set, that axis is traversed backwards.
281 */
282#define IGS_COP_PIXEL_OP_REG	0x07c
283
284#define   IGS_COP_OCTANT_Y_NEG		0x00000002 /* 0: top down, 1: bottom up */
285#define   IGS_COP_OCTANT_X_NEG		0x00000004 /* 0: l2r, 1: r2l */
286
287#define   IGS_COP_DRAW_ALL		0x00000000
288#define   IGS_COP_DRAW_FIRST_NULL	0x00000010
289#define   IGS_COP_DRAW_LAST_NULL	0x00000020
290
291
292/*
293 * Pixel operation: Pattern operation.
294 */
295
296#define   IGS_COP_PPM_TEXT		0x00001000
297#define   IGS_COP_PPM_TILE		0x00002000
298#define   IGS_COP_PPM_LINE		0x00003000
299#define   IGS_COP_PPM_TRANSPARENT	0x00004000/* "or" with one of the above */
300
301#define   IGS_COP_PPM_FIXED_FG		0x00008000
302#define   IGS_COP_PPM_SRC_COLOR_TILE	0x00009000
303
304
305/*
306 * Pixel operation: Host CPU access (host blit) to graphics engine.
307 */
308#define   IGS_COP_HBLTR			0x00010000 /* enable read from engine */
309#define   IGS_COP_HBLTW			0x00020000 /* enable write to engine  */
310
311
312/*
313 * Pixel operation: Operation function of graphic engine.
314 */
315#define   IGS_COP_OP_STROKE		0x04000000 /* short stroke */
316#define   IGS_COP_OP_LINE		0x05000000 /* bresenham line draw */
317#define   IGS_COP_OP_PXBLT		0x08000000 /* pixel blit */
318#define   IGS_COP_OP_PXBLT_INV		0x09000000 /* invert pixel blit */
319#define   IGS_COP_OP_PXBLT_3		0x0a000000 /* ternary pixel blit */
320
321/* select fg/bg source: 0 - fg/bg color reg, 1 - src1 map */
322#define   IGS_COP_OP_FG_FROM_SRC	0x20000000
323#define   IGS_COP_OP_BG_FROM_SRC	0x80000000
324
325#define IGS_CLOCK_REF	14318 /*24576*/	/* KHz */
326
327#define IGS_SCALE(p)	((p) ? (2 * (p)) : 1)
328
329#define IGS_CLOCK(m,n,p) \
330	((IGS_CLOCK_REF * ((m) + 1)) / (((n) + 1) * IGS_SCALE(p)))
331
332#define IGS_MAX_CLOCK	260000
333
334#define IGS_MIN_VCO	115000
335
336static __inline uint8_t
337igs_idx_read(u_int idxport, uint8_t idx)
338{
339	outb(idxport, idx);
340	return inb(idxport + 1);
341}
342
343static __inline void
344igs_idx_write(u_int idxport, uint8_t idx, uint8_t val)
345{
346	outb(idxport, idx);
347	outb(idxport + 1, val);
348}
349
350/* sugar for extended registers */
351#define igs_ext_read(x)	(igs_idx_read(IGS_EXT_IDX,(x)))
352#define igs_ext_write(x, v)	(igs_idx_write((IGS_EXT_IDX,(x),(v)))
353
354Bool IgsInitAccel(ScreenPtr);
355
356#endif
357