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