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