blob: 75d5a31bd7b013a695c24049a071bdd29b70b8b1 [file] [log] [blame]
wdenkc6097192002-11-03 00:24:07 +00001/*
2 * (C) Copyright 1997-2002 ELTEC Elektronik AG
3 * Frank Gottschling <fgottschling@eltec.de>
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24/*
25 * smiLynxEM.c
26 *
27 * Silicon Motion graphic interface for sm810/sm710/sm712 accelerator
28 *
29 * modification history
30 * --------------------
31 * 04-18-2002 Rewritten for U-Boot <fgottschling@eltec.de>.
32 *
33 */
34
35#include <common.h>
36
37#if defined(CONFIG_VIDEO_SMI_LYNXEM)
38
39#include <pci.h>
40#include <video_fb.h>
41
42/*
43 * Export Graphic Device
44 */
45GraphicDevice smi;
46
47/*
48 * SMI 710/712 have 4MB internal RAM; SMI 810 2MB internal + 2MB external
49 */
50#define VIDEO_MEM_SIZE 0x400000
51
52/*
53 * Supported video modes for SMI Lynx E/EM/EM+
54 */
55#define VIDEO_MODES 7
56#define DUAL_800_600 0 /* SMI710:VGA1:75Hz (pitch=1600) */
57 /* VGA2:60/120Hz (pitch=1600) */
58 /* SMI810:VGA1:75Hz (pitch=1600) */
59 /* VGA2:75Hz (pitch=1600) */
60#define DUAL_1024_768 1 /* VGA1:75Hz VGA2:73Hz (pitch=2048) */
61#define SINGLE_800_600 2 /* VGA1:75Hz (pitch=800) */
62#define SINGLE_1024_768 3 /* VGA1:75Hz (pitch=1024) */
63#define SINGLE_1280_1024 4 /* VGA1:75Hz (pitch=1280) */
64#define TV_MODE_CCIR 5 /* VGA1:50Hz (h=720;v=576;pitch=720) */
65#define TV_MODE_EIA 6 /* VGA1:60Hz (h=720;v=484;pitch=720) */
66
67
68/*
69 * ISA mapped regs
70 */
71#define SMI_INDX_C4 (pGD->isaBase + 0x03c4) /* index reg */
72#define SMI_DATA_C5 (pGD->isaBase + 0x03c5) /* data reg */
73#define SMI_INDX_D4 (pGD->isaBase + 0x03d4) /* index reg */
74#define SMI_DATA_D5 (pGD->isaBase + 0x03d5) /* data reg */
75#define SMI_INDX_CE (pGD->isaBase + 0x03ce) /* index reg */
76#define SMI_DATA_CF (pGD->isaBase + 0x03cf) /* data reg */
77#define SMI_LOCK_REG (pGD->isaBase + 0x03c3) /* unlock/lock ext crt reg */
78#define SMI_MISC_REG (pGD->isaBase + 0x03c2) /* misc reg */
79#define SMI_LUT_MASK (pGD->isaBase + 0x03c6) /* lut mask reg */
80#define SMI_LUT_START (pGD->isaBase + 0x03c8) /* lut start index */
81#define SMI_LUT_RGB (pGD->isaBase + 0x03c9) /* lut colors auto incr.*/
82
83
84/*
85 * Video processor control
86*/
87typedef struct {
88 unsigned int control;
89 unsigned int colorKey;
90 unsigned int colorKeyMask;
91 unsigned int start;
92 unsigned short offset;
93 unsigned short width;
94 unsigned int fifoPrio;
95 unsigned int fifoERL;
96 unsigned int YUVtoRGB;
97} SmiVideoProc;
98
99/*
100 * Video window control
101 */
102typedef struct {
103 unsigned short top;
104 unsigned short left;
105 unsigned short bottom;
106 unsigned short right;
107 unsigned int srcStart;
108 unsigned short width;
109 unsigned short offset;
110 unsigned char hStretch;
111 unsigned char vStretch;
112} SmiVideoWin;
113
114/*
115 * Capture port control
116 */
117typedef struct {
118 unsigned int control;
119 unsigned short topClip;
120 unsigned short leftClip;
121 unsigned short srcHeight;
122 unsigned short srcWidth;
123 unsigned int srcBufStart1;
124 unsigned int srcBufStart2;
125 unsigned short srcOffset;
126 unsigned short fifoControl;
127} SmiCapturePort;
128
129
130
131/*
132 * Register values for common video modes
133 */
134static char SMI_SCR[22] = {
135 /* all modes */
136 0x10, 0xff, 0x11, 0xff, 0x12, 0xff, 0x13, 0xff, 0x14, 0x00, 0x15, 0x90,
137 0x16, 0x10, 0x17, 0x2c, 0x18, 0xb1, 0x19, 0x20, 0x1a, 0x01
138};
139
140static char SMI_EXT_CRT[VIDEO_MODES][24] = {
141 { /* DUAL_800_600_8 */
142 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
143 0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00
144 },
145 { /* DUAL_1024_768_8 */
146 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
147 0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00
148 },
149 { /* SINGLE_800_600_8 */
150 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
151 0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00
152 },
153 { /* SINGLE_1024_768_8 */
154 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
155 0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00
156 },
157 { /* SINGLE_1280_1024_8 */
158 0x30, 0x09, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
159 0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00
160 },
161 { /* TV_MODE_CCIR */
162 0x30, 0x80, 0x31, 0x2b, 0x32, 0x06, 0x33, 0x01, 0x34, 0x26, 0x35, 0x88,
163 0x36, 0x02, 0x38, 0x11, 0x39, 0x11, 0x3a, 0x20, 0x3e, 0xa3, 0x3f, 0x00
164 },
165 { /* TV_MODE_EIA */
166 0x30, 0x80, 0x31, 0x2b, 0x32, 0x06, 0x33, 0x00, 0x34, 0xf8, 0x35, 0x88,
167 0x36, 0x02, 0x38, 0x11, 0x39, 0x11, 0x3a, 0x20, 0x3e, 0xa3, 0x3f, 0x00
168 },
169};
170
171static char SMI_CRTCR[VIDEO_MODES][50] = {
172 { /* DUAL_800_600_8 */
173 0x00, 0x7f, 0x01, 0x63, 0x02, 0x63, 0x03, 0x00, 0x04, 0x68, 0x05, 0x12,
174 0x06, 0x6f, 0x07, 0xf0, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
175 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x59, 0x11, 0x2c,
176 0x12, 0x57, 0x13, 0x64, 0x14, 0x40, 0x15, 0x57, 0x16, 0x00, 0x17, 0xe3,
177 0x18, 0xff
178 },
179 { /* DUAL_1024_768_8 */
180 0x00, 0x9f, 0x01, 0x7f, 0x02, 0x7f, 0x03, 0x00, 0x04, 0x82, 0x05, 0x0e,
181 0x06, 0x1e, 0x07, 0xf5, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
182 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x01, 0x11, 0x24,
183 0x12, 0xff, 0x13, 0x80, 0x14, 0x40, 0x15, 0xff, 0x16, 0x00, 0x17, 0xe3,
184 0x18, 0xff
185 },
186 { /* SINGLE_800_600_8 */
187 0x00, 0x7f, 0x01, 0x63, 0x02, 0x63, 0x03, 0x00, 0x04, 0x68, 0x05, 0x12,
188 0x06, 0x6f, 0x07, 0xf0, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
189 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x59, 0x11, 0x2c,
190 0x12, 0x57, 0x13, 0x32, 0x14, 0x40, 0x15, 0x57, 0x16, 0x00, 0x17, 0xe3,
191 0x18, 0xff
192 },
193 { /* SINGLE_1024_768_8 */
194 0x00, 0x9f, 0x01, 0x7f, 0x02, 0x7f, 0x03, 0x00, 0x04, 0x82, 0x05, 0x0e,
195 0x06, 0x1e, 0x07, 0xf5, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
196 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x01, 0x11, 0x24,
197 0x12, 0xff, 0x13, 0x40, 0x14, 0x40, 0x15, 0xff, 0x16, 0x00, 0x17, 0xe3,
198 0x18, 0xff
199 },
200 { /* SINGLE_1280_1024_8 */
201 0x00, 0xce, 0x01, 0x9f, 0x02, 0x9f, 0x03, 0x00, 0x04, 0xa2, 0x05, 0x12,
202 0x06, 0x2a, 0x07, 0x5a, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
203 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x01, 0x11, 0x23,
204 0x12, 0xff, 0x13, 0x50, 0x14, 0x40, 0x15, 0xff, 0x16, 0x00, 0x17, 0xe3,
205 0x18, 0xff
206 },
207 { /* TV_MODE_CCIR */
208 0x00, 0x00, 0x01, 0x59, 0x02, 0x63, 0x03, 0x00, 0x04, 0x69, 0x05, 0x10,
209 0x06, 0x72, 0x07, 0xf0, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
210 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x58, 0x11, 0x2c,
211 0x12, 0x57, 0x13, 0x2d, 0x14, 0x40, 0x15, 0x57, 0x16, 0x00, 0x17, 0xe3,
212 0x18, 0xff
213 },
214 { /* TV_MODE_EIA */
215 0x00, 0x00, 0x01, 0x59, 0x02, 0x63, 0x03, 0x00, 0x04, 0x69, 0x05, 0x10,
216 0x06, 0x72, 0x07, 0xf0, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
217 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x58, 0x11, 0x2c,
218 0x12, 0x57, 0x13, 0x2d, 0x14, 0x40, 0x15, 0x57, 0x16, 0x00, 0x17, 0xe3,
219 0x18, 0xff
220 },
221};
222
223static char SMI_SEQR[10] = {
224 0x00, 0x03, 0x01, 0x01, 0x02, 0x0f, 0x03, 0x03, 0x04, 0x0e
225};
226
227static char SMI_PCR[VIDEO_MODES][8] = {
228 { /* DUAL_800_600_8 */
229 0x20, 0x04, 0x21, 0x20, 0x22, 0x00, 0x23, 0x00
230 },
231 { /* DUAL_1024_768_8 */
232 0x20, 0x04, 0x21, 0x20, 0x22, 0x00, 0x23, 0x00
233 },
234 { /* SINGLE_800_600_8 */
235 0x20, 0x04, 0x21, 0x30, 0x22, 0x02, 0x23, 0x00
236 },
237 { /* SINGLE_1024_768_8 */
238 0x20, 0x04, 0x21, 0x30, 0x22, 0x02, 0x23, 0x00
239 },
240 { /* SINGLE_1280_1024_8 */
241 0x20, 0x04, 0x21, 0x30, 0x22, 0x02, 0x23, 0x00
242 },
243 { /* TV_MODE_CCIR */
244 0x20, 0x04, 0x21, 0x30, 0x22, 0x02, 0x23, 0x00
245 },
246 { /* TV_MODE_EIA */
247 0x20, 0x04, 0x21, 0x30, 0x22, 0x02, 0x23, 0x00
248 },
249};
250
251static char SMI_MCR[VIDEO_MODES][6] = {
252 { /* DUAL_800_600_8 */
253 0x60, 0x01, 0x61, 0x00, 0x62, 0x7a
254 },
255 { /* DUAL_1024_768_8 */
256 0x60, 0x01, 0x61, 0x00, 0x62, 0x7a
257 },
258 { /* SINGLE_800_600_8 */
259 0x60, 0x00, 0x61, 0x00, 0x62, 0x34
260 },
261 { /* SINGLE_1024_768_8 */
262 0x60, 0x00, 0x61, 0x00, 0x62, 0xfe
263 },
264 { /* SINGLE_1280_1024_8 */
265 0x60, 0x00, 0x61, 0x00, 0x62, 0xfe
266 },
267 { /* TV_MODE_CCIR */
268 0x60, 0x00, 0x61, 0x00, 0x62, 0x34
269 },
270 { /* TV_MODE_EIA */
271 0x60, 0x00, 0x61, 0x00, 0x62, 0x34
272 },
273};
274
275static char SMI_CCR[VIDEO_MODES][18] = {
276 { /* DUAL_800_600_8 */
277 0x65, 0x34, 0x68, 0x50, 0x69, 0x05, 0x6a, 0x53, 0x6b, 0x15, 0x6c, 0x15,
278 0x6d, 0x06, 0x6e, 0x3d, 0x6f, 0x12
279 },
280 { /* DUAL_1024_768_8 */
281 0x65, 0x00, 0x68, 0x50, 0x69, 0x06, 0x6a, 0x53, 0x6b, 0x15, 0x6c, 0x0b,
282 0x6d, 0x02, 0x6e, 0x0b, 0x6f, 0x02
283 },
284 { /* SINGLE_800_600_8 */
285 0x65, 0x34, 0x68, 0x40, 0x69, 0x03, 0x6a, 0x53, 0x6b, 0x15, 0x6c, 0x15,
286 0x6d, 0x06, 0x6e, 0x3d, 0x6f, 0x12
287 },
288 { /* SINGLE_1024_768_8 */
289 0x65, 0x00, 0x68, 0x50, 0x69, 0x03, 0x6a, 0x53, 0x6b, 0x15, 0x6c, 0x0b,
290 0x6d, 0x02, 0x6e, 0x0b, 0x6f, 0x02
291 },
292 { /* SINGLE_1280_1024_8 */
293 0x65, 0x00, 0x68, 0x50, 0x69, 0x03, 0x6a, 0x53, 0x6b, 0x15, 0x6c, 0xd9,
294 0x6d, 0x17, 0x6e, 0xd9, 0x6f, 0x17
295 },
296 { /* TV_MODE_CCIR */
297 0x65, 0x07, 0x68, 0xc0, 0x69, 0x81, 0x6a, 0x53, 0x6b, 0x15, 0x6c, 0x15,
298 0x6d, 0x06, 0x6e, 0x3d, 0x6f, 0x12
299 },
300 { /* TV_MODE_EIA */
301 0x65, 0x07, 0x68, 0xc0, 0x69, 0x81, 0x6a, 0x53, 0x6b, 0x15, 0x6c, 0x15,
302 0x6d, 0x06, 0x6e, 0x3d, 0x6f, 0x12
303 },
304};
305
306static char SMI_SHVGA[VIDEO_MODES][24] = {
307 { /* DUAL_800_600_8 */
308 0x40, 0x7f, 0x41, 0x63, 0x42, 0x00, 0x43, 0x68, 0x44, 0x12, 0x45, 0x6f,
309 0x46, 0x57, 0x47, 0x00, 0x48, 0x59, 0x49, 0x0c, 0x4a, 0xa0, 0x4b, 0x20,
310 },
311 { /* DUAL_1024_768_8 */
312 0x40, 0x9f, 0x41, 0x7f, 0x42, 0x00, 0x43, 0x82, 0x44, 0x0e, 0x45, 0x1e,
313 0x46, 0xff, 0x47, 0x00, 0x48, 0x00, 0x49, 0x03, 0x4a, 0xe5, 0x4b, 0x20,
314 },
315 { /* SINGLE_800_600_8 */
316 0x40, 0x7f, 0x41, 0x63, 0x42, 0x00, 0x43, 0x68, 0x44, 0x12, 0x45, 0x6f,
317 0x46, 0x57, 0x47, 0x00, 0x48, 0x59, 0x49, 0x0c, 0x4a, 0xa0, 0x4b, 0x20,
318 },
319 { /* SINGLE_1024_768_8 */
320 0x40, 0x9f, 0x41, 0x7f, 0x42, 0x00, 0x43, 0x82, 0x44, 0x0e, 0x45, 0x1e,
321 0x46, 0xff, 0x47, 0x00, 0x48, 0x01, 0x49, 0x04, 0x4a, 0xa5, 0x4b, 0x20,
322 },
323 { /* SINGLE_1280_1024_8 */
324 0x40, 0xce, 0x41, 0x9f, 0x42, 0x00, 0x43, 0xa2, 0x44, 0x12, 0x45, 0x2a,
325 0x46, 0xff, 0x47, 0x00, 0x48, 0x01, 0x49, 0x03, 0x4a, 0x4a, 0x4b, 0x20,
326 },
327 { /* TV_MODE_CCIR */
328 0x40, 0x6d, 0x41, 0x59, 0x42, 0x00, 0x43, 0x60, 0x44, 0x09, 0x45, 0x38,
329 0x46, 0x25, 0x47, 0x05, 0x48, 0x2a, 0x49, 0x00, 0x4a, 0x4d, 0x4b, 0x00,
330 },
331 { /* TV_MODE_EIA */
332 0x40, 0x6d, 0x41, 0x59, 0x42, 0x00, 0x43, 0x60, 0x44, 0x09, 0x45, 0x06,
333 0x46, 0xf7, 0x47, 0x05, 0x48, 0xfa, 0x49, 0x00, 0x4a, 0x41, 0x4b, 0x00,
334 },
335};
336
337
338static char SMI_GPR[VIDEO_MODES][12] = {
339 { /* DUAL_800_600_8 */
340 0x70, 0x00, 0x71, 0xa2, 0x72, 0x0f, 0x73, 0x30, 0x74, 0x40, 0x75, 0x00
341 },
342 { /* DUAL_1024_768_8 */
343 0x70, 0x00, 0x71, 0xa2, 0x72, 0x0f, 0x73, 0x30, 0x74, 0x40, 0x75, 0x00
344 },
345 { /* SINGLE_800_600_8 */
346 0x70, 0x00, 0x71, 0xa2, 0x72, 0x0f, 0x73, 0x30, 0x74, 0x40, 0x75, 0x00
347 },
348 { /* SINGLE_1024_768_8 */
349 0x70, 0x00, 0x71, 0xa2, 0x72, 0x0f, 0x73, 0x30, 0x74, 0x40, 0x75, 0x00
350 },
351 { /* SINGLE_1280_1024_8 */
352 0x70, 0x00, 0x71, 0xa2, 0x72, 0x0f, 0x73, 0x30, 0x74, 0x40, 0x75, 0x00
353 },
354 { /* TV_MODE_CCIR */
355 0x70, 0x82, 0x71, 0x8d, 0x72, 0x0c, 0x73, 0x32, 0x74, 0x09, 0x75, 0x28
356 },
357 { /* TV_MODE_EIA */
358 0x70, 0x82, 0x71, 0x8d, 0x72, 0x0c, 0x73, 0x32, 0x74, 0x09, 0x75, 0x28
359 },
360};
361
362static char SMI_HCR[VIDEO_MODES][22] = {
363 { /* DUAL_800_600_8 */
364 0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
365 0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00
366 },
367 { /* DUAL_1024_768_8 */
368 0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
369 0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00
370 },
371 { /* SINGLE_800_600_8 */
372 0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
373 0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00
374 },
375 { /* SINGLE_1024_768_8 */
376 0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
377 0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00
378 },
379 { /* SINGLE_1280_1024_8 */
380 0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
381 0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00
382 },
383 { /* TV_MODE_CCIR */
384 0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
385 0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00
386 },
387 { /* TV_MODE_EIA */
388 0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
389 0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00
390 },
391};
392
393static char SMI_FPR[VIDEO_MODES][88] = {
394 { /* DUAL_800_600_8 */
395 0x30, 0x36, 0x31, 0x83, 0x32, 0x38, 0x33, 0x00, 0x34, 0x40, 0x3e, 0x03,
396 0x3f, 0xff, 0x40, 0x64, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0xc8,
397 0x45, 0x02, 0x46, 0x00, 0x47, 0xfc, 0x48, 0x20, 0x49, 0x1c, 0x4a, 0x41,
398 0x4b, 0xa0, 0x4c, 0x00,
399 0x50, 0x04, 0x51, 0x48, 0x52, 0x83, 0x53, 0x63, 0x54, 0x67, 0x55, 0x71,
400 0x56, 0x57, 0x57, 0x59, 0x58, 0x03, 0x59, 0x00, 0x5a, 0x4a,
401 0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa8, 0x00, 0xa9, 0x00,
402 0xaa, 0xdf, 0xab, 0x7f, 0xac, 0x00, 0xad, 0x41, 0xae, 0x00, 0xaf, 0x00,
403 0xa0, 0x44
404 },
405 { /* DUAL_1024_768_8 */
406 0x30, 0x3a, 0x31, 0x83, 0x32, 0x38, 0x33, 0x00, 0x34, 0x40, 0x3e, 0x00,
407 0x3f, 0x00, 0x40, 0x80, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00,
408 0x45, 0x42, 0x46, 0x00, 0x47, 0xfc, 0x48, 0x20, 0x49, 0x1c, 0x4a, 0x41,
409 0x4b, 0xa0, 0x4c, 0x00,
410 0x50, 0x06, 0x51, 0x68, 0x52, 0xa7, 0x53, 0x7f, 0x54, 0x83, 0x55, 0x25,
411 0x56, 0xff, 0x57, 0x03, 0x58, 0x04, 0x59, 0x00, 0x5a, 0xc2,
412 0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa8, 0x00, 0xa9, 0x00,
413 0xaa, 0xdf, 0xab, 0x7f, 0xac, 0x00, 0xad, 0x41, 0xae, 0x00, 0xaf, 0x00,
414 0xa0, 0x44
415 },
416 { /* SINGLE_800_600_8 */
417 0x30, 0x36, 0x31, 0x82, 0x32, 0x38, 0x33, 0x00, 0x34, 0x40, 0x3e, 0x03,
418 0x3f, 0xff, 0x40, 0x64, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0xc8,
419 0x45, 0x02, 0x46, 0x00, 0x47, 0xfc, 0x48, 0x20, 0x49, 0x1c, 0x4a, 0x00,
420 0x4b, 0xa0, 0x4c, 0x00,
421 0x50, 0x04, 0x51, 0x48, 0x52, 0x83, 0x53, 0x63, 0x54, 0x67, 0x55, 0x71,
422 0x56, 0x57, 0x57, 0x59, 0x58, 0x03, 0x59, 0x00, 0x5a, 0x4a,
423 0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa8, 0x00, 0xa9, 0x00,
424 0xaa, 0xdf, 0xab, 0x7f, 0xac, 0x00, 0xad, 0x41, 0xae, 0x00, 0xaf, 0x00,
425 0xa0, 0x44
426 },
427 { /* SINGLE_1024_768_8 */
428 0x30, 0x3a, 0x31, 0x82, 0x32, 0x38, 0x33, 0x00, 0x34, 0x40, 0x3e, 0x00,
429 0x3f, 0x00, 0x40, 0x80, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00,
430 0x45, 0x42, 0x46, 0x00, 0x47, 0xfc, 0x48, 0x20, 0x49, 0x1c, 0x4a, 0x11,
431 0x4b, 0xa0, 0x4c, 0x00,
432 0x50, 0x06, 0x51, 0x68, 0x52, 0xa7, 0x53, 0x7f, 0x54, 0x83, 0x55, 0x24,
433 0x56, 0xff, 0x57, 0x03, 0x58, 0x04, 0x59, 0x00, 0x5a, 0xc2,
434 0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa8, 0x00, 0xa9, 0x00,
435 0xaa, 0xdf, 0xab, 0x7f, 0xac, 0x00, 0xad, 0x41, 0xae, 0x00, 0xaf, 0x00,
436 0xa0, 0x44
437 },
438 { /* SINGLE_1280_1024_8 */
439 0x30, 0x3e, 0x31, 0x82, 0x32, 0x38, 0x33, 0x00, 0x34, 0x40, 0x3e, 0x00,
440 0x3f, 0x00, 0x40, 0xa0, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00,
441 0x45, 0x42, 0x46, 0x00, 0x47, 0xfc, 0x48, 0x20, 0x49, 0x1c, 0x4a, 0x11,
442 0x4b, 0xa0, 0x4c, 0x00,
443 0x50, 0x08, 0x51, 0x88, 0x52, 0xd3, 0x53, 0x9f, 0x54, 0xa3, 0x55, 0x2a,
444 0x56, 0xff, 0x57, 0x04, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x63,
445 0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa8, 0x00, 0xa9, 0x00,
446 0xaa, 0xdf, 0xab, 0x7f, 0xac, 0x00, 0xad, 0x41, 0xae, 0x00, 0xaf, 0x00,
447 0xa0, 0x44
448 },
449 { /* TV_MODE_CCIR */
450 0x30, 0x24, 0x31, 0x84, 0x32, 0x20, 0x33, 0x09, 0x34, 0xf0, 0x3e, 0x03,
451 0x3f, 0xff, 0x40, 0x64, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0xc8,
452 0x45, 0x02, 0x46, 0x00, 0x47, 0xfc, 0x48, 0x20, 0x49, 0x1c, 0x4a, 0x00,
453 0x4b, 0xa0, 0x4c, 0x00,
454 0x50, 0x04, 0x51, 0x48, 0x52, 0x83, 0x53, 0x63, 0x54, 0x68, 0x55, 0x73,
455 0x56, 0x57, 0x57, 0x58, 0x58, 0x04, 0x59, 0x57, 0x5a, 0x7b,
456 0xa1, 0x10, 0xa2, 0xab, 0xa3, 0x98, 0xa4, 0xc1, 0xa8, 0x8c, 0xa9, 0x05,
457 0xaa, 0x17, 0xab, 0x35, 0xac, 0x41, 0xad, 0x68, 0xae, 0x00, 0xaf, 0x00,
458 0xa0, 0x00
459 },
460 { /* TV_MODE_EIA */
461 0x30, 0x24, 0x31, 0x84, 0x32, 0x20, 0x33, 0x09, 0x34, 0xf0, 0x3e, 0x03,
462 0x3f, 0xff, 0x40, 0x64, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0xc8,
463 0x45, 0x02, 0x46, 0x00, 0x47, 0xfc, 0x48, 0x20, 0x49, 0x1c, 0x4a, 0x00,
464 0x4b, 0xa0, 0x4c, 0x00,
465 0x50, 0x04, 0x51, 0x48, 0x52, 0x83, 0x53, 0x63, 0x54, 0x68, 0x55, 0x73,
466 0x56, 0x57, 0x57, 0x58, 0x58, 0x04, 0x59, 0x57, 0x5a, 0x7b,
467 0xa1, 0x10, 0xa2, 0xab, 0xa3, 0x98, 0xa4, 0xc1, 0xa8, 0x8c, 0xa9, 0x05,
468 0xaa, 0x17, 0xab, 0x35, 0xac, 0x41, 0xad, 0x68, 0xae, 0x00, 0xaf, 0x00,
469 0xa0, 0x00
470 },
471};
472
473static char SMI_GCR[18] = {
474 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x40,
475 0x06, 0x05, 0x07, 0x0f, 0x08, 0xff
476};
477
478/*******************************************************************************
479*
480* Read SMI ISA register
481*/
482static char smiRead (unsigned short index, char reg)
483{
484 register GraphicDevice *pGD = (GraphicDevice *)&smi;
485
486 out8 ((pGD->isaBase + index), reg);
487 return (in8 (pGD->isaBase + index + 1));
488}
489
490/*******************************************************************************
491*
492* Write SMI ISA register
493*/
494static void smiWrite (unsigned short index, char reg, char val)
495{
496 register GraphicDevice *pGD = (GraphicDevice *)&smi;
497
498 out8 ((pGD->isaBase + index), reg);
499 out8 ((pGD->isaBase + index + 1), val);
500}
501
502/*******************************************************************************
503*
504* Write a table of SMI ISA register
505*/
506static void smiLoadRegs (
507 unsigned int iReg,
508 unsigned int dReg,
509 char *regTab,
510 unsigned int tabSize
511 )
512{
513 register int i;
514
515 for (i=0; i<tabSize; i+=2)
516 {
517 out8 (iReg, regTab[i]);
518 out8 (dReg, regTab[i+1]);
519 }
520}
521
522/*******************************************************************************
523*
524* Init capture port registers
525*/
526static void smiInitCapturePort (void)
527{
528 SmiCapturePort smiCP = { 0x01400600, 0x30, 0x40, 480, 640, 0, 0, 2560, 6 };
529 register GraphicDevice *pGD = (GraphicDevice *)&smi;
530 register SmiCapturePort *pCP = (SmiCapturePort *)&smiCP;
531
532 out32r ((pGD->cprBase + 0x0004), ((pCP->topClip<<16) | pCP->leftClip));
533 out32r ((pGD->cprBase + 0x0008), ((pCP->srcHeight<<16) | pCP->srcWidth));
534 out32r ((pGD->cprBase + 0x000c), pCP->srcBufStart1/8);
535 out32r ((pGD->cprBase + 0x0010), pCP->srcBufStart2/8);
536 out32r ((pGD->cprBase + 0x0014), pCP->srcOffset/8);
537 out32r ((pGD->cprBase + 0x0018), pCP->fifoControl);
538 out32r ((pGD->cprBase + 0x0000), pCP->control);
539}
540
541
542/*******************************************************************************
543*
544* Init video processor registers
545*/
546static void smiInitVideoProcessor (void)
547{
548 SmiVideoProc smiVP = { 0x100000, 0, 0, 0, 0, 1600, 0x1200543, 4, 0xededed };
549 SmiVideoWin smiVW = { 0, 0, 599, 799, 0, 1600, 0, 0, 0 };
550 register GraphicDevice *pGD = (GraphicDevice *)&smi;
551 register SmiVideoProc *pVP = (SmiVideoProc *)&smiVP;
552 register SmiVideoWin *pVWin = (SmiVideoWin *)&smiVW;
553
554 pVP->width = pGD->plnSizeX * pGD->gdfBytesPP;
555 pVP->control |= pGD->gdfIndex << 16;
556 pVWin->bottom = pGD->winSizeY - 1;
557 pVWin->right = pGD->winSizeX - 1;
558 pVWin->width = pVP->width;
559
560 /* color key */
561 out32r ((pGD->vprBase + 0x0004), pVP->colorKey);
562
563 /* color key mask */
564 out32r ((pGD->vprBase + 0x0008), pVP->colorKeyMask);
565
566 /* data src start adrs */
567 out32r ((pGD->vprBase + 0x000c), pVP->start / 8);
568
569 /* data width and offset */
570 out32r ((pGD->vprBase + 0x0010),
571 ((pVP->offset / 8 * pGD->gdfBytesPP) << 16) |
572 (pGD->plnSizeX / 8 * pGD->gdfBytesPP));
573
574 /* video window 1 */
575 out32r ((pGD->vprBase + 0x0014),
576 ((pVWin->top << 16) | pVWin->left));
577
578 out32r ((pGD->vprBase + 0x0018),
579 ((pVWin->bottom << 16) | pVWin->right));
580
581 out32r ((pGD->vprBase + 0x001c), pVWin->srcStart / 8);
582
583 out32r ((pGD->vprBase + 0x0020),
584 (((pVWin->offset / 8) << 16) | (pVWin->width / 8)));
585
586 out32r ((pGD->vprBase + 0x0024),
587 (((pVWin->hStretch) << 8) | pVWin->vStretch));
588
589 /* video window 2 */
590 out32r ((pGD->vprBase + 0x0028),
591 ((pVWin->top << 16) | pVWin->left));
592
593 out32r ((pGD->vprBase + 0x002c),
594 ((pVWin->bottom << 16) | pVWin->right));
595
596 out32r ((pGD->vprBase + 0x0030),
597 pVWin->srcStart / 8);
598
599 out32r ((pGD->vprBase + 0x0034),
600 (((pVWin->offset / 8) << 16) | (pVWin->width / 8)));
601
602 out32r ((pGD->vprBase + 0x0038),
603 (((pVWin->hStretch) << 8) | pVWin->vStretch));
604
605 /* fifo prio control */
606 out32r ((pGD->vprBase + 0x0054), pVP->fifoPrio);
607
608 /* fifo empty request levell */
609 out32r ((pGD->vprBase + 0x0058), pVP->fifoERL);
610
611 /* conversion constant */
612 out32r ((pGD->vprBase + 0x005c), pVP->YUVtoRGB);
613
614 /* vpr control word */
615 out32r ((pGD->vprBase + 0x0000), pVP->control);
616}
617
618/******************************************************************************
619 *
620 * Init drawing engine registers
621 */
622static void smiInitDrawingEngine (void)
623{
624 GraphicDevice *pGD = (GraphicDevice *)&smi;
625 unsigned int val;
626
627 /* don't start now */
628 out32r ((pGD->dprBase + 0x000c), 0x000f0000);
629
630 /* set rop2 to copypen */
631 val = 0xffff3ff0 & in32r ((pGD->dprBase + 0x000c));
632 out32r ((pGD->dprBase + 0x000c), (val | 0x8000 | 0x0c));
633
634 /* set clip rect */
635 out32r ((pGD->dprBase + 0x002c), 0);
636 out32r ((pGD->dprBase + 0x0030),
637 ((pGD->winSizeY<<16) | pGD->winSizeX * pGD->gdfBytesPP ));
638
639 /* src row pitch */
640 val = 0xffff0000 & (in32r ((pGD->dprBase + 0x0010)));
641 out32r ((pGD->dprBase + 0x0010),
642 (val | pGD->plnSizeX * pGD->gdfBytesPP));
643
644 /* dst row pitch */
645 val = 0x0000ffff & (in32r ((pGD->dprBase + 0x0010)));
646 out32r ((pGD->dprBase + 0x0010),
647 (((pGD->plnSizeX * pGD->gdfBytesPP)<<16) | val));
648
649 /* window width src/dst */
650 out32r ((pGD->dprBase + 0x003c),
651 (((pGD->plnSizeX * pGD->gdfBytesPP & 0x0fff)<<16) |
652 (pGD->plnSizeX * pGD->gdfBytesPP & 0x0fff)));
653 out16r ((pGD->dprBase + 0x001e), 0x0000);
654
655 /* src base adrs */
656 out32r ((pGD->dprBase + 0x0040),
657 (((pGD->frameAdrs/8) & 0x000fffff)));
658
659 /* dst base adrs */
660 out32r ((pGD->dprBase + 0x0044),
661 (((pGD->frameAdrs/8) & 0x000fffff)));
662
663 /* foreground color */
664 out32r ((pGD->dprBase + 0x0014), pGD->fg);
665
666 /* background color */
667 out32r ((pGD->dprBase + 0x0018), pGD->bg);
668
669 /* xcolor */
670 out32r ((pGD->dprBase + 0x0020), 0x00ffffff);
671
672 /* xcolor mask */
673 out32r ((pGD->dprBase + 0x0024), 0x00ffffff);
674
675 /* bit mask */
676 out32r ((pGD->dprBase + 0x0028), 0x00ffffff);
677
678 /* load mono pattern */
679 out32r ((pGD->dprBase + 0x0034), 0);
680 out32r ((pGD->dprBase + 0x0038), 0);
681}
682
683static struct pci_device_id supported[] = {
684 { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_710 },
685 { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_712 },
686 { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_810 },
687 { }
688};
689
690
691/*******************************************************************************
692*
693* Init video chip with common Linux graphic modes (lilo)
694*/
695void *video_hw_init (void)
696{
697 GraphicDevice *pGD = (GraphicDevice *)&smi;
698 unsigned short device_id;
699 pci_dev_t devbusfn;
700 int videomode;
701 unsigned int pci_mem_base, *vm, i;
702 unsigned int gdfTab[] = { 1, 2, 2, 4, 3, 1 };
703 char *penv;
704 char *gdfModes[] =
705 {
706 "8 Bit Index Color",
707 "15 Bit 5-5-5 RGB",
708 "16 Bit 5-6-5 RGB",
709 "32 Bit X-8-8-8 RGB",
710 "24 Bit 8-8-8 RGB",
711 "8 Bit 3-3-2 RGB"
712 };
713 int vgaModes[16][2] =
714 {
715 {769, -1}, {771, 0x00002}, {773, 0x00003}, {775, 0x00004},
716 {784, -1}, {787, 0x10002}, {790, 0x10003}, {793, 0x10004},
717 {785, -1}, {788, 0x20002}, {791, 0x20003}, {794, 0x20004},
718 {786, -1}, {789, 0x40002}, {792, 0x40003}, {795, 0x40004}
719 };
720
721 /* Search for video chip */
722 printf("Video: ");
723
724 if ((devbusfn = pci_find_devices(supported, 0)) < 0)
725 {
726 printf ("Controller not found !\n");
727 return (NULL);
728 }
729
730 /* PCI setup */
731 pci_write_config_dword (devbusfn, PCI_COMMAND, (PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
732 pci_read_config_word (devbusfn, PCI_DEVICE_ID, &device_id);
733 pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &pci_mem_base);
734 pci_mem_base = pci_mem_to_phys (devbusfn, pci_mem_base);
735
736 /* Initialize the video controller */
737 if ((penv = getenv ("videomode")) != NULL)
738 videomode = (int)simple_strtoul (penv, NULL, 16);
739 else
740 videomode = 0x303; /* Default 800x600 8 bit index color */
741
742 /* Compare with common vga mode numbers */
743 for (i=0; i<16; i++)
744 {
745 if (vgaModes[i][0] == videomode)
746 {
747 if (vgaModes[i][1] == -1)
748 {
749 printf("Videomode not supported !\n");
750 return (NULL); /* mode not supported */
751 }
752 pGD->mode = vgaModes[i][1]; /* use driver int. mode number */
753 break;
754 }
755 }
756
757 /* Extract graphic data format */
758 pGD->gdfIndex = (pGD->mode & 0x00070000) >> 16;
759 if (pGD->gdfIndex > 5)
760 pGD->gdfIndex = 0;
761 pGD->gdfBytesPP = gdfTab[pGD->gdfIndex];
762
763 /* Extract graphic resolution */
764 pGD->mode &= 0xf;
765
766 /* Exit for not supported resolutions */
767 if (((pGD->mode==DUAL_800_600) || (pGD->mode==DUAL_1024_768)) && (pGD->gdfBytesPP > 1))
768 {
769 printf ("Dual screen for 1BPP only !\n");
770 return (NULL);
771 }
772
773 if ((pGD->mode==SINGLE_1280_1024) && (pGD->gdfBytesPP==4))
774 {
775 printf ("Out of memory !\n");
776 return (NULL);
777 }
778
779 /* Set graphic parameters */
780 switch (pGD->mode)
781 {
782 case DUAL_800_600:
783 pGD->winSizeX = 800;
784 pGD->winSizeY = 600;
785 pGD->plnSizeX = 1600;
786 pGD->plnSizeY = 600;
787 sprintf (pGD->modeIdent, "Dual Screen 800x600 with %s", gdfModes[pGD->gdfIndex]);
788 break;
789 case DUAL_1024_768:
790 pGD->winSizeX = 1024;
791 pGD->winSizeY = 768;
792 pGD->plnSizeX = 2048;
793 pGD->plnSizeY = 768;
794 sprintf (pGD->modeIdent, "Dual Screen 1024x768 with %s", gdfModes[pGD->gdfIndex]);
795 break;
796 case SINGLE_800_600:
797 pGD->winSizeX = 800;
798 pGD->winSizeY = 600;
799 pGD->plnSizeX = 800;
800 pGD->plnSizeY = 600;
801 sprintf (pGD->modeIdent, "Single Screen 800x600 with %s", gdfModes[pGD->gdfIndex]);
802 break;
803 case SINGLE_1024_768:
804 pGD->winSizeX = 1024;
805 pGD->winSizeY = 768;
806 pGD->plnSizeX = 1024;
807 pGD->plnSizeY = 768;
808 sprintf (pGD->modeIdent,"Single Screen 1024x768 with %s", gdfModes[pGD->gdfIndex]);
809 break;
810 case TV_MODE_CCIR:
811 pGD->winSizeX = 720;
812 pGD->winSizeY = 576;
813 pGD->plnSizeX = 720;
814 pGD->plnSizeY = 576;
815 sprintf (pGD->modeIdent, "TV Mode CCIR with %s", gdfModes[pGD->gdfIndex]);
816 break;
817 case TV_MODE_EIA:
818 pGD->winSizeX = 720;
819 pGD->winSizeY = 484;
820 pGD->plnSizeX = 720;
821 pGD->plnSizeY = 484;
822 sprintf (pGD->modeIdent, "TV Mode EIA with %s", gdfModes[pGD->gdfIndex]);
823 break;
824 case SINGLE_1280_1024:
825 pGD->winSizeX = 1280;
826 pGD->winSizeY = 1024;
827 pGD->plnSizeX = 1280;
828 pGD->plnSizeY = 1024;
829 sprintf (pGD->modeIdent, "Single Screen 1280x1024 with %s", gdfModes[pGD->gdfIndex]);
830 break;
831 default:
832 printf("Videomode not supported !\n");
833 return (NULL);
834 }
835
836
837 pGD->isaBase = CFG_ISA_IO;
838 pGD->pciBase = pci_mem_base;
839 pGD->dprBase = (pci_mem_base + 0x400000 + 0x8000);
840 pGD->vprBase = (pci_mem_base + 0x400000 + 0xc000);
841 pGD->cprBase = (pci_mem_base + 0x400000 + 0xe000);
842 pGD->frameAdrs = pci_mem_base;
843 pGD->memSize = VIDEO_MEM_SIZE;
844
845 /* Turn off display */
846 smiWrite (0x3c4, 0x01, 0x20);
847
848 /* Unlock ext. crt regs */
849 out8 (SMI_LOCK_REG, 0x40);
850
851 /* Set Register base to isa 3dx for 3?x regs (color mode) */
852 out8 (SMI_MISC_REG, 0x2b);
853
854 /* Unlock crt regs 0-7 */
855 smiWrite (0x3d4, 0x11, 0x0e);
856
857 /* Sytem Control Register */
858 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
859 SMI_SCR, sizeof(SMI_SCR));
860
861 /* extented CRT Register */
862 smiLoadRegs (SMI_INDX_D4, SMI_DATA_D5,
863 SMI_EXT_CRT[pGD->mode], sizeof(SMI_EXT_CRT)/VIDEO_MODES);
864
865 /* Sequencer Register */
866 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
867 SMI_SEQR, sizeof(SMI_SEQR));
868
869 /* Power Control Register */
870 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
871 SMI_PCR[pGD->mode], sizeof(SMI_PCR)/VIDEO_MODES);
872
873 /* Memory Control Register */
874 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
875 SMI_MCR[pGD->mode], sizeof(SMI_MCR)/VIDEO_MODES);
876
877 /* Clock Control Register */
878 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
879 SMI_CCR[pGD->mode], sizeof(SMI_CCR)/VIDEO_MODES);
880
881 /* Shadow VGA Register */
882 smiLoadRegs (SMI_INDX_D4, SMI_DATA_D5,
883 SMI_SHVGA[pGD->mode], sizeof(SMI_SHVGA)/VIDEO_MODES);
884
885 /* General Purpose Register */
886 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
887 SMI_GPR[pGD->mode], sizeof(SMI_GPR)/VIDEO_MODES);
888
889 /* Hardware Cusor Register */
890 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
891 SMI_HCR[pGD->mode], sizeof(SMI_HCR)/VIDEO_MODES);
892
893 /* Flat Panel Register */
894 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
895 SMI_FPR[pGD->mode], sizeof(SMI_FPR)/VIDEO_MODES);
896
897 /* CRTC Register */
898 smiLoadRegs (SMI_INDX_D4, SMI_DATA_D5,
899 SMI_CRTCR[pGD->mode], sizeof(SMI_CRTCR)/VIDEO_MODES);
900
901 /* Graphics Controller Register */
902 smiLoadRegs (SMI_INDX_CE, SMI_DATA_CF,
903 SMI_GCR, sizeof(SMI_GCR));
904
905 /* Patch memory and refresh settings for SMI710 */
906 if (device_id == PCI_DEVICE_ID_SMI_710)
907 {
908 unsigned char reg = smiRead (0x3c4, 0x62);
909
910 /* external memory disabled */
911 smiWrite (0x3c4, 0x62, (reg & 0xfb));
912 /* memory clock */
913 smiWrite (0x3c4, 0x6a, 0x75);
914 }
915
916 /* Patch memory and refresh settings for SMI712 */
917 if (device_id == PCI_DEVICE_ID_SMI_712)
918 {
919 unsigned char reg = smiRead (0x3c4, 0x62);
920
921 /* IL runs at MCLK; 64bit bus; external memory disabled */
922 smiWrite (0x3c4, 0x62, (reg | 0xc4));
923 /* memory clock */
924 smiWrite (0x3c4, 0x6a, 0x80);
925 }
926
927 /* Patch clock settings for SMI810 */
928 if (device_id == PCI_DEVICE_ID_SMI_810)
929 {
930 /* clock control */
931 smiWrite (0x3c4, 0x69, 0x03);
932 }
933
934 /* Video processor default setup */
935 smiInitVideoProcessor ();
936
937 /* Capture port default setup */
938 smiInitCapturePort ();
939
940 /* Drawing engine default setup */
941 smiInitDrawingEngine ();
942
943 /* Turn on display */
944 smiWrite (0x3c4, 0x01, 0x01);
945
946 /* Clear video memory */
947 i = pGD->memSize/4;
948 vm = (unsigned int *)pGD->pciBase;
949 while(i--)
950 *vm++ = 0;
951
952 printf("mode=%x - %s\n", videomode, pGD->modeIdent);
953 return ((void*)&smi);
954}
955
956/*******************************************************************************
957*
958* Drawing engine fill on screen region
959*/
960void video_hw_rectfill (
961 unsigned int bpp, /* bytes per pixel */
962 unsigned int dst_x, /* dest pos x */
963 unsigned int dst_y, /* dest pos y */
964 unsigned int dim_x, /* frame width */
965 unsigned int dim_y, /* frame height */
966 unsigned int color /* fill color */
967 )
968{
969 register GraphicDevice *pGD = (GraphicDevice *)&smi;
970 register unsigned int control;
971
972 dim_x *= bpp;
973
974 out32r ((pGD->dprBase + 0x0014), color);
975 out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y));
976 out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y));
977
978 control = 0x0000ffff & in32r ((pGD->dprBase + 0x000c));
979
980 control |= 0x80010000;
981
982 out32r ((pGD->dprBase + 0x000c), control);
983
984 /* Wait for drawing processor */
985 do
986 {
987 out8 ((pGD->isaBase + 0x3c4), 0x16);
988 } while (in8 (pGD->isaBase + 0x3c5) & 0x08);
989}
990
991/*******************************************************************************
992*
993* Drawing engine bitblt with screen region
994*/
995void video_hw_bitblt (
996 unsigned int bpp, /* bytes per pixel */
997 unsigned int src_x, /* source pos x */
998 unsigned int src_y, /* source pos y */
999 unsigned int dst_x, /* dest pos x */
1000 unsigned int dst_y, /* dest pos y */
1001 unsigned int dim_x, /* frame width */
1002 unsigned int dim_y /* frame height */
1003 )
1004{
1005 register GraphicDevice *pGD = (GraphicDevice *)&smi;
1006 register unsigned int control;
1007
1008 dim_x *= bpp;
1009
1010 if ((src_y<dst_y) || ((src_y==dst_y) && (src_x<dst_x)))
1011 {
1012 out32r ((pGD->dprBase + 0x0000), (((src_x+dim_x-1)<<16) | (src_y+dim_y-1)));
1013 out32r ((pGD->dprBase + 0x0004), (((dst_x+dim_x-1)<<16) | (dst_y+dim_y-1)));
1014 control = 0x88000000;
1015 }
1016 else
1017 {
1018 out32r ((pGD->dprBase + 0x0000), ((src_x<<16) | src_y));
1019 out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y));
1020 control = 0x80000000;
1021 }
1022
1023 out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y));
1024 control |= (0x0000ffff & in32r ((pGD->dprBase + 0x000c)));
1025 out32r ((pGD->dprBase + 0x000c), control);
1026
1027 /* Wait for drawing processor */
1028 do
1029 {
1030 out8 ((pGD->isaBase + 0x3c4), 0x16);
1031 } while (in8 (pGD->isaBase + 0x3c5) & 0x08);
1032}
1033
1034/*******************************************************************************
1035*
1036* Set a RGB color in the LUT (8 bit index)
1037*/
1038void video_set_lut (
1039 unsigned int index, /* color number */
1040 unsigned char r, /* red */
1041 unsigned char g, /* green */
1042 unsigned char b /* blue */
1043 )
1044{
1045 register GraphicDevice *pGD = (GraphicDevice *)&smi;
1046
1047 out8 (SMI_LUT_MASK, 0xff);
1048
1049 out8 (SMI_LUT_START, (char)index);
1050
1051 out8 (SMI_LUT_RGB, r>>2); /* red */
1052 udelay (10);
1053 out8 (SMI_LUT_RGB, g>>2); /* green */
1054 udelay (10);
1055 out8 (SMI_LUT_RGB, b>>2); /* blue */
1056 udelay (10);
1057}
1058
1059#endif /* CONFIG_VIDEO_SMI_LYNXEM */