1
2
3
4
5
6
7
8
9
10#include <common.h>
11
12#ifdef CONFIG_VIDEO
13
14#include <pci.h>
15#include <video_fb.h>
16#include "videomodes.h"
17
18
19#undef VGA_DEBUG
20#undef VGA_DUMP_REG
21#ifdef VGA_DEBUG
22#undef _DEBUG
23#define _DEBUG 1
24#else
25#undef _DEBUG
26#define _DEBUG 0
27#endif
28
29
30#ifndef min
31#define min( a, b ) ( ( a ) < ( b ) ) ? ( a ) : ( b )
32#endif
33#ifndef max
34#define max( a, b ) ( ( a ) > ( b ) ) ? ( a ) : ( b )
35#endif
36#ifdef minmax
37#error "term minmax already used."
38#endif
39#define minmax( a, x, b ) max( ( a ), min( ( x ), ( b ) ) )
40#define N_ELTS( x ) ( sizeof( x ) / sizeof( x[ 0 ] ) )
41
42
43#define CT_AR_O 0x3c0
44#define CT_GR_O 0x3ce
45#define CT_SR_O 0x3c4
46#define CT_CR_O 0x3d4
47#define CT_XR_O 0x3d6
48#define CT_MSR_W_O 0x3c2
49#define CT_LUT_MASK_O 0x3c6
50#define CT_LUT_START_O 0x3c8
51#define CT_LUT_RGB_O 0x3c9
52#define CT_STATUS_REG0_O 0x3c2
53#define CT_STATUS_REG1_O 0x3da
54
55#define CT_FP_O 0x3d0
56#define CT_MR_O 0x3d2
57
58
59#define BR00_o 0x400000
60#define BR01_o 0x400004
61#define BR02_o 0x400008
62#define BR03_o 0x40000C
63#define BR04_o 0x400010
64#define BR05_o 0x400014
65#define BR06_o 0x400018
66#define BR07_o 0x40001C
67#define BR08_o 0x400020
68#define BR09_o 0x400024
69#define BR0A_o 0x400028
70
71#define CURSOR_SIZE 0x1000
72#define PATTERN_ADR (pGD->dprBase + CURSOR_SIZE)
73#define PATTERN_SIZE 8*8*4
74#define ACCELMEMORY (CURSOR_SIZE + PATTERN_SIZE)
75
76
77#define FB_SYNC_HOR_HIGH_ACT 1
78#define FB_SYNC_VERT_HIGH_ACT 2
79#define FB_SYNC_EXT 4
80#define FB_SYNC_COMP_HIGH_ACT 8
81#define FB_SYNC_BROADCAST 16
82
83
84#define FB_SYNC_ON_GREEN 32
85
86#define FB_VMODE_NONINTERLACED 0
87#define FB_VMODE_INTERLACED 1
88#define FB_VMODE_DOUBLE 2
89#define FB_VMODE_MASK 255
90
91#define FB_VMODE_YWRAP 256
92#define FB_VMODE_SMOOTH_XPAN 512
93#define FB_VMODE_CONUPDATE 512
94
95#define text 0
96#define fntwidth 8
97
98
99typedef struct {
100 const unsigned char reg;
101 const unsigned char val;
102} CT_CFG_TABLE;
103
104
105static CT_CFG_TABLE xreg[] = {
106 {0x09, 0x01},
107 {0x0A, 0x02},
108 {0x0B, 0x01},
109 {0x20, 0x00},
110 {0x40, 0x03},
111 {0x60, 0x00},
112 {0x61, 0x00},
113 {0x62, 0x00},
114 {0x63, 0xBD},
115 {0x67, 0x00},
116 {0x80, 0x80},
117 {0xA0, 0x00},
118 {0xA1, 0x00},
119 {0xA2, 0x00},
120 {0xA3, 0x00},
121 {0xA4, 0x00},
122 {0xA5, 0x00},
123 {0xA6, 0x00},
124 {0xA7, 0x00},
125 {0xA8, 0x00},
126 {0xA9, 0x00},
127 {0xAA, 0x00},
128 {0xAB, 0x00},
129 {0xAC, 0x00},
130 {0xAD, 0x00},
131 {0xAE, 0x00},
132 {0xAF, 0x00},
133 {0xC0, 0x7D},
134 {0xC1, 0x07},
135 {0xC3, 0x34},
136 {0xC4, 0x55},
137 {0xC5, 0x09},
138 {0xC7, 0x24},
139 {0xC8, 0x7D},
140 {0xC9, 0x07},
141 {0xCB, 0x34},
142 {0xCC, 0x38},
143 {0xCD, 0x03},
144 {0xCE, 0x90},
145 {0xCF, 0x06},
146 {0xD0, 0x0F},
147 {0xD1, 0x01},
148 {0xFF, 0xFF}
149};
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245struct ctfb_chips_properties {
246 int device_id;
247 unsigned long max_mem;
248 int vld_set;
249 int vld_not_set;
250 int mn_diff;
251 int mn_min;
252 int mn_max;
253 int vco_min;
254 int vco_max;
255};
256
257static const struct ctfb_chips_properties chips[] = {
258 {PCI_DEVICE_ID_CT_69000, 0x200000, 1, 4, -2, 3, 257, 100, 220},
259 {PCI_DEVICE_ID_CT_65555, 0x100000, 16, 4, 0, 1, 255, 48, 220},
260 {0, 0, 0, 0, 0, 0, 0, 0, 0}
261};
262
263
264
265
266GraphicDevice ctfb;
267
268
269
270
271
272
273
274
275
276
277#ifdef VGA_DEBUG
278static unsigned char
279ctRead (unsigned short index)
280{
281 GraphicDevice *pGD = (GraphicDevice *) & ctfb;
282 if (index == CT_AR_O)
283
284 in8 (pGD->isaBase + CT_STATUS_REG1_O);
285
286 return (in8 (pGD->isaBase + index));
287}
288#endif
289
290
291
292
293static void
294ctWrite (unsigned short index, unsigned char val)
295{
296 GraphicDevice *pGD = (GraphicDevice *) & ctfb;
297
298 out8 ((pGD->isaBase + index), val);
299}
300
301
302
303
304
305static unsigned char
306ctRead_i (unsigned short index, char reg)
307{
308 GraphicDevice *pGD = (GraphicDevice *) & ctfb;
309 if (index == CT_AR_O)
310
311 in8 (pGD->isaBase + CT_STATUS_REG1_O);
312 out8 ((pGD->isaBase + index), reg);
313 return (in8 (pGD->isaBase + index + 1));
314}
315
316
317
318
319
320static void
321ctWrite_i (unsigned short index, char reg, char val)
322{
323 GraphicDevice *pGD = (GraphicDevice *) & ctfb;
324 if (index == CT_AR_O) {
325
326 in8 (pGD->isaBase + CT_STATUS_REG1_O);
327 out8 ((pGD->isaBase + index), reg);
328 out8 ((pGD->isaBase + index), val);
329 } else {
330 out8 ((pGD->isaBase + index), reg);
331 out8 ((pGD->isaBase + index + 1), val);
332 }
333}
334
335
336
337
338
339static void
340ctLoadRegs (unsigned short index, CT_CFG_TABLE * regTab)
341{
342 while (regTab->reg != 0xFF) {
343 ctWrite_i (index, regTab->reg, regTab->val);
344 regTab++;
345 }
346}
347
348
349static void
350SetArRegs (void)
351{
352 int i, tmp;
353
354 for (i = 0; i < 0x10; i++)
355 ctWrite_i (CT_AR_O, i, i);
356 if (text)
357 tmp = 0x04;
358 else
359 tmp = 0x41;
360
361 ctWrite_i (CT_AR_O, 0x10, tmp);
362 ctWrite_i (CT_AR_O, 0x11, 0x00);
363 ctWrite_i (CT_AR_O, 0x12, 0x0f);
364 if (fntwidth == 9)
365 tmp = 0x08;
366 else
367 tmp = 0x00;
368 ctWrite_i (CT_AR_O, 0x13, tmp);
369 ctWrite_i (CT_AR_O, 0x14, 0x00);
370 ctWrite (CT_AR_O, 0x20);
371}
372
373
374static void
375SetGrRegs (void)
376{
377 int i;
378
379 for (i = 0; i < 0x05; i++)
380 ctWrite_i (CT_GR_O, i, 0);
381 if (text) {
382 ctWrite_i (CT_GR_O, 0x05, 0x10);
383 ctWrite_i (CT_GR_O, 0x06, 0x02);
384 } else {
385 ctWrite_i (CT_GR_O, 0x05, 0x40);
386 ctWrite_i (CT_GR_O, 0x06, 0x05);
387 }
388 ctWrite_i (CT_GR_O, 0x07, 0x0f);
389 ctWrite_i (CT_GR_O, 0x08, 0xff);
390}
391
392
393static void
394SetSrRegs (void)
395{
396 int tmp = 0;
397
398 ctWrite_i (CT_SR_O, 0x00, 0x00);
399
400
401
402 if (fntwidth == 8)
403 ctWrite_i (CT_SR_O, 0x01, 0x01);
404 else
405 ctWrite_i (CT_SR_O, 0x01, 0x00);
406 ctWrite_i (CT_SR_O, 0x02, 0x0f);
407 ctWrite_i (CT_SR_O, 0x03, 0x00);
408 if (text)
409 tmp = 0x02;
410 else
411 tmp = 0x0e;
412 ctWrite_i (CT_SR_O, 0x04, tmp);
413
414
415 ctWrite_i (CT_SR_O, 0x00, 0x03);
416}
417
418
419static void
420SetBitsPerPixelIntoXrRegs (int bpp)
421{
422 unsigned int n = (bpp >> 3), tmp;
423 static char md[4] = { 0x04, 0x02, 0x05, 0x06 };
424 static char off[4] = { ~0x20, ~0x30, ~0x20, ~0x10 };
425 static char on[4] = { 0x10, 0x00, 0x10, 0x20 };
426 if (bpp == 15)
427 n = 0;
428 tmp = ctRead_i (CT_XR_O, 0x20);
429 tmp &= off[n];
430 tmp |= on[n];
431 ctWrite_i (CT_XR_O, 0x20, tmp);
432 ctWrite_i (CT_XR_O, 0x81, md[n]);
433}
434
435
436static void
437SetCrRegs (struct ctfb_res_modes *var, int bits_per_pixel)
438{
439 unsigned char cr[0x7a];
440 int i, tmp;
441 unsigned int hd, hs, he, ht, hbe;
442 unsigned int vd, vs, ve, vt;
443 unsigned int bpp, wd, dblscan, interlaced, bcast, CrtHalfLine;
444 unsigned int CompSyncCharClkDelay, CompSyncPixelClkDelay;
445 unsigned int NTSC_PAL_HorizontalPulseWidth, BlDelayCtrl;
446 unsigned int HorizontalEqualizationPulses;
447 unsigned int HorizontalSerration1Start, HorizontalSerration2Start;
448
449 const int LineCompare = 0x3ff;
450 unsigned int TextScanLines = 1;
451 unsigned int RAMDAC_BlankPedestalEnable = 0;
452
453 hd = (var->xres) / 8;
454 hs = (var->xres + var->right_margin) / 8;
455 he = (var->xres + var->right_margin + var->hsync_len) / 8;
456 ht = (var->left_margin + var->xres + var->right_margin + var->hsync_len) / 8;
457 hbe = ht - 1;
458
459 vd = var->yres;
460 vs = var->yres + var->lower_margin;
461 ve = var->yres + var->lower_margin + var->vsync_len;
462 vt = var->upper_margin + var->yres + var->lower_margin + var->vsync_len;
463 bpp = bits_per_pixel;
464 dblscan = (var->vmode & FB_VMODE_DOUBLE) ? 1 : 0;
465 interlaced = var->vmode & FB_VMODE_INTERLACED;
466 bcast = var->sync & FB_SYNC_BROADCAST;
467 CrtHalfLine = bcast ? (hd >> 1) : 0;
468 BlDelayCtrl = bcast ? 1 : 0;
469 CompSyncCharClkDelay = 0;
470 CompSyncPixelClkDelay = 0;
471 if (bcast) {
472 NTSC_PAL_HorizontalPulseWidth = 7;
473 HorizontalEqualizationPulses = 0;
474 HorizontalSerration1Start = 31;
475 HorizontalSerration2Start = 89;
476 } else {
477 NTSC_PAL_HorizontalPulseWidth = 0;
478
479
480 HorizontalEqualizationPulses = 1;
481 HorizontalSerration1Start = 0;
482 HorizontalSerration2Start = 0;
483 }
484
485 if (bpp == 15)
486 bpp = 16;
487 wd = var->xres * bpp / 64;
488 if (interlaced) {
489 vs >>= 1;
490 ve >>= 1;
491 vt >>= 1;
492 }
493 memset (cr, 0, sizeof (cr));
494 cr[0x00] = 0xff & (ht - 5);
495 cr[0x01] = hd - 1;
496 cr[0x02] = hd;
497 cr[0x03] = (hbe & 0x1F) | 0x80;
498 cr[0x04] = hs;
499 cr[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f);
500 cr[0x06] = (vt - 2) & 0xFF;
501 cr[0x30] = (vt - 2) >> 8;
502 cr[0x07] = ((vt & 0x100) >> 8)
503 | ((vd & 0x100) >> 7)
504 | ((vs & 0x100) >> 6)
505 | ((vs & 0x100) >> 5)
506 | ((LineCompare & 0x100) >> 4)
507 | ((vt & 0x200) >> 4)
508 | ((vd & 0x200) >> 3)
509 | ((vs & 0x200) >> 2);
510 cr[0x08] = 0x00;
511 cr[0x09] = (dblscan << 7)
512 | ((LineCompare & 0x200) >> 3)
513 | ((vs & 0x200) >> 4)
514 | (TextScanLines - 1);
515 cr[0x10] = vs & 0xff;
516 cr[0x32] = (vs & 0xf00) >> 8;
517 cr[0x11] = (ve & 0x0f);
518 cr[0x12] = (vd - 1) & 0xff;
519 cr[0x31] = ((vd - 1) & 0xf00) >> 8;
520 cr[0x13] = wd & 0xff;
521 cr[0x41] = (wd & 0xf00) >> 8;
522 cr[0x15] = vs & 0xff;
523 cr[0x33] = (vs & 0xf00) >> 8;
524 cr[0x38] = (0x100 & (ht - 5)) >> 8;
525 cr[0x3C] = 0xc0 & hbe;
526 cr[0x16] = (vt - 1) & 0xff;
527 cr[0x17] = 0xe3;
528 cr[0x18] = 0xff & LineCompare;
529 cr[0x22] = 0xff;
530 cr[0x70] = interlaced ? (0x80 | CrtHalfLine) : 0x00;
531 cr[0x71] = 0x80 | (RAMDAC_BlankPedestalEnable << 6)
532 | (BlDelayCtrl << 5)
533 | ((0x03 & CompSyncCharClkDelay) << 3)
534 | (0x07 & CompSyncPixelClkDelay);
535 cr[0x72] = HorizontalSerration1Start;
536 cr[0x73] = HorizontalSerration2Start;
537 cr[0x74] = (HorizontalEqualizationPulses << 5)
538 | NTSC_PAL_HorizontalPulseWidth;
539
540
541 for (i = 0; i <= 0x0d; i++) {
542 ctWrite_i (CT_CR_O, i, cr[i]);
543 }
544 for (i = 0x10; i <= 0x18; i++) {
545 ctWrite_i (CT_CR_O, i, cr[i]);
546 }
547 i = 0x22;
548 ctWrite_i (CT_CR_O, i, cr[i]);
549 for (i = 0x30; i <= 0x33; i++) {
550 ctWrite_i (CT_CR_O, i, cr[i]);
551 }
552 i = 0x38;
553 ctWrite_i (CT_CR_O, i, cr[i]);
554 i = 0x3C;
555 ctWrite_i (CT_CR_O, i, cr[i]);
556 for (i = 0x40; i <= 0x41; i++) {
557 ctWrite_i (CT_CR_O, i, cr[i]);
558 }
559 for (i = 0x70; i <= 0x74; i++) {
560 ctWrite_i (CT_CR_O, i, cr[i]);
561 }
562 tmp = ctRead_i (CT_CR_O, 0x40);
563 tmp &= 0x0f;
564 tmp |= 0x80;
565 ctWrite_i (CT_CR_O, 0x40, tmp);
566}
567
568
569
570
571
572
573
574
575static unsigned int
576FindBestPQFittingMN (unsigned int p, unsigned int q, unsigned int mnmin,
577 unsigned int mnmax, unsigned int *pm, unsigned int *pn)
578{
579
580 unsigned int n = mnmin, m = 0;
581 long long int L = 0, P = p, Q = q, H = P >> 1;
582 long long int D = 0x7ffffffffffffffLL;
583 for (n = mnmin; n <= mnmax; n++) {
584 m = mnmin;
585 L = P * n - m * Q;
586 while (L > 0 && m < mnmax) {
587 L -= q;
588 m++;
589 }
590
591 if (m > mnmax)
592 break;
593
594 if (-L > H && m > mnmin) {
595 L += q;
596 m--;
597 }
598 L = (L < 0) ? -L : +L;
599 if (D < L)
600 continue;
601 D = L;
602 *pm = m;
603 *pn = n;
604 if (D == 0)
605 break;
606 }
607 return (unsigned int) (0xffffffff & D);
608}
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649#define VIDEO_FREF 14318180;
650
651static int
652ReadPixClckFromXrRegsBack (struct ctfb_chips_properties *param)
653{
654 unsigned int m, n, vld, pd, PD, fref, xr_cb, i, pixclock;
655 i = 0;
656 pixclock = -1;
657 fref = VIDEO_FREF;
658 m = ctRead_i (CT_XR_O, 0xc8);
659 n = ctRead_i (CT_XR_O, 0xc9);
660 m -= param->mn_diff;
661 n -= param->mn_diff;
662 xr_cb = ctRead_i (CT_XR_O, 0xcb);
663 PD = (0x70 & xr_cb) >> 4;
664 pd = 1;
665 for (i = 0; i < PD; i++) {
666 pd *= 2;
667 }
668 vld = (0x04 & xr_cb) ? param->vld_set : param->vld_not_set;
669 if (n * vld * m) {
670 unsigned long long p = 1000000000000LL * pd * n;
671 unsigned long long q = (long long) fref * vld * m;
672 while ((p > 0xffffffffLL) || (q > 0xffffffffLL)) {
673 p >>= 1;
674 q >>= 1;
675 }
676 pixclock = (unsigned) p / (unsigned) q;
677 } else
678 printf ("Invalid data in xr regs.\n");
679 return pixclock;
680}
681
682
683static void
684FindAndSetPllParamIntoXrRegs (unsigned int pixelclock,
685 struct ctfb_chips_properties *param)
686{
687 unsigned int m, n, vld, pd, PD, fref, xr_cb;
688 unsigned int fvcomin, fvcomax, pclckmin, pclckmax, pclk;
689 unsigned int pfreq, fvco, new_pixclock;
690 unsigned int D,nback,mback;
691
692 fref = VIDEO_FREF;
693 pd = 1;
694 PD = 0;
695 fvcomin = param->vco_min;
696 fvcomax = param->vco_max;
697 pclckmin = 1000000 / fvcomax + 1;
698 pclckmax = 32000000 / fvcomin - 1;
699 pclk = minmax (pclckmin, pixelclock, pclckmax);
700 pfreq = 250 * (4000000000U / pclk);
701 fvco = pfreq;
702 new_pixclock = 0;
703 while (fvco < fvcomin * 1000000) {
704
705
706 fvco *= 2;
707 pd *= 2;
708 PD++;
709 }
710
711
712 vld = param->vld_set;
713 D=FindBestPQFittingMN (fvco / vld, fref, param->mn_min, param->mn_max, &m, &n);
714 mback=m;
715 nback=n;
716
717 vld = param->vld_not_set;
718 if(D<FindBestPQFittingMN (fvco / vld, fref, param->mn_min, param->mn_max, &m, &n)) {
719
720 m=mback;
721 n=nback;
722 vld = param->vld_set;
723 }
724 m += param->mn_diff;
725 n += param->mn_diff;
726 debug("VCO %d, pd %d, m %d n %d vld %d\n", fvco, pd, m, n, vld);
727 xr_cb = ((0x7 & PD) << 4) | (vld == param->vld_set ? 0x04 : 0);
728
729
730
731
732 ctWrite_i (CT_XR_O, 0xc8, m);
733 ctWrite_i (CT_XR_O, 0xc9, n);
734 ctWrite_i (CT_XR_O, 0xca, 0);
735 ctWrite_i (CT_XR_O, 0xcb, xr_cb);
736 new_pixclock = ReadPixClckFromXrRegsBack (param);
737 debug("pixelclock.set = %d, pixelclock.real = %d\n",
738 pixelclock, new_pixclock);
739}
740
741
742static void
743SetMsrRegs (struct ctfb_res_modes *mode)
744{
745 unsigned char h_synch_high, v_synch_high;
746
747 h_synch_high = (mode->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 0x40;
748 v_synch_high = (mode->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 0x80;
749 ctWrite (CT_MSR_W_O, (h_synch_high | v_synch_high | 0x29));
750
751
752
753
754
755
756
757}
758
759
760#ifdef VGA_DUMP_REG
761
762static void
763ctDispRegs (unsigned short index, int from, int to)
764{
765 unsigned char status;
766 int i;
767
768 for (i = from; i < to; i++) {
769 status = ctRead_i (index, i);
770 printf ("%02X: is %02X\n", i, status);
771 }
772}
773
774void
775video_dump_reg (void)
776{
777 int i;
778
779 printf ("Extended Regs:\n");
780 ctDispRegs (CT_XR_O, 0, 0xC);
781 ctDispRegs (CT_XR_O, 0xe, 0xf);
782 ctDispRegs (CT_XR_O, 0x20, 0x21);
783 ctDispRegs (CT_XR_O, 0x40, 0x50);
784 ctDispRegs (CT_XR_O, 0x60, 0x64);
785 ctDispRegs (CT_XR_O, 0x67, 0x68);
786 ctDispRegs (CT_XR_O, 0x70, 0x72);
787 ctDispRegs (CT_XR_O, 0x80, 0x83);
788 ctDispRegs (CT_XR_O, 0xA0, 0xB0);
789 ctDispRegs (CT_XR_O, 0xC0, 0xD3);
790 printf ("Sequencer Regs:\n");
791 ctDispRegs (CT_SR_O, 0, 0x8);
792 printf ("Graphic Regs:\n");
793 ctDispRegs (CT_GR_O, 0, 0x9);
794 printf ("CRT Regs:\n");
795 ctDispRegs (CT_CR_O, 0, 0x19);
796 ctDispRegs (CT_CR_O, 0x22, 0x23);
797 ctDispRegs (CT_CR_O, 0x30, 0x34);
798 ctDispRegs (CT_CR_O, 0x38, 0x39);
799 ctDispRegs (CT_CR_O, 0x3C, 0x3D);
800 ctDispRegs (CT_CR_O, 0x40, 0x42);
801 ctDispRegs (CT_CR_O, 0x70, 0x80);
802
803}
804
805#endif
806
807#ifdef CONFIG_VIDEO_HW_CURSOR
808
809
810
811void
812video_set_hw_cursor (int x, int y)
813{
814 int sig_x = 0, sig_y = 0;
815 if (x < 0) {
816 x *= -1;
817 sig_x = 1;
818 }
819 if (y < 0) {
820 y *= -1;
821 sig_y = 1;
822 }
823 ctWrite_i (CT_XR_O, 0xa4, x & 0xff);
824 ctWrite_i (CT_XR_O, 0xa5, (x >> 8) & 0x7);
825 ctWrite_i (CT_XR_O, 0xa6, y & 0xff);
826 ctWrite_i (CT_XR_O, 0xa7, (y >> 8) & 0x7);
827}
828
829
830
831
832
833void
834video_init_hw_cursor (int font_width, int font_height)
835{
836 unsigned char xr_80;
837 unsigned long *curs, pattern;
838 int i;
839 int cursor_start;
840 GraphicDevice *pGD = (GraphicDevice *) & ctfb;
841
842 cursor_start = pGD->dprBase;
843 xr_80 = ctRead_i (CT_XR_O, 0x80);
844
845 ctWrite_i (CT_XR_O, 0xa2, (cursor_start >> 8) & 0xf0);
846 ctWrite_i (CT_XR_O, 0xa3, (cursor_start >> 16) & 0x3f);
847
848 curs = (unsigned long *) cursor_start;
849 i = 0;
850 while (i < 0x400) {
851 curs[i++] = 0xffffffff;
852 curs[i++] = 0xffffffff;
853 curs[i++] = 0;
854 curs[i++] = 0;
855
856 }
857 pattern = 0xffffffff >> font_width;
858 i = 0;
859 while (i < (font_height * 2)) {
860 curs[i++] = pattern;
861 curs[i++] = pattern;
862 curs[i++] = 0;
863 curs[i++] = 0;
864
865 }
866
867 ctWrite_i (CT_FP_O, 0x19, 0xf);
868
869
870 xr_80 = ctRead_i (CT_XR_O, 0x80);
871 xr_80 |= 0x1;
872 ctWrite_i (CT_XR_O, 0x80, xr_80);
873 video_set_lut (4, CONSOLE_FG_COL, CONSOLE_FG_COL, CONSOLE_FG_COL);
874
875 xr_80 &= 0xfe;
876 ctWrite_i (CT_XR_O, 0x80, xr_80);
877
878 ctWrite_i (CT_XR_O, 0xa0, 0x91);
879 xr_80 |= 0x10;
880 ctWrite_i (CT_XR_O, 0x80, xr_80);
881 video_set_hw_cursor (0, 0);
882}
883#endif
884
885
886
887
888static int
889video_wait_bitblt (unsigned long addr)
890{
891 unsigned long br04;
892 int i = 0;
893 br04 = in32r (addr);
894 while (br04 & 0x80000000) {
895 udelay (1);
896 br04 = in32r (addr);
897 if (i++ > 1000000) {
898 printf ("ERROR Timeout %lx\n", br04);
899 return 1;
900 }
901 }
902 return 0;
903}
904
905
906
907
908static void
909SetDrawingEngine (int bits_per_pixel)
910{
911 unsigned long br04, br00;
912 unsigned char tmp;
913
914 GraphicDevice *pGD = (GraphicDevice *) & ctfb;
915
916 tmp = ctRead_i (CT_XR_O, 0x20);
917 tmp |= 0x02;
918 ctWrite_i (CT_XR_O, 0x20, tmp);
919 udelay (10);
920 tmp &= 0xfd;
921 ctWrite_i (CT_XR_O, 0x20, tmp);
922 video_wait_bitblt (pGD->pciBase + BR04_o);
923
924
925 out32r (pGD->pciBase + BR05_o, PATTERN_ADR & 0x003ffff8);
926 br04 = 0;
927 if (bits_per_pixel == 1) {
928 br04 |= 0x00040000;
929 br04 |= 0x00001000;
930 }
931 br00 = ((pGD->winSizeX * pGD->gdfBytesPP) << 16) + (pGD->winSizeX * pGD->gdfBytesPP);
932 out32r (pGD->pciBase + BR00_o, br00);
933 out32r (pGD->pciBase + BR08_o, (10 << 16) + 10);
934 out32r (pGD->pciBase + BR04_o, br04);
935 out32r (pGD->pciBase + BR07_o, 0);
936 video_wait_bitblt (pGD->pciBase + BR04_o);
937}
938
939
940
941
942static struct pci_device_id supported[] = {
943 {PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69000},
944 {}
945};
946
947
948
949
950
951void *
952video_hw_init (void)
953{
954 GraphicDevice *pGD = (GraphicDevice *) & ctfb;
955 unsigned short device_id;
956 pci_dev_t devbusfn;
957 int videomode;
958 unsigned long t1, hsynch, vsynch;
959 unsigned int pci_mem_base, *vm;
960 int tmp, i, bits_per_pixel;
961 char *penv;
962 struct ctfb_res_modes *res_mode;
963 struct ctfb_res_modes var_mode;
964 struct ctfb_chips_properties *chips_param;
965
966
967 if ((devbusfn = pci_find_devices (supported, 0)) < 0) {
968#ifdef CONFIG_VIDEO_ONBOARD
969 printf ("Video: Controller not found !\n");
970#endif
971 return (NULL);
972 }
973
974
975 pci_write_config_dword (devbusfn, PCI_COMMAND,
976 (PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
977 pci_read_config_word (devbusfn, PCI_DEVICE_ID, &device_id);
978 pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &pci_mem_base);
979 pci_mem_base = pci_mem_to_phys (devbusfn, pci_mem_base);
980
981
982 for (chips_param = (struct ctfb_chips_properties *) &chips[0];
983 chips_param->device_id != 0; chips_param++) {
984 if (chips_param->device_id == device_id)
985 break;
986 }
987 if (chips_param->device_id == 0) {
988#ifdef CONFIG_VIDEO_ONBOARD
989 printf ("Video: controller 0x%X not supported\n", device_id);
990#endif
991 return NULL;
992 }
993
994 printf ("Video: ");
995
996 tmp = 0;
997 videomode = 0x301;
998
999 if ((penv = getenv ("videomode")) != NULL) {
1000
1001 if (penv[0] <= '9') {
1002 videomode = (int) simple_strtoul (penv, NULL, 16);
1003 tmp = 1;
1004 }
1005 } else {
1006 tmp = 1;
1007 }
1008 if (tmp) {
1009
1010
1011 for (i = 0; i < VESA_MODES_COUNT; i++) {
1012 if (vesa_modes[i].vesanr == videomode)
1013 break;
1014 }
1015 if (i == VESA_MODES_COUNT) {
1016 printf ("no VESA Mode found, switching to mode 0x301 ");
1017 i = 0;
1018 }
1019 res_mode =
1020 (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].
1021 resindex];
1022 bits_per_pixel = vesa_modes[i].bits_per_pixel;
1023 } else {
1024
1025 res_mode = (struct ctfb_res_modes *) &var_mode;
1026 bits_per_pixel = video_get_params (res_mode, penv);
1027 }
1028
1029
1030 if (bits_per_pixel == 15)
1031 tmp = 2;
1032 else
1033 tmp = bits_per_pixel >> 3;
1034 if (((chips_param->max_mem -
1035 ACCELMEMORY) / (res_mode->xres * res_mode->yres)) < tmp) {
1036 tmp =
1037 ((chips_param->max_mem -
1038 ACCELMEMORY) / (res_mode->xres * res_mode->yres));
1039 if (tmp == 0) {
1040 printf
1041 ("No matching videomode found .-> reduce resolution\n");
1042 return NULL;
1043 } else {
1044 printf ("Switching back to %d Bits per Pixel ",
1045 tmp << 3);
1046 bits_per_pixel = tmp << 3;
1047 }
1048 }
1049
1050
1051 t1 = (res_mode->left_margin + res_mode->xres +
1052 res_mode->right_margin + res_mode->hsync_len) / 8;
1053 t1 *= 8;
1054 t1 *= res_mode->pixclock;
1055 t1 /= 1000;
1056 hsynch = 1000000000L / t1;
1057 t1 *=
1058 (res_mode->upper_margin + res_mode->yres +
1059 res_mode->lower_margin + res_mode->vsync_len);
1060 t1 /= 1000;
1061 vsynch = 1000000000L / t1;
1062
1063
1064 sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
1065 res_mode->yres, bits_per_pixel, (hsynch / 1000),
1066 (vsynch / 1000));
1067 printf ("%s\n", pGD->modeIdent);
1068 pGD->winSizeX = res_mode->xres;
1069 pGD->winSizeY = res_mode->yres;
1070 pGD->plnSizeX = res_mode->xres;
1071 pGD->plnSizeY = res_mode->yres;
1072 switch (bits_per_pixel) {
1073 case 8:
1074 pGD->gdfBytesPP = 1;
1075 pGD->gdfIndex = GDF__8BIT_INDEX;
1076 break;
1077 case 15:
1078 pGD->gdfBytesPP = 2;
1079 pGD->gdfIndex = GDF_15BIT_555RGB;
1080 break;
1081 case 16:
1082 pGD->gdfBytesPP = 2;
1083 pGD->gdfIndex = GDF_16BIT_565RGB;
1084 break;
1085 case 24:
1086 pGD->gdfBytesPP = 3;
1087 pGD->gdfIndex = GDF_24BIT_888RGB;
1088 break;
1089 }
1090 pGD->isaBase = CONFIG_SYS_ISA_IO_BASE_ADDRESS;
1091 pGD->pciBase = pci_mem_base;
1092 pGD->frameAdrs = pci_mem_base;
1093 pGD->memSize = chips_param->max_mem;
1094
1095 pGD->dprBase =
1096 (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) + pci_mem_base;
1097 if ((pGD->dprBase & 0x0fff) != 0) {
1098
1099 pGD->dprBase &= 0xfffff000;
1100 pGD->dprBase += 0x00001000;
1101 }
1102 debug("Cursor Start %x Pattern Start %x\n", pGD->dprBase,
1103 PATTERN_ADR);
1104 pGD->vprBase = pci_mem_base;
1105 pGD->cprBase = pci_mem_base;
1106
1107
1108 ctWrite (CT_MSR_W_O, 0x01);
1109
1110
1111 ctLoadRegs (CT_XR_O, xreg);
1112
1113 SetArRegs ();
1114
1115 SetGrRegs ();
1116
1117 SetSrRegs ();
1118
1119
1120 SetMsrRegs (res_mode);
1121
1122
1123 SetCrRegs (res_mode, bits_per_pixel);
1124
1125 SetBitsPerPixelIntoXrRegs (bits_per_pixel);
1126
1127
1128 FindAndSetPllParamIntoXrRegs (res_mode->pixclock, chips_param);
1129
1130 ctWrite_i (CT_SR_O, 0, 0x03);
1131
1132 i = pGD->memSize / 4;
1133 vm = (unsigned int *) pGD->pciBase;
1134 while (i--)
1135 *vm++ = 0;
1136 SetDrawingEngine (bits_per_pixel);
1137#ifdef VGA_DUMP_REG
1138 video_dump_reg ();
1139#endif
1140
1141 return ((void *) &ctfb);
1142}
1143
1144
1145
1146
1147
1148void
1149video_set_lut (unsigned int index,
1150 unsigned char r,
1151 unsigned char g,
1152 unsigned char b
1153 )
1154{
1155
1156 ctWrite (CT_LUT_MASK_O, 0xff);
1157
1158 ctWrite (CT_LUT_START_O, (char) index);
1159
1160 ctWrite (CT_LUT_RGB_O, r);
1161 ctWrite (CT_LUT_RGB_O, g);
1162 ctWrite (CT_LUT_RGB_O, b);
1163 udelay (1);
1164 ctWrite (CT_LUT_MASK_O, 0xff);
1165}
1166
1167
1168
1169
1170
1171void
1172video_hw_rectfill (unsigned int bpp,
1173 unsigned int dst_x,
1174 unsigned int dst_y,
1175 unsigned int dim_x,
1176 unsigned int dim_y,
1177 unsigned int color
1178 )
1179{
1180 GraphicDevice *pGD = (GraphicDevice *) & ctfb;
1181 unsigned long *p, br04;
1182
1183 video_wait_bitblt (pGD->pciBase + BR04_o);
1184
1185 p = (unsigned long *) PATTERN_ADR;
1186 dim_x *= bpp;
1187 if (bpp == 3)
1188 bpp++;
1189 memset (p, color, (bpp * sizeof (unsigned char) * 8 * 8));
1190 out32r (pGD->pciBase + BR07_o, ((pGD->winSizeX * dst_y) + dst_x) * pGD->gdfBytesPP);
1191 br04 = in32r (pGD->pciBase + BR04_o) & 0xffffff00;
1192 br04 |= 0xF0;
1193 out32r (pGD->pciBase + BR04_o, br04);
1194 out32r (pGD->pciBase + BR08_o, (dim_y << 16) + dim_x);
1195 video_wait_bitblt (pGD->pciBase + BR04_o);
1196}
1197
1198
1199
1200
1201
1202void
1203video_hw_bitblt (unsigned int bpp,
1204 unsigned int src_x,
1205 unsigned int src_y,
1206 unsigned int dst_x,
1207 unsigned int dst_y,
1208 unsigned int dim_x,
1209 unsigned int dim_y
1210 )
1211{
1212 GraphicDevice *pGD = (GraphicDevice *) & ctfb;
1213 unsigned long br04;
1214
1215 br04 = in32r (pGD->pciBase + BR04_o);
1216
1217
1218
1219 if (src_x < dst_x) {
1220
1221
1222 br04 |= 0x00000100;
1223 src_x += dim_x;
1224 dst_x += dim_x;
1225 } else {
1226 br04 &= 0xfffffeff;
1227 }
1228 if (src_y < dst_y) {
1229
1230
1231 br04 |= 0x00000200;
1232 src_y += dim_y;
1233 dst_y += dim_y;
1234 } else {
1235 br04 &= 0xfffffdff;
1236 }
1237 dim_x *= bpp;
1238 out32r (pGD->pciBase + BR06_o, ((pGD->winSizeX * src_y) + src_x) * pGD->gdfBytesPP);
1239 out32r (pGD->pciBase + BR07_o, ((pGD->winSizeX * dst_y) + dst_x) * pGD->gdfBytesPP);
1240 br04 &= 0xffffff00;
1241 br04 |= 0x000000CC;
1242 out32r (pGD->pciBase + BR04_o, br04);
1243 out32r (pGD->pciBase + BR08_o, (dim_y << 16) + dim_x);
1244 video_wait_bitblt (pGD->pciBase + BR04_o);
1245}
1246#endif
1247