2 * (C) Copyright 1997-2002 ELTEC Elektronik AG
3 * Frank Gottschling <fgottschling@eltec.de>
5 * See file CREDITS for list of people who contributed to this
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.
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.
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,
27 * Silicon Motion graphic interface for sm810/sm710/sm712 accelerator
29 * modification history
30 * --------------------
31 * 04-18-2002 Rewritten for U-Boot <fgottschling@eltec.de>.
33 * 18-03-2004 - Unify videomodes handling with the ct69000
34 * - The video output can be set via the variable "videoout"
36 * videoout=1 output on LCD
37 * videoout=2 output on CRT (default value)
38 * <p.aubert@staubli.com>
43 #if defined(CONFIG_VIDEO_SMI_LYNXEM)
47 #include "videomodes.h"
49 * Export Graphic Device
54 * SMI 710/712 have 4MB internal RAM; SMI 810 2MB internal + 2MB external
56 #define VIDEO_MEM_SIZE 0x400000
62 #define SMI_INDX_C4 (pGD->isaBase + 0x03c4) /* index reg */
63 #define SMI_DATA_C5 (pGD->isaBase + 0x03c5) /* data reg */
64 #define SMI_INDX_D4 (pGD->isaBase + 0x03d4) /* index reg */
65 #define SMI_DATA_D5 (pGD->isaBase + 0x03d5) /* data reg */
66 #define SMI_ISR1 (pGD->isaBase + 0x03ca)
67 #define SMI_INDX_CE (pGD->isaBase + 0x03ce) /* index reg */
68 #define SMI_DATA_CF (pGD->isaBase + 0x03cf) /* data reg */
69 #define SMI_LOCK_REG (pGD->isaBase + 0x03c3) /* unlock/lock ext crt reg */
70 #define SMI_MISC_REG (pGD->isaBase + 0x03c2) /* misc reg */
71 #define SMI_LUT_MASK (pGD->isaBase + 0x03c6) /* lut mask reg */
72 #define SMI_LUT_START (pGD->isaBase + 0x03c8) /* lut start index */
73 #define SMI_LUT_RGB (pGD->isaBase + 0x03c9) /* lut colors auto incr.*/
74 #define SMI_INDX_ATTR (pGD->isaBase + 0x03c0) /* attributes index reg */
77 * Video processor control
81 unsigned int colorKey;
82 unsigned int colorKeyMask;
84 unsigned short offset;
86 unsigned int fifoPrio;
88 unsigned int YUVtoRGB;
92 * Video window control
97 unsigned short bottom;
99 unsigned int srcStart;
100 unsigned short width;
101 unsigned short offset;
102 unsigned char hStretch;
103 unsigned char vStretch;
107 * Capture port control
110 unsigned int control;
111 unsigned short topClip;
112 unsigned short leftClip;
113 unsigned short srcHeight;
114 unsigned short srcWidth;
115 unsigned int srcBufStart1;
116 unsigned int srcBufStart2;
117 unsigned short srcOffset;
118 unsigned short fifoControl;
123 * Register values for common video modes
125 static char SMI_SCR[] = {
127 0x10, 0xff, 0x11, 0xff, 0x12, 0xff, 0x13, 0xff, 0x15, 0x90,
128 0x17, 0x20, 0x18, 0xb1, 0x19, 0x00,
130 static char SMI_EXT_CRT[] = {
131 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
132 0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00,
134 static char SMI_ATTR [] = {
135 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05,
136 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b,
137 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x41, 0x11, 0x00,
138 0x12, 0x0f, 0x13, 0x00, 0x14, 0x00,
140 static char SMI_GCR[18] = {
141 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x40,
142 0x06, 0x05, 0x07, 0x0f, 0x08, 0xff,
144 static char SMI_SEQR[] = {
145 0x00, 0x00, 0x01, 0x01, 0x02, 0x0f, 0x03, 0x03, 0x04, 0x0e, 0x00, 0x03,
147 static char SMI_PCR [] = {
148 0x20, 0x04, 0x21, 0x30, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00,
150 static char SMI_MCR[] = {
151 0x60, 0x01, 0x61, 0x00,
152 #ifdef CONFIG_HMI1001
153 0x62, 0x74, /* Memory type is not configured by pins on HMI1001 */
157 static char SMI_HCR[] = {
158 0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
159 0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00,
163 /*******************************************************************************
165 * Write SMI ISA register
167 static void smiWrite (unsigned short index, char reg, char val)
169 register GraphicDevice *pGD = (GraphicDevice *)&smi;
171 out8 ((pGD->isaBase + index), reg);
172 out8 ((pGD->isaBase + index + 1), val);
175 /*******************************************************************************
177 * Write a table of SMI ISA register
179 static void smiLoadRegs (
186 register GraphicDevice *pGD = (GraphicDevice *)&smi;
189 for (i=0; i<tabSize; i+=2) {
190 if (iReg == SMI_INDX_ATTR) {
191 /* Reset the Flip Flop */
193 out8 (iReg, regTab[i]);
194 out8 (iReg, regTab[i+1]);
196 out8 (iReg, regTab[i]);
197 out8 (dReg, regTab[i+1]);
202 /*******************************************************************************
204 * Init capture port registers
206 static void smiInitCapturePort (void)
208 SmiCapturePort smiCP = { 0x01400600, 0x30, 0x40, 480, 640, 0, 0, 2560, 6 };
209 register GraphicDevice *pGD = (GraphicDevice *)&smi;
210 register SmiCapturePort *pCP = (SmiCapturePort *)&smiCP;
212 out32r ((pGD->cprBase + 0x0004), ((pCP->topClip<<16) | pCP->leftClip));
213 out32r ((pGD->cprBase + 0x0008), ((pCP->srcHeight<<16) | pCP->srcWidth));
214 out32r ((pGD->cprBase + 0x000c), pCP->srcBufStart1/8);
215 out32r ((pGD->cprBase + 0x0010), pCP->srcBufStart2/8);
216 out32r ((pGD->cprBase + 0x0014), pCP->srcOffset/8);
217 out32r ((pGD->cprBase + 0x0018), pCP->fifoControl);
218 out32r ((pGD->cprBase + 0x0000), pCP->control);
222 /*******************************************************************************
224 * Init video processor registers
226 static void smiInitVideoProcessor (void)
228 SmiVideoProc smiVP = { 0x100000, 0, 0, 0, 0, 1600, 0x1200543, 4, 0xededed };
229 SmiVideoWin smiVW = { 0, 0, 599, 799, 0, 1600, 0, 0, 0 };
230 register GraphicDevice *pGD = (GraphicDevice *)&smi;
231 register SmiVideoProc *pVP = (SmiVideoProc *)&smiVP;
232 register SmiVideoWin *pVWin = (SmiVideoWin *)&smiVW;
234 pVP->width = pGD->plnSizeX * pGD->gdfBytesPP;
235 pVP->control |= pGD->gdfIndex << 16;
236 pVWin->bottom = pGD->winSizeY - 1;
237 pVWin->right = pGD->winSizeX - 1;
238 pVWin->width = pVP->width;
241 out32r ((pGD->vprBase + 0x0004), pVP->colorKey);
244 out32r ((pGD->vprBase + 0x0008), pVP->colorKeyMask);
246 /* data src start adrs */
247 out32r ((pGD->vprBase + 0x000c), pVP->start / 8);
249 /* data width and offset */
250 out32r ((pGD->vprBase + 0x0010),
251 ((pVP->offset / 8 * pGD->gdfBytesPP) << 16) |
252 (pGD->plnSizeX / 8 * pGD->gdfBytesPP));
255 out32r ((pGD->vprBase + 0x0014),
256 ((pVWin->top << 16) | pVWin->left));
258 out32r ((pGD->vprBase + 0x0018),
259 ((pVWin->bottom << 16) | pVWin->right));
261 out32r ((pGD->vprBase + 0x001c), pVWin->srcStart / 8);
263 out32r ((pGD->vprBase + 0x0020),
264 (((pVWin->offset / 8) << 16) | (pVWin->width / 8)));
266 out32r ((pGD->vprBase + 0x0024),
267 (((pVWin->hStretch) << 8) | pVWin->vStretch));
270 out32r ((pGD->vprBase + 0x0028),
271 ((pVWin->top << 16) | pVWin->left));
273 out32r ((pGD->vprBase + 0x002c),
274 ((pVWin->bottom << 16) | pVWin->right));
276 out32r ((pGD->vprBase + 0x0030),
277 pVWin->srcStart / 8);
279 out32r ((pGD->vprBase + 0x0034),
280 (((pVWin->offset / 8) << 16) | (pVWin->width / 8)));
282 out32r ((pGD->vprBase + 0x0038),
283 (((pVWin->hStretch) << 8) | pVWin->vStretch));
285 /* fifo prio control */
286 out32r ((pGD->vprBase + 0x0054), pVP->fifoPrio);
288 /* fifo empty request levell */
289 out32r ((pGD->vprBase + 0x0058), pVP->fifoERL);
291 /* conversion constant */
292 out32r ((pGD->vprBase + 0x005c), pVP->YUVtoRGB);
294 /* vpr control word */
295 out32r ((pGD->vprBase + 0x0000), pVP->control);
298 /******************************************************************************
300 * Init drawing engine registers
302 static void smiInitDrawingEngine (void)
304 GraphicDevice *pGD = (GraphicDevice *)&smi;
307 /* don't start now */
308 out32r ((pGD->dprBase + 0x000c), 0x000f0000);
310 /* set rop2 to copypen */
311 val = 0xffff3ff0 & in32r ((pGD->dprBase + 0x000c));
312 out32r ((pGD->dprBase + 0x000c), (val | 0x8000 | 0x0c));
315 out32r ((pGD->dprBase + 0x002c), 0);
316 out32r ((pGD->dprBase + 0x0030),
317 ((pGD->winSizeY<<16) | pGD->winSizeX * pGD->gdfBytesPP ));
320 val = 0xffff0000 & (in32r ((pGD->dprBase + 0x0010)));
321 out32r ((pGD->dprBase + 0x0010),
322 (val | pGD->plnSizeX * pGD->gdfBytesPP));
325 val = 0x0000ffff & (in32r ((pGD->dprBase + 0x0010)));
326 out32r ((pGD->dprBase + 0x0010),
327 (((pGD->plnSizeX * pGD->gdfBytesPP)<<16) | val));
329 /* window width src/dst */
330 out32r ((pGD->dprBase + 0x003c),
331 (((pGD->plnSizeX * pGD->gdfBytesPP & 0x0fff)<<16) |
332 (pGD->plnSizeX * pGD->gdfBytesPP & 0x0fff)));
333 out16r ((pGD->dprBase + 0x001e), 0x0000);
336 out32r ((pGD->dprBase + 0x0040),
337 (((pGD->frameAdrs/8) & 0x000fffff)));
340 out32r ((pGD->dprBase + 0x0044),
341 (((pGD->frameAdrs/8) & 0x000fffff)));
343 /* foreground color */
344 out32r ((pGD->dprBase + 0x0014), pGD->fg);
346 /* background color */
347 out32r ((pGD->dprBase + 0x0018), pGD->bg);
350 out32r ((pGD->dprBase + 0x0020), 0x00ffffff);
353 out32r ((pGD->dprBase + 0x0024), 0x00ffffff);
356 out32r ((pGD->dprBase + 0x0028), 0x00ffffff);
358 /* load mono pattern */
359 out32r ((pGD->dprBase + 0x0034), 0);
360 out32r ((pGD->dprBase + 0x0038), 0);
363 static struct pci_device_id supported[] = {
364 { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_710 },
365 { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_712 },
366 { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_810 },
370 /*****************************************************************************/
371 static void smiLoadMsr (struct ctfb_res_modes *mode)
373 unsigned char h_synch_high, v_synch_high;
374 register GraphicDevice *pGD = (GraphicDevice *)&smi;
376 h_synch_high = (mode->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 0x40; /* horizontal Synch High active */
377 v_synch_high = (mode->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 0x80; /* vertical Synch High active */
378 out8 (SMI_MISC_REG, (h_synch_high | v_synch_high | 0x29));
379 /* upper64K==0x20, CLC2select==0x08, RAMenable==0x02!(todo), CGA==0x01
380 * Selects the upper 64KB page.Bit5=1
381 * CLK2 (left reserved in standard VGA) Bit3|2=1|0
382 * Disables CPU access to frame buffer. Bit1=0
383 * Sets the I/O address decode for ST01, FCR, and all CR registers
384 * to the 3Dx I/O address range (CGA emulation). Bit0=1
387 /*****************************************************************************/
388 static void smiLoadCrt (struct ctfb_res_modes *var, int bits_per_pixel)
390 unsigned char cr[0x7a];
392 unsigned int hd, hs, he, ht, hbs, hbe; /* Horizontal. */
393 unsigned int vd, vs, ve, vt, vbs, vbe; /* vertical */
394 unsigned int bpp, wd, dblscan, interlaced;
396 const int LineCompare = 0x3ff;
397 unsigned int TextScanLines = 1; /* this is in fact a vertical zoom factor */
398 register GraphicDevice *pGD = (GraphicDevice *)&smi;
401 hd = (var->xres) / 8; /* HDisp. */
402 hs = (var->xres + var->right_margin) / 8; /* HsStrt */
403 he = (var->xres + var->right_margin + var->hsync_len) / 8; /* HsEnd */
404 ht = (var->left_margin + var->xres + var->right_margin + var->hsync_len) / 8; /* HTotal */
407 hbe = 0; /* Blank end at 0 */
410 vd = var->yres; /* VDisplay */
411 vs = var->yres + var->lower_margin; /* VSyncStart */
412 ve = var->yres + var->lower_margin + var->vsync_len; /* VSyncEnd */
413 vt = var->upper_margin + var->yres + var->lower_margin + var->vsync_len; /* VTotal */
417 bpp = bits_per_pixel;
418 dblscan = (var->vmode & FB_VMODE_DOUBLE) ? 1 : 0;
419 interlaced = var->vmode & FB_VMODE_INTERLACED;
424 wd = var->xres * bpp / 64; /* double words per line */
425 if (interlaced) { /* we divide all vertical timings, exept vd */
432 memset (cr, 0, sizeof (cr));
436 cr[0x03] = (hbe & 0x1F);
438 cr[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f);
440 cr[0x06] = (vt - 2) & 0xFF;
441 cr[0x07] = (((vt - 2) & 0x100) >> 8)
442 | (((vd - 1) & 0x100) >> 7)
443 | ((vs & 0x100) >> 6)
444 | (((vbs - 1) & 0x100) >> 5)
445 | ((LineCompare & 0x100) >> 4)
446 | (((vt - 2) & 0x200) >> 4)
447 | (((vd - 1) & 0x200) >> 3)
448 | ((vs & 0x200) >> 2);
450 cr[0x30] = ((vt - 2) & 0x400) >> 7
451 | (((vd - 1) & 0x400) >> 8)
452 | (((vbs - 1) & 0x400) >> 9)
453 | ((vs & 0x400) >> 10)
454 | (interlaced) ? 0x80 : 0;
458 cr[0x09] = (dblscan << 7)
459 | ((LineCompare & 0x200) >> 3)
460 | (((vbs - 1) & 0x200) >> 4)
461 | (TextScanLines - 1);
463 cr[0x10] = vs & 0xff; /* VSyncPulseStart */
464 cr[0x11] = (ve & 0x0f);
465 cr[0x12] = (vd - 1) & 0xff; /* LineCount */
466 cr[0x13] = wd & 0xff;
468 cr[0x15] = (vbs - 1) & 0xff;
469 cr[0x16] = vbe & 0xff;
470 cr[0x17] = 0xe3; /* but it does not work */
471 cr[0x18] = 0xff & LineCompare;
472 cr[0x22] = 0x00; /* todo? */
475 /* now set the registers */
476 for (i = 0; i <= 0x18; i++) { /*CR00 .. CR18 */
477 smiWrite (SMI_INDX_D4, i, cr[i]);
480 smiWrite (SMI_INDX_D4, i, cr[i]);
482 smiWrite (SMI_INDX_D4, i, cr[i]);
485 /*****************************************************************************/
486 #define REF_FREQ 14318180
492 static unsigned int FindPQ (unsigned int freq, unsigned int *pp, unsigned int *pq)
494 unsigned int n = QMIN, m = 0;
495 long long int L = 0, P = freq, Q = REF_FREQ, H = P >> 1;
496 long long int D = 0x7ffffffffffffffLL;
498 for (n = QMIN; n <= QMAX; n++) {
499 m = PMIN; /* p/q ~ freq/ref -> p*ref-freq*q ~ 0 */
501 while (L > 0 && m < PMAX) {
502 L -= REF_FREQ; /* difference is greater as 0 subtract fref */
503 m++; /* and increment m */
505 /* difference is less or equal than 0 or m > maximum */
507 break; /* no solution: if we increase n we get the same situation */
509 if (-L > H && m > PMIN) { /* if difference > the half fref */
510 L += REF_FREQ; /* we take the situation before */
511 m--; /* because its closer to 0 */
513 L = (L < 0) ? -L : +L; /* absolute value */
514 if (D < L) /* if last difference was better take next n */
518 *pq = n; /* keep improved data */
520 break; /* best result we can get */
522 return (unsigned int) (0xffffffff & D);
525 /*****************************************************************************/
526 static void smiLoadCcr (struct ctfb_res_modes *var, unsigned short device_id)
530 register GraphicDevice *pGD = (GraphicDevice *)&smi;
532 smiWrite (SMI_INDX_C4, 0x65, 0);
533 smiWrite (SMI_INDX_C4, 0x66, 0);
534 smiWrite (SMI_INDX_C4, 0x68, 0x50);
535 if (device_id == PCI_DEVICE_ID_SMI_810) {
536 smiWrite (SMI_INDX_C4, 0x69, 0x3);
538 smiWrite (SMI_INDX_C4, 0x69, 0x0);
543 case PCI_DEVICE_ID_SMI_710 :
544 smiWrite (SMI_INDX_C4, 0x6a, 0x75);
546 case PCI_DEVICE_ID_SMI_712 :
547 smiWrite (SMI_INDX_C4, 0x6a, 0x80);
550 smiWrite (SMI_INDX_C4, 0x6a, 0x53);
553 smiWrite (SMI_INDX_C4, 0x6b, 0x15);
556 freq = 1000000000000LL / var -> pixclock;
558 FindPQ ((unsigned int)freq, &p, &q);
560 smiWrite (SMI_INDX_C4, 0x6c, p);
561 smiWrite (SMI_INDX_C4, 0x6d, q);
565 /*******************************************************************************
567 * Init video chip with common Linux graphic modes (lilo)
569 void *video_hw_init (void)
571 GraphicDevice *pGD = (GraphicDevice *)&smi;
572 unsigned short device_id;
575 unsigned long t1, hsynch, vsynch;
576 unsigned int pci_mem_base, *vm;
578 int tmp, i, bits_per_pixel;
579 struct ctfb_res_modes *res_mode;
580 struct ctfb_res_modes var_mode;
581 unsigned char videoout;
583 /* Search for video chip */
586 if ((devbusfn = pci_find_devices(supported, 0)) < 0)
588 printf ("Controller not found !\n");
593 pci_write_config_dword (devbusfn, PCI_COMMAND, (PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
594 pci_read_config_word (devbusfn, PCI_DEVICE_ID, &device_id);
595 pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &pci_mem_base);
596 pci_mem_base = pci_mem_to_phys (devbusfn, pci_mem_base);
600 videomode = CFG_DEFAULT_VIDEO_MODE;
601 /* get video mode via environment */
602 if ((penv = getenv ("videomode")) != NULL) {
603 /* deceide if it is a string */
604 if (penv[0] <= '9') {
605 videomode = (int) simple_strtoul (penv, NULL, 16);
612 /* parameter are vesa modes */
614 for (i = 0; i < VESA_MODES_COUNT; i++) {
615 if (vesa_modes[i].vesanr == videomode)
618 if (i == VESA_MODES_COUNT) {
619 printf ("no VESA Mode found, switching to mode 0x%x ", CFG_DEFAULT_VIDEO_MODE);
623 (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].
625 bits_per_pixel = vesa_modes[i].bits_per_pixel;
628 res_mode = (struct ctfb_res_modes *) &var_mode;
629 bits_per_pixel = video_get_params (res_mode, penv);
632 /* calculate hsynch and vsynch freq (info only) */
633 t1 = (res_mode->left_margin + res_mode->xres +
634 res_mode->right_margin + res_mode->hsync_len) / 8;
636 t1 *= res_mode->pixclock;
638 hsynch = 1000000000L / t1;
640 (res_mode->upper_margin + res_mode->yres +
641 res_mode->lower_margin + res_mode->vsync_len);
643 vsynch = 1000000000L / t1;
645 /* fill in Graphic device struct */
646 sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
647 res_mode->yres, bits_per_pixel, (hsynch / 1000),
649 printf ("%s\n", pGD->modeIdent);
650 pGD->winSizeX = res_mode->xres;
651 pGD->winSizeY = res_mode->yres;
652 pGD->plnSizeX = res_mode->xres;
653 pGD->plnSizeY = res_mode->yres;
654 switch (bits_per_pixel) {
657 pGD->gdfIndex = GDF__8BIT_INDEX;
661 pGD->gdfIndex = GDF_15BIT_555RGB;
665 pGD->gdfIndex = GDF_16BIT_565RGB;
669 pGD->gdfIndex = GDF_24BIT_888RGB;
673 pGD->isaBase = CFG_ISA_IO;
674 pGD->pciBase = pci_mem_base;
675 pGD->dprBase = (pci_mem_base + 0x400000 + 0x8000);
676 pGD->vprBase = (pci_mem_base + 0x400000 + 0xc000);
677 pGD->cprBase = (pci_mem_base + 0x400000 + 0xe000);
678 pGD->frameAdrs = pci_mem_base;
679 pGD->memSize = VIDEO_MEM_SIZE;
681 /* Set up hardware : select color mode,
682 set Register base to isa 3dx for 3?x regs*/
683 out8 (SMI_MISC_REG, 0x01);
685 /* Turn off display */
686 smiWrite (SMI_INDX_C4, 0x01, 0x20);
688 /* Unlock ext. crt regs */
689 out8 (SMI_LOCK_REG, 0x40);
691 /* Unlock crt regs 0-7 */
692 smiWrite (SMI_INDX_D4, 0x11, 0x0e);
694 /* Sytem Control Register */
695 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_SCR, sizeof(SMI_SCR));
697 /* extented CRT Register */
698 smiLoadRegs (SMI_INDX_D4, SMI_DATA_D5, SMI_EXT_CRT, sizeof(SMI_EXT_CRT));
700 /* Attributes controller registers */
701 smiLoadRegs (SMI_INDX_ATTR, SMI_INDX_ATTR, SMI_ATTR, sizeof(SMI_ATTR));
703 /* Graphics Controller Register */
704 smiLoadRegs (SMI_INDX_CE, SMI_DATA_CF, SMI_GCR, sizeof(SMI_GCR));
706 /* Sequencer Register */
707 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_SEQR, sizeof(SMI_SEQR));
709 /* Power Control Register */
710 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_PCR, sizeof(SMI_PCR));
712 /* Memory Control Register */
713 /* Register MSR62 is a power on configurable register. We don't */
715 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_MCR, sizeof(SMI_MCR));
717 /* Set misc output register */
718 smiLoadMsr (res_mode);
720 /* Set CRT and Clock control registers */
721 smiLoadCrt (res_mode, bits_per_pixel);
723 smiLoadCcr (res_mode, device_id);
725 /* Hardware Cusor Register */
726 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_HCR, sizeof(SMI_HCR));
729 videoout = 2; /* Default output is CRT */
730 if ((penv = getenv ("videoout")) != NULL) {
731 /* deceide if it is a string */
732 videoout = (int) simple_strtoul (penv, NULL, 16);
734 smiWrite (SMI_INDX_C4, 0x31, videoout);
736 /* Video processor default setup */
737 smiInitVideoProcessor ();
739 /* Capture port default setup */
740 smiInitCapturePort ();
742 /* Drawing engine default setup */
743 smiInitDrawingEngine ();
745 /* Turn on display */
746 smiWrite (0x3c4, 0x01, 0x01);
748 /* Clear video memory */
750 vm = (unsigned int *)pGD->pciBase;
753 return ((void*)&smi);
756 /*******************************************************************************
758 * Drawing engine fill on screen region
760 void video_hw_rectfill (
761 unsigned int bpp, /* bytes per pixel */
762 unsigned int dst_x, /* dest pos x */
763 unsigned int dst_y, /* dest pos y */
764 unsigned int dim_x, /* frame width */
765 unsigned int dim_y, /* frame height */
766 unsigned int color /* fill color */
769 register GraphicDevice *pGD = (GraphicDevice *)&smi;
770 register unsigned int control;
774 out32r ((pGD->dprBase + 0x0014), color);
775 out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y));
776 out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y));
778 control = 0x0000ffff & in32r ((pGD->dprBase + 0x000c));
780 control |= 0x80010000;
782 out32r ((pGD->dprBase + 0x000c), control);
784 /* Wait for drawing processor */
787 out8 ((pGD->isaBase + 0x3c4), 0x16);
788 } while (in8 (pGD->isaBase + 0x3c5) & 0x08);
791 /*******************************************************************************
793 * Drawing engine bitblt with screen region
795 void video_hw_bitblt (
796 unsigned int bpp, /* bytes per pixel */
797 unsigned int src_x, /* source pos x */
798 unsigned int src_y, /* source pos y */
799 unsigned int dst_x, /* dest pos x */
800 unsigned int dst_y, /* dest pos y */
801 unsigned int dim_x, /* frame width */
802 unsigned int dim_y /* frame height */
805 register GraphicDevice *pGD = (GraphicDevice *)&smi;
806 register unsigned int control;
810 if ((src_y<dst_y) || ((src_y==dst_y) && (src_x<dst_x)))
812 out32r ((pGD->dprBase + 0x0000), (((src_x+dim_x-1)<<16) | (src_y+dim_y-1)));
813 out32r ((pGD->dprBase + 0x0004), (((dst_x+dim_x-1)<<16) | (dst_y+dim_y-1)));
814 control = 0x88000000;
816 out32r ((pGD->dprBase + 0x0000), ((src_x<<16) | src_y));
817 out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y));
818 control = 0x80000000;
821 out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y));
822 control |= (0x0000ffff & in32r ((pGD->dprBase + 0x000c)));
823 out32r ((pGD->dprBase + 0x000c), control);
825 /* Wait for drawing processor */
828 out8 ((pGD->isaBase + 0x3c4), 0x16);
829 } while (in8 (pGD->isaBase + 0x3c5) & 0x08);
832 /*******************************************************************************
834 * Set a RGB color in the LUT (8 bit index)
837 unsigned int index, /* color number */
838 unsigned char r, /* red */
839 unsigned char g, /* green */
840 unsigned char b /* blue */
843 register GraphicDevice *pGD = (GraphicDevice *)&smi;
845 out8 (SMI_LUT_MASK, 0xff);
847 out8 (SMI_LUT_START, (char)index);
849 out8 (SMI_LUT_RGB, r>>2); /* red */
851 out8 (SMI_LUT_RGB, g>>2); /* green */
853 out8 (SMI_LUT_RGB, b>>2); /* blue */
857 #endif /* CONFIG_VIDEO_SMI_LYNXEM */