1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include <common.h>
26
27#include <pci.h>
28#include <video_fb.h>
29#include "videomodes.h"
30
31
32
33GraphicDevice smi;
34
35
36
37
38#define VIDEO_MEM_SIZE 0x400000
39
40
41
42
43
44#define SMI_INDX_C4 (pGD->isaBase + 0x03c4)
45#define SMI_DATA_C5 (pGD->isaBase + 0x03c5)
46#define SMI_INDX_D4 (pGD->isaBase + 0x03d4)
47#define SMI_DATA_D5 (pGD->isaBase + 0x03d5)
48#define SMI_ISR1 (pGD->isaBase + 0x03ca)
49#define SMI_INDX_CE (pGD->isaBase + 0x03ce)
50#define SMI_DATA_CF (pGD->isaBase + 0x03cf)
51#define SMI_LOCK_REG (pGD->isaBase + 0x03c3)
52#define SMI_MISC_REG (pGD->isaBase + 0x03c2)
53#define SMI_LUT_MASK (pGD->isaBase + 0x03c6)
54#define SMI_LUT_START (pGD->isaBase + 0x03c8)
55#define SMI_LUT_RGB (pGD->isaBase + 0x03c9)
56#define SMI_INDX_ATTR (pGD->isaBase + 0x03c0)
57
58
59
60
61typedef struct {
62 unsigned int control;
63 unsigned int colorKey;
64 unsigned int colorKeyMask;
65 unsigned int start;
66 unsigned short offset;
67 unsigned short width;
68 unsigned int fifoPrio;
69 unsigned int fifoERL;
70 unsigned int YUVtoRGB;
71} SmiVideoProc;
72
73
74
75
76typedef struct {
77 unsigned short top;
78 unsigned short left;
79 unsigned short bottom;
80 unsigned short right;
81 unsigned int srcStart;
82 unsigned short width;
83 unsigned short offset;
84 unsigned char hStretch;
85 unsigned char vStretch;
86} SmiVideoWin;
87
88
89
90
91typedef struct {
92 unsigned int control;
93 unsigned short topClip;
94 unsigned short leftClip;
95 unsigned short srcHeight;
96 unsigned short srcWidth;
97 unsigned int srcBufStart1;
98 unsigned int srcBufStart2;
99 unsigned short srcOffset;
100 unsigned short fifoControl;
101} SmiCapturePort;
102
103
104
105
106
107static char SMI_SCR[] = {
108
109 0x10, 0xff, 0x11, 0xff, 0x12, 0xff, 0x13, 0xff, 0x15, 0x90,
110 0x17, 0x20, 0x18, 0xb1, 0x19, 0x00,
111};
112static char SMI_EXT_CRT[] = {
113 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
114 0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00,
115};
116static char SMI_ATTR [] = {
117 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05,
118 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b,
119 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x41, 0x11, 0x00,
120 0x12, 0x0f, 0x13, 0x00, 0x14, 0x00,
121};
122static char SMI_GCR[18] = {
123 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x40,
124 0x06, 0x05, 0x07, 0x0f, 0x08, 0xff,
125};
126static char SMI_SEQR[] = {
127 0x00, 0x00, 0x01, 0x01, 0x02, 0x0f, 0x03, 0x03, 0x04, 0x0e, 0x00, 0x03,
128};
129static char SMI_PCR [] = {
130 0x20, 0x04, 0x21, 0x30, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00,
131};
132static char SMI_MCR[] = {
133 0x60, 0x01, 0x61, 0x00,
134};
135
136static char SMI_HCR[] = {
137 0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
138 0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00,
139};
140
141
142
143
144
145
146static void smiWrite (unsigned short index, char reg, char val)
147{
148 register GraphicDevice *pGD = (GraphicDevice *)&smi;
149
150 out8 ((pGD->isaBase + index), reg);
151 out8 ((pGD->isaBase + index + 1), val);
152}
153
154
155
156
157
158static void smiLoadRegs (
159 unsigned int iReg,
160 unsigned int dReg,
161 char *regTab,
162 unsigned int tabSize
163 )
164{
165 register GraphicDevice *pGD = (GraphicDevice *)&smi;
166 register int i;
167
168 for (i=0; i<tabSize; i+=2) {
169 if (iReg == SMI_INDX_ATTR) {
170
171 in8 (SMI_ISR1);
172 out8 (iReg, regTab[i]);
173 out8 (iReg, regTab[i+1]);
174 } else {
175 out8 (iReg, regTab[i]);
176 out8 (dReg, regTab[i+1]);
177 }
178 }
179}
180
181
182
183
184
185static void smiInitCapturePort (void)
186{
187 SmiCapturePort smiCP = { 0x01400600, 0x30, 0x40, 480, 640, 0, 0, 2560, 6 };
188 register GraphicDevice *pGD = (GraphicDevice *)&smi;
189 register SmiCapturePort *pCP = (SmiCapturePort *)&smiCP;
190
191 out32r ((pGD->cprBase + 0x0004), ((pCP->topClip<<16) | pCP->leftClip));
192 out32r ((pGD->cprBase + 0x0008), ((pCP->srcHeight<<16) | pCP->srcWidth));
193 out32r ((pGD->cprBase + 0x000c), pCP->srcBufStart1/8);
194 out32r ((pGD->cprBase + 0x0010), pCP->srcBufStart2/8);
195 out32r ((pGD->cprBase + 0x0014), pCP->srcOffset/8);
196 out32r ((pGD->cprBase + 0x0018), pCP->fifoControl);
197 out32r ((pGD->cprBase + 0x0000), pCP->control);
198}
199
200
201
202
203
204
205static void smiInitVideoProcessor (void)
206{
207 SmiVideoProc smiVP = { 0x100000, 0, 0, 0, 0, 1600, 0x1200543, 4, 0xededed };
208 SmiVideoWin smiVW = { 0, 0, 599, 799, 0, 1600, 0, 0, 0 };
209 register GraphicDevice *pGD = (GraphicDevice *)&smi;
210 register SmiVideoProc *pVP = (SmiVideoProc *)&smiVP;
211 register SmiVideoWin *pVWin = (SmiVideoWin *)&smiVW;
212
213 pVP->width = pGD->plnSizeX * pGD->gdfBytesPP;
214 pVP->control |= pGD->gdfIndex << 16;
215 pVWin->bottom = pGD->winSizeY - 1;
216 pVWin->right = pGD->winSizeX - 1;
217 pVWin->width = pVP->width;
218
219
220 out32r ((pGD->vprBase + 0x0004), pVP->colorKey);
221
222
223 out32r ((pGD->vprBase + 0x0008), pVP->colorKeyMask);
224
225
226 out32r ((pGD->vprBase + 0x000c), pVP->start / 8);
227
228
229 out32r ((pGD->vprBase + 0x0010),
230 ((pVP->offset / 8 * pGD->gdfBytesPP) << 16) |
231 (pGD->plnSizeX / 8 * pGD->gdfBytesPP));
232
233
234 out32r ((pGD->vprBase + 0x0014),
235 ((pVWin->top << 16) | pVWin->left));
236
237 out32r ((pGD->vprBase + 0x0018),
238 ((pVWin->bottom << 16) | pVWin->right));
239
240 out32r ((pGD->vprBase + 0x001c), pVWin->srcStart / 8);
241
242 out32r ((pGD->vprBase + 0x0020),
243 (((pVWin->offset / 8) << 16) | (pVWin->width / 8)));
244
245 out32r ((pGD->vprBase + 0x0024),
246 (((pVWin->hStretch) << 8) | pVWin->vStretch));
247
248
249 out32r ((pGD->vprBase + 0x0028),
250 ((pVWin->top << 16) | pVWin->left));
251
252 out32r ((pGD->vprBase + 0x002c),
253 ((pVWin->bottom << 16) | pVWin->right));
254
255 out32r ((pGD->vprBase + 0x0030),
256 pVWin->srcStart / 8);
257
258 out32r ((pGD->vprBase + 0x0034),
259 (((pVWin->offset / 8) << 16) | (pVWin->width / 8)));
260
261 out32r ((pGD->vprBase + 0x0038),
262 (((pVWin->hStretch) << 8) | pVWin->vStretch));
263
264
265 out32r ((pGD->vprBase + 0x0054), pVP->fifoPrio);
266
267
268 out32r ((pGD->vprBase + 0x0058), pVP->fifoERL);
269
270
271 out32r ((pGD->vprBase + 0x005c), pVP->YUVtoRGB);
272
273
274 out32r ((pGD->vprBase + 0x0000), pVP->control);
275}
276
277
278
279
280
281static void smiInitDrawingEngine (void)
282{
283 GraphicDevice *pGD = (GraphicDevice *)&smi;
284 unsigned int val;
285
286
287 out32r ((pGD->dprBase + 0x000c), 0x000f0000);
288
289
290 val = 0xffff3ff0 & in32r ((pGD->dprBase + 0x000c));
291 out32r ((pGD->dprBase + 0x000c), (val | 0x8000 | 0x0c));
292
293
294 out32r ((pGD->dprBase + 0x002c), 0);
295 out32r ((pGD->dprBase + 0x0030),
296 ((pGD->winSizeY<<16) | pGD->winSizeX * pGD->gdfBytesPP ));
297
298
299 val = 0xffff0000 & (in32r ((pGD->dprBase + 0x0010)));
300 out32r ((pGD->dprBase + 0x0010),
301 (val | pGD->plnSizeX * pGD->gdfBytesPP));
302
303
304 val = 0x0000ffff & (in32r ((pGD->dprBase + 0x0010)));
305 out32r ((pGD->dprBase + 0x0010),
306 (((pGD->plnSizeX * pGD->gdfBytesPP)<<16) | val));
307
308
309 out32r ((pGD->dprBase + 0x003c),
310 (((pGD->plnSizeX * pGD->gdfBytesPP & 0x0fff)<<16) |
311 (pGD->plnSizeX * pGD->gdfBytesPP & 0x0fff)));
312 out16r ((pGD->dprBase + 0x001e), 0x0000);
313
314
315 out32r ((pGD->dprBase + 0x0040),
316 (((pGD->frameAdrs/8) & 0x000fffff)));
317
318
319 out32r ((pGD->dprBase + 0x0044),
320 (((pGD->frameAdrs/8) & 0x000fffff)));
321
322
323 out32r ((pGD->dprBase + 0x0014), pGD->fg);
324
325
326 out32r ((pGD->dprBase + 0x0018), pGD->bg);
327
328
329 out32r ((pGD->dprBase + 0x0020), 0x00ffffff);
330
331
332 out32r ((pGD->dprBase + 0x0024), 0x00ffffff);
333
334
335 out32r ((pGD->dprBase + 0x0028), 0x00ffffff);
336
337
338 out32r ((pGD->dprBase + 0x0034), 0);
339 out32r ((pGD->dprBase + 0x0038), 0);
340}
341
342static struct pci_device_id supported[] = {
343 { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_710 },
344 { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_712 },
345 { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_810 },
346 { }
347};
348
349
350static void smiLoadMsr (struct ctfb_res_modes *mode)
351{
352 unsigned char h_synch_high, v_synch_high;
353 register GraphicDevice *pGD = (GraphicDevice *)&smi;
354
355 h_synch_high = (mode->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 0x40;
356 v_synch_high = (mode->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 0x80;
357 out8 (SMI_MISC_REG, (h_synch_high | v_synch_high | 0x29));
358
359
360
361
362
363
364
365}
366
367static void smiLoadCrt (struct ctfb_res_modes *var, int bits_per_pixel)
368{
369 unsigned char cr[0x7a];
370 int i;
371 unsigned int hd, hs, he, ht, hbs, hbe;
372 unsigned int vd, vs, ve, vt, vbs, vbe;
373 unsigned int bpp, wd, dblscan, interlaced;
374
375 const int LineCompare = 0x3ff;
376 unsigned int TextScanLines = 1;
377 register GraphicDevice *pGD = (GraphicDevice *)&smi;
378
379
380 hd = (var->xres) / 8;
381 hs = (var->xres + var->right_margin) / 8;
382 he = (var->xres + var->right_margin + var->hsync_len) / 8;
383 ht = (var->left_margin + var->xres + var->right_margin + var->hsync_len) / 8;
384
385 hbs = hd;
386 hbe = 0;
387
388
389 vd = var->yres;
390 vs = var->yres + var->lower_margin;
391 ve = var->yres + var->lower_margin + var->vsync_len;
392 vt = var->upper_margin + var->yres + var->lower_margin + var->vsync_len;
393 vbs = vd;
394 vbe = 0;
395
396 bpp = bits_per_pixel;
397 dblscan = (var->vmode & FB_VMODE_DOUBLE) ? 1 : 0;
398 interlaced = var->vmode & FB_VMODE_INTERLACED;
399
400
401 if (bpp == 15)
402 bpp = 16;
403 wd = var->xres * bpp / 64;
404 if (interlaced) {
405 vs >>= 1;
406 vbs >>= 1;
407 ve >>= 1;
408 vt >>= 1;
409 }
410
411 memset (cr, 0, sizeof (cr));
412 cr[0x00] = ht - 5;
413 cr[0x01] = hd - 1;
414 cr[0x02] = hbs - 1;
415 cr[0x03] = (hbe & 0x1F);
416 cr[0x04] = hs;
417 cr[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f);
418
419 cr[0x06] = (vt - 2) & 0xFF;
420 cr[0x07] = (((vt - 2) & 0x100) >> 8)
421 | (((vd - 1) & 0x100) >> 7)
422 | ((vs & 0x100) >> 6)
423 | (((vbs - 1) & 0x100) >> 5)
424 | ((LineCompare & 0x100) >> 4)
425 | (((vt - 2) & 0x200) >> 4)
426 | (((vd - 1) & 0x200) >> 3)
427 | ((vs & 0x200) >> 2);
428
429 cr[0x30] = ((vt - 2) & 0x400) >> 7
430 | (((vd - 1) & 0x400) >> 8)
431 | (((vbs - 1) & 0x400) >> 9)
432 | ((vs & 0x400) >> 10)
433 | (interlaced) ? 0x80 : 0;
434
435
436 cr[0x08] = 0x00;
437 cr[0x09] = (dblscan << 7)
438 | ((LineCompare & 0x200) >> 3)
439 | (((vbs - 1) & 0x200) >> 4)
440 | (TextScanLines - 1);
441
442 cr[0x10] = vs & 0xff;
443 cr[0x11] = (ve & 0x0f);
444 cr[0x12] = (vd - 1) & 0xff;
445 cr[0x13] = wd & 0xff;
446 cr[0x14] = 0x40;
447 cr[0x15] = (vbs - 1) & 0xff;
448 cr[0x16] = vbe & 0xff;
449 cr[0x17] = 0xe3;
450 cr[0x18] = 0xff & LineCompare;
451 cr[0x22] = 0x00;
452
453
454
455 for (i = 0; i <= 0x18; i++) {
456 smiWrite (SMI_INDX_D4, i, cr[i]);
457 }
458 i = 0x22;
459 smiWrite (SMI_INDX_D4, i, cr[i]);
460 i = 0x30;
461 smiWrite (SMI_INDX_D4, i, cr[i]);
462}
463
464
465#define REF_FREQ 14318180
466#define PMIN 1
467#define PMAX 255
468#define QMIN 1
469#define QMAX 63
470
471static unsigned int FindPQ (unsigned int freq, unsigned int *pp, unsigned int *pq)
472{
473 unsigned int n = QMIN, m = 0;
474 long long int L = 0, P = freq, Q = REF_FREQ, H = P >> 1;
475 long long int D = 0x7ffffffffffffffLL;
476
477 for (n = QMIN; n <= QMAX; n++) {
478 m = PMIN;
479 L = P * n - m * Q;
480 while (L > 0 && m < PMAX) {
481 L -= REF_FREQ;
482 m++;
483 }
484
485 if (m > PMAX)
486 break;
487
488 if (-L > H && m > PMIN) {
489 L += REF_FREQ;
490 m--;
491 }
492 L = (L < 0) ? -L : +L;
493 if (D < L)
494 continue;
495 D = L;
496 *pp = m;
497 *pq = n;
498 if (D == 0)
499 break;
500 }
501 return (unsigned int) (0xffffffff & D);
502}
503
504
505static void smiLoadCcr (struct ctfb_res_modes *var, unsigned short device_id)
506{
507 unsigned int p = 0;
508 unsigned int q = 0;
509 long long freq;
510 register GraphicDevice *pGD = (GraphicDevice *)&smi;
511
512 smiWrite (SMI_INDX_C4, 0x65, 0);
513 smiWrite (SMI_INDX_C4, 0x66, 0);
514 smiWrite (SMI_INDX_C4, 0x68, 0x50);
515 if (device_id == PCI_DEVICE_ID_SMI_810) {
516 smiWrite (SMI_INDX_C4, 0x69, 0x3);
517 } else {
518 smiWrite (SMI_INDX_C4, 0x69, 0x0);
519 }
520
521
522 switch (device_id) {
523 case PCI_DEVICE_ID_SMI_710 :
524 smiWrite (SMI_INDX_C4, 0x6a, 0x75);
525 break;
526 case PCI_DEVICE_ID_SMI_712 :
527 smiWrite (SMI_INDX_C4, 0x6a, 0x80);
528 break;
529 default :
530 smiWrite (SMI_INDX_C4, 0x6a, 0x53);
531 break;
532 }
533 smiWrite (SMI_INDX_C4, 0x6b, 0x15);
534
535
536 freq = 1000000000000LL / var -> pixclock;
537
538 FindPQ ((unsigned int)freq, &p, &q);
539
540 smiWrite (SMI_INDX_C4, 0x6c, p);
541 smiWrite (SMI_INDX_C4, 0x6d, q);
542
543}
544
545
546
547
548
549void *video_hw_init (void)
550{
551 GraphicDevice *pGD = (GraphicDevice *)&smi;
552 unsigned short device_id;
553 pci_dev_t devbusfn;
554 int videomode;
555 unsigned long t1, hsynch, vsynch;
556 unsigned int pci_mem_base, *vm;
557 char *penv;
558 int tmp, i, bits_per_pixel;
559 struct ctfb_res_modes *res_mode;
560 struct ctfb_res_modes var_mode;
561 unsigned char videoout;
562
563
564 printf("Video: ");
565
566 if ((devbusfn = pci_find_devices(supported, 0)) < 0)
567 {
568 printf ("Controller not found !\n");
569 return (NULL);
570 }
571
572
573 pci_write_config_dword (devbusfn, PCI_COMMAND, (PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
574 pci_read_config_word (devbusfn, PCI_DEVICE_ID, &device_id);
575 pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &pci_mem_base);
576 pci_mem_base = pci_mem_to_phys (devbusfn, pci_mem_base);
577
578 tmp = 0;
579
580 videomode = CONFIG_SYS_DEFAULT_VIDEO_MODE;
581
582 if ((penv = getenv ("videomode")) != NULL) {
583
584 if (penv[0] <= '9') {
585 videomode = (int) simple_strtoul (penv, NULL, 16);
586 tmp = 1;
587 }
588 } else {
589 tmp = 1;
590 }
591 if (tmp) {
592
593
594 for (i = 0; i < VESA_MODES_COUNT; i++) {
595 if (vesa_modes[i].vesanr == videomode)
596 break;
597 }
598 if (i == VESA_MODES_COUNT) {
599 printf ("no VESA Mode found, switching to mode 0x%x ", CONFIG_SYS_DEFAULT_VIDEO_MODE);
600 i = 0;
601 }
602 res_mode =
603 (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].
604 resindex];
605 bits_per_pixel = vesa_modes[i].bits_per_pixel;
606 } else {
607
608 res_mode = (struct ctfb_res_modes *) &var_mode;
609 bits_per_pixel = video_get_params (res_mode, penv);
610 }
611
612
613 t1 = (res_mode->left_margin + res_mode->xres +
614 res_mode->right_margin + res_mode->hsync_len) / 8;
615 t1 *= 8;
616 t1 *= res_mode->pixclock;
617 t1 /= 1000;
618 hsynch = 1000000000L / t1;
619 t1 *=
620 (res_mode->upper_margin + res_mode->yres +
621 res_mode->lower_margin + res_mode->vsync_len);
622 t1 /= 1000;
623 vsynch = 1000000000L / t1;
624
625
626 sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
627 res_mode->yres, bits_per_pixel, (hsynch / 1000),
628 (vsynch / 1000));
629 printf ("%s\n", pGD->modeIdent);
630 pGD->winSizeX = res_mode->xres;
631 pGD->winSizeY = res_mode->yres;
632 pGD->plnSizeX = res_mode->xres;
633 pGD->plnSizeY = res_mode->yres;
634 switch (bits_per_pixel) {
635 case 8:
636 pGD->gdfBytesPP = 1;
637 pGD->gdfIndex = GDF__8BIT_INDEX;
638 break;
639 case 15:
640 pGD->gdfBytesPP = 2;
641 pGD->gdfIndex = GDF_15BIT_555RGB;
642 break;
643 case 16:
644 pGD->gdfBytesPP = 2;
645 pGD->gdfIndex = GDF_16BIT_565RGB;
646 break;
647 case 24:
648 pGD->gdfBytesPP = 3;
649 pGD->gdfIndex = GDF_24BIT_888RGB;
650 break;
651 }
652
653 pGD->isaBase = CONFIG_SYS_ISA_IO;
654 pGD->pciBase = pci_mem_base;
655 pGD->dprBase = (pci_mem_base + 0x400000 + 0x8000);
656 pGD->vprBase = (pci_mem_base + 0x400000 + 0xc000);
657 pGD->cprBase = (pci_mem_base + 0x400000 + 0xe000);
658 pGD->frameAdrs = pci_mem_base;
659 pGD->memSize = VIDEO_MEM_SIZE;
660
661
662
663 out8 (SMI_MISC_REG, 0x01);
664
665
666 smiWrite (SMI_INDX_C4, 0x01, 0x20);
667
668
669 out8 (SMI_LOCK_REG, 0x40);
670
671
672 smiWrite (SMI_INDX_D4, 0x11, 0x0e);
673
674
675 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_SCR, sizeof(SMI_SCR));
676
677
678 smiLoadRegs (SMI_INDX_D4, SMI_DATA_D5, SMI_EXT_CRT, sizeof(SMI_EXT_CRT));
679
680
681 smiLoadRegs (SMI_INDX_ATTR, SMI_INDX_ATTR, SMI_ATTR, sizeof(SMI_ATTR));
682
683
684 smiLoadRegs (SMI_INDX_CE, SMI_DATA_CF, SMI_GCR, sizeof(SMI_GCR));
685
686
687 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_SEQR, sizeof(SMI_SEQR));
688
689
690 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_PCR, sizeof(SMI_PCR));
691
692
693
694
695 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_MCR, sizeof(SMI_MCR));
696
697
698 smiLoadMsr (res_mode);
699
700
701 smiLoadCrt (res_mode, bits_per_pixel);
702
703 smiLoadCcr (res_mode, device_id);
704
705
706 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_HCR, sizeof(SMI_HCR));
707
708
709 videoout = 2;
710 if ((penv = getenv ("videoout")) != NULL) {
711
712 videoout = (int) simple_strtoul (penv, NULL, 16);
713 }
714 smiWrite (SMI_INDX_C4, 0x31, videoout);
715
716
717 smiInitVideoProcessor ();
718
719
720 smiInitCapturePort ();
721
722
723 smiInitDrawingEngine ();
724
725
726 smiWrite (0x3c4, 0x01, 0x01);
727
728
729 i = pGD->memSize/4;
730 vm = (unsigned int *)pGD->pciBase;
731 while(i--)
732 *vm++ = 0;
733 return ((void*)&smi);
734}
735
736
737
738
739
740void video_hw_rectfill (
741 unsigned int bpp,
742 unsigned int dst_x,
743 unsigned int dst_y,
744 unsigned int dim_x,
745 unsigned int dim_y,
746 unsigned int color
747 )
748{
749 register GraphicDevice *pGD = (GraphicDevice *)&smi;
750 register unsigned int control;
751
752 dim_x *= bpp;
753
754 out32r ((pGD->dprBase + 0x0014), color);
755 out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y));
756 out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y));
757
758 control = 0x0000ffff & in32r ((pGD->dprBase + 0x000c));
759
760 control |= 0x80010000;
761
762 out32r ((pGD->dprBase + 0x000c), control);
763
764
765 do
766 {
767 out8 ((pGD->isaBase + 0x3c4), 0x16);
768 } while (in8 (pGD->isaBase + 0x3c5) & 0x08);
769}
770
771
772
773
774
775void video_hw_bitblt (
776 unsigned int bpp,
777 unsigned int src_x,
778 unsigned int src_y,
779 unsigned int dst_x,
780 unsigned int dst_y,
781 unsigned int dim_x,
782 unsigned int dim_y
783 )
784{
785 register GraphicDevice *pGD = (GraphicDevice *)&smi;
786 register unsigned int control;
787
788 dim_x *= bpp;
789
790 if ((src_y<dst_y) || ((src_y==dst_y) && (src_x<dst_x)))
791 {
792 out32r ((pGD->dprBase + 0x0000), (((src_x+dim_x-1)<<16) | (src_y+dim_y-1)));
793 out32r ((pGD->dprBase + 0x0004), (((dst_x+dim_x-1)<<16) | (dst_y+dim_y-1)));
794 control = 0x88000000;
795 } else {
796 out32r ((pGD->dprBase + 0x0000), ((src_x<<16) | src_y));
797 out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y));
798 control = 0x80000000;
799 }
800
801 out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y));
802 control |= (0x0000ffff & in32r ((pGD->dprBase + 0x000c)));
803 out32r ((pGD->dprBase + 0x000c), control);
804
805
806 do
807 {
808 out8 ((pGD->isaBase + 0x3c4), 0x16);
809 } while (in8 (pGD->isaBase + 0x3c5) & 0x08);
810}
811
812
813
814
815
816void video_set_lut (
817 unsigned int index,
818 unsigned char r,
819 unsigned char g,
820 unsigned char b
821 )
822{
823 register GraphicDevice *pGD = (GraphicDevice *)&smi;
824
825 out8 (SMI_LUT_MASK, 0xff);
826
827 out8 (SMI_LUT_START, (char)index);
828
829 out8 (SMI_LUT_RGB, r>>2);
830 udelay (10);
831 out8 (SMI_LUT_RGB, g>>2);
832 udelay (10);
833 out8 (SMI_LUT_RGB, b>>2);
834 udelay (10);
835}
836