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