3 * Denis Peter, MPL AG Switzerland
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,
25 * ported from ctfb.c (linux kernel) for the U-Boot
29 /************************************************************************
30 Get Parameters for the video mode:
31 Parameters can be set via the variable "videomode" in the environment.
32 2 diferent ways are possible:
33 "videomode=301" - 301 is a hexadecimal number describing the VESA
34 mode. Following modes are implemented:
36 Colors 640x480 800x600 1024x768 1152x864
37 --------+-----------------------------------
38 8 bits | 0x301 0x303 0x305 0x161
39 15 bits | 0x310 0x313 0x316 0x162
40 16 bits | 0x311 0x314 0x317 0x163
41 24 bits | 0x312 0x315 0x318 ?
42 --------+-----------------------------------
44 - the parameters are parsed from the bootargs.
45 The format is "NAME:VALUE,NAME:VALUE" etc.
47 "bootargs=video=ctfb:x:800,y:600,depth:16,pclk:25000"
48 Parameters not included in the list will be taken from
49 the default mode, which is one of the following:
55 if "mode" is not provided within the parameter list,
57 Following parameters are supported:
58 x xres = visible resolution horizontal
59 y yres = visible resolution vertical
60 pclk pixelclocks in pico sec
61 le left_marging time from sync to picture in pixelclocks
62 ri right_marging time from picture to sync in pixelclocks
63 up upper_margin time from sync to picture
65 hs hsync_len length of horizontal sync
66 vs vsync_len length of vertical sync
69 depth Color depth in bits per pixel
70 All other parameters in the variable bootargs are ignored.
71 It is also possible to set the parameters direct in the
72 variable "videomode", or in another variable i.e.
73 "myvideo" and setting the variable "videomode=myvideo"..
74 ****************************************************************************/
83 #ifdef CONFIG_VIDEO_CT69000
89 #define PRINTF(fmt,args...) printf (fmt ,##args)
91 #define PRINTF(fmt,args...)
96 #define min( a, b ) ( ( a ) < ( b ) ) ? ( a ) : ( b )
99 #define max( a, b ) ( ( a ) > ( b ) ) ? ( a ) : ( b )
102 #error "term minmax already used."
104 #define minmax( a, x, b ) max( ( a ), min( ( x ), ( b ) ) )
105 #define N_ELTS( x ) ( sizeof( x ) / sizeof( x[ 0 ] ) )
107 /* CT Register Offsets */
108 #define CT_AR_O 0x3c0 /* Index and Data write port of the attribute Registers */
109 #define CT_GR_O 0x3ce /* Index port of the Graphic Controller Registers */
110 #define CT_SR_O 0x3c4 /* Index port of the Sequencer Controller */
111 #define CT_CR_O 0x3d4 /* Index port of the CRT Controller */
112 #define CT_XR_O 0x3d6 /* Extended Register index */
113 #define CT_MSR_W_O 0x3c2 /* Misc. Output Register (write only) */
114 #define CT_LUT_MASK_O 0x3c6 /* Color Palette Mask */
115 #define CT_LUT_START_O 0x3c8 /* Color Palette Write Mode Index */
116 #define CT_LUT_RGB_O 0x3c9 /* Color Palette Data Port */
117 #define CT_STATUS_REG0_O 0x3c2 /* Status Register 0 (read only) */
118 #define CT_STATUS_REG1_O 0x3da /* Input Status Register 1 (read only) */
120 #define CT_FP_O 0x3d0 /* Index port of the Flat panel Registers */
121 #define CT_MR_O 0x3d2 /* Index Port of the Multimedia Extension */
123 /* defines for the memory mapped registers */
124 #define BR00_o 0x400000 /* Source and Destination Span Register */
125 #define BR01_o 0x400004 /* Pattern/Source Expansion Background Color & Transparency Key Register */
126 #define BR02_o 0x400008 /* Pattern/Source Expansion Foreground Color Register */
127 #define BR03_o 0x40000C /* Monochrome Source Control Register */
128 #define BR04_o 0x400010 /* BitBLT Control Register */
129 #define BR05_o 0x400014 /* Pattern Address Registe */
130 #define BR06_o 0x400018 /* Source Address Register */
131 #define BR07_o 0x40001C /* Destination Address Register */
132 #define BR08_o 0x400020 /* Destination Width & Height Register */
133 #define BR09_o 0x400024 /* Source Expansion Background Color & Transparency Key Register */
134 #define BR0A_o 0x400028 /* Source Expansion Foreground Color Register */
136 #define CURSOR_SIZE 0x1000 /* in KByte for HW Cursor */
137 #define PATTERN_ADR (pGD->dprBase + CURSOR_SIZE) /* pattern Memory after Cursor Memory */
138 #define PATTERN_SIZE 8*8*4 /* 4 Bytes per Pixel 8 x 8 Pixel */
139 #define ACCELMEMORY (CURSOR_SIZE + PATTERN_SIZE) /* reserved Memory for BITBlt and hw cursor */
141 /* Some Mode definitions */
142 #define FB_SYNC_HOR_HIGH_ACT 1 /* horizontal sync high active */
143 #define FB_SYNC_VERT_HIGH_ACT 2 /* vertical sync high active */
144 #define FB_SYNC_EXT 4 /* external sync */
145 #define FB_SYNC_COMP_HIGH_ACT 8 /* composite sync high active */
146 #define FB_SYNC_BROADCAST 16 /* broadcast video timings */
147 /* vtotal = 144d/288n/576i => PAL */
148 /* vtotal = 121d/242n/484i => NTSC */
149 #define FB_SYNC_ON_GREEN 32 /* sync on green */
151 #define FB_VMODE_NONINTERLACED 0 /* non interlaced */
152 #define FB_VMODE_INTERLACED 1 /* interlaced */
153 #define FB_VMODE_DOUBLE 2 /* double scan */
154 #define FB_VMODE_MASK 255
156 #define FB_VMODE_YWRAP 256 /* ywrap instead of panning */
157 #define FB_VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */
158 #define FB_VMODE_CONUPDATE 512 /* don't update x/yoffset */
163 /* table for VGA Initialization */
165 const unsigned char reg;
166 const unsigned char val;
169 /* this table provides some basic initialisations such as Memory Clock etc */
170 static CT_CFG_TABLE xreg[] = {
171 {0x09, 0x01}, /* CRT Controller Extensions Enable */
172 {0x0A, 0x02}, /* Frame Buffer Mapping */
173 {0x0B, 0x01}, /* PCI Write Burst support */
174 {0x20, 0x00}, /* BitBLT Configuration */
175 {0x40, 0x03}, /* Memory Access Control */
176 {0x60, 0x00}, /* Video Pin Control */
177 {0x61, 0x00}, /* DPMS Synch control */
178 {0x62, 0x00}, /* GPIO Pin Control */
179 {0x63, 0xBD}, /* GPIO Pin Data */
180 {0x67, 0x00}, /* Pin Tri-State */
181 {0x80, 0x80}, /* Pixel Pipeline Config 0 register */
182 {0xA0, 0x00}, /* Cursor 1 Control Reg */
183 {0xA1, 0x00}, /* Cursor 1 Vertical Extension Reg */
184 {0xA2, 0x00}, /* Cursor 1 Base Address Low */
185 {0xA3, 0x00}, /* Cursor 1 Base Address High */
186 {0xA4, 0x00}, /* Cursor 1 X-Position Low */
187 {0xA5, 0x00}, /* Cursor 1 X-Position High */
188 {0xA6, 0x00}, /* Cursor 1 Y-Position Low */
189 {0xA7, 0x00}, /* Cursor 1 Y-Position High */
190 {0xA8, 0x00}, /* Cursor 2 Control Reg */
191 {0xA9, 0x00}, /* Cursor 2 Vertical Extension Reg */
192 {0xAA, 0x00}, /* Cursor 2 Base Address Low */
193 {0xAB, 0x00}, /* Cursor 2 Base Address High */
194 {0xAC, 0x00}, /* Cursor 2 X-Position Low */
195 {0xAD, 0x00}, /* Cursor 2 X-Position High */
196 {0xAE, 0x00}, /* Cursor 2 Y-Position Low */
197 {0xAF, 0x00}, /* Cursor 2 Y-Position High */
198 {0xC0, 0x7D}, /* Dot Clock 0 VCO M-Divisor */
199 {0xC1, 0x07}, /* Dot Clock 0 VCO N-Divisor */
200 {0xC3, 0x34}, /* Dot Clock 0 Divisor select */
201 {0xC4, 0x55}, /* Dot Clock 1 VCO M-Divisor */
202 {0xC5, 0x09}, /* Dot Clock 1 VCO N-Divisor */
203 {0xC7, 0x24}, /* Dot Clock 1 Divisor select */
204 {0xC8, 0x7D}, /* Dot Clock 2 VCO M-Divisor */
205 {0xC9, 0x07}, /* Dot Clock 2 VCO N-Divisor */
206 {0xCB, 0x34}, /* Dot Clock 2 Divisor select */
207 {0xCC, 0x38}, /* Memory Clock 0 VCO M-Divisor */
208 {0xCD, 0x03}, /* Memory Clock 0 VCO N-Divisor */
209 {0xCE, 0x90}, /* Memory Clock 0 Divisor select */
210 {0xCF, 0x06}, /* Clock Config */
211 {0xD0, 0x0F}, /* Power Down */
212 {0xD1, 0x01}, /* Power Down BitBLT */
213 {0xFF, 0xFF} /* end of table */
220 * Bit2 and Bit4..6 are used for the Loop Divisor and Post Divisor.
221 * They are encoded as follows:
223 * +---+--------------+
224 * | 2 | Loop Divisor |
225 * +---+--------------+
227 * +---+--------------+
229 * +---+--------------+
230 * Note: The Memory Clock does not have a Loop Divisor.
231 * +---+---+---+--------------+
232 * | 6 | 5 | 4 | Post Divisor |
233 * +---+---+---+--------------+
235 * +---+---+---+--------------+
237 * +---+---+---+--------------+
239 * +---+---+---+--------------+
241 * +---+---+---+--------------+
243 * +---+---+---+--------------+
245 * +---+---+---+--------------+
246 * | 1 | 1 | X | reserved |
247 * +---+---+---+--------------+
249 * All other bits are reserved in these registers.
251 * Clock VCO M Registers:
252 * ----------------------
253 * These Registers contain the M Value -2.
255 * Clock VCO N Registers:
256 * ----------------------
257 * These Registers contain the N Value -2.
261 * Fvco = (Fref * Loop Divisor * M/N), whereas 100MHz < Fvco < 220MHz
262 * Fout = Fvco / Post Divisor
264 * Dot Clk0 (default 25MHz):
265 * -------------------------
266 * Fvco = 14.318 * 127 / 9 = 202.045MHz
267 * Fout = 202.045MHz / 8 = 25.25MHz
270 * XRC0 = (M - 2) = 125 = 0x7D
271 * XRC1 = (N - 2) = 7 = 0x07
274 * Dot Clk1 (default 28MHz):
275 * -------------------------
276 * Fvco = 14.318 * 87 / 11 = 113.24MHz
277 * Fout = 113.24MHz / 4 = 28.31MHz
280 * XRC4 = (M - 2) = 85 = 0x55
281 * XRC5 = (N - 2) = 9 = 0x09
284 * Dot Clk2 (variable for extended modes set to 25MHz):
285 * ----------------------------------------------------
286 * Fvco = 14.318 * 127 / 9 = 202.045MHz
287 * Fout = 202.045MHz / 8 = 25.25MHz
290 * XRC8 = (M - 2) = 125 = 0x7D
291 * XRC9 = (N - 2) = 7 = 0x07
294 * Memory Clk for most modes >50MHz:
295 * ----------------------------------
296 * Fvco = 14.318 * 58 / 5 = 166MHz
297 * Fout = 166MHz / 2 = 83MHz
299 * XRCC = (M - 2) = 57 = 0x38
300 * XRCD = (N - 2) = 3 = 0x03
303 * Note Bit7 enables the clock source from the VCO
307 /******************************************************************
309 ******************************************************************/
310 struct ctfb_res_modes {
311 int xres; /* visible resolution */
313 /* Timing: All values in pixclocks, except pixclock (of course) */
314 int pixclock; /* pixel clock in ps (pico seconds) */
315 int left_margin; /* time from sync to picture */
316 int right_margin; /* time from picture to sync */
317 int upper_margin; /* time from sync to picture */
319 int hsync_len; /* length of horizontal sync */
320 int vsync_len; /* length of vertical sync */
321 int sync; /* see FB_SYNC_* */
322 int vmode; /* see FB_VMODE_* */
325 /******************************************************************
327 ******************************************************************/
328 struct ctfb_vesa_modes {
329 int vesanr; /* Vesa number as in LILO (VESA Nr + 0x200} */
330 int resindex; /* index to resolution struct */
331 int bits_per_pixel; /* bpp */
333 /*******************************************************************
335 *******************************************************************/
336 struct ctfb_chips_properties {
337 int device_id; /* PCI Device ID */
338 unsigned long max_mem; /* memory for frame buffer */
339 int vld_set; /* value of VLD if bit2 in clock control is set */
340 int vld_not_set; /* value of VLD if bit2 in clock control is set */
341 int mn_diff; /* difference between M/N Value + mn_diff = M/N Register */
342 int mn_min; /* min value of M/N Value */
343 int mn_max; /* max value of M/N Value */
344 int vco_min; /* VCO Min in MHz */
345 int vco_max; /* VCO Max in MHz */
348 static const struct ctfb_chips_properties chips[] = {
349 {PCI_DEVICE_ID_CT_69000, 0x200000, 1, 4, -2, 3, 257, 100, 220},
350 {PCI_DEVICE_ID_CT_65555, 0x100000, 16, 4, 0, 1, 255, 48, 220}, /* NOT TESTED */
351 {0, 0, 0, 0, 0, 0, 0, 0, 0} /* Terminator */
354 /*************************************************
356 Colours 640x400 640x480 800x600 1024x768 1152x864 1280x1024 1600x1200
357 --------+--------------------------------------------------------------
358 4 bits | ? ? 0x302 ? ? ? ?
359 8 bits | 0x300 0x301 0x303 0x305 0x161 0x307 0x31C
360 15 bits | ? 0x310 0x313 0x316 0x162 0x319 0x31D
361 16 bits | ? 0x311 0x314 0x317 0x163 0x31A 0x31E
362 24 bits | ? 0x312 0x315 0x318 ? 0x31B 0x31F
363 32 bits | ? ? ? ? 0x164 ?
366 #define RES_MODE_640x480 0
367 #define RES_MODE_800x600 1
368 #define RES_MODE_1024x768 2
369 #define RES_MODE_960_720 3
370 #define RES_MODE_1152x864 4
371 #define RES_MODES_COUNT 5
373 #define VESA_MODES_COUNT 15
375 static const struct ctfb_vesa_modes vesa_modes[VESA_MODES_COUNT] = {
376 {0x301, RES_MODE_640x480, 8},
377 {0x310, RES_MODE_640x480, 15},
378 {0x311, RES_MODE_640x480, 16},
379 {0x312, RES_MODE_640x480, 24},
380 {0x303, RES_MODE_800x600, 8},
381 {0x313, RES_MODE_800x600, 15},
382 {0x314, RES_MODE_800x600, 16},
383 {0x315, RES_MODE_800x600, 24},
384 {0x305, RES_MODE_1024x768, 8},
385 {0x316, RES_MODE_1024x768, 15},
386 {0x317, RES_MODE_1024x768, 16},
387 {0x318, RES_MODE_1024x768, 24},
388 {0x161, RES_MODE_1152x864, 8},
389 {0x162, RES_MODE_1152x864, 15},
390 {0x163, RES_MODE_1152x864, 16}
393 static const struct ctfb_res_modes res_mode_init[RES_MODES_COUNT] = {
394 /* x y pixclk le ri up lo hs vs s vmode */
395 {640, 480, 39721, 40, 24, 32, 11, 96, 2, 0,
396 FB_VMODE_NONINTERLACED},
397 {800, 600, 27778, 64, 24, 22, 1, 72, 2, 0, FB_VMODE_NONINTERLACED},
398 {1024, 768, 15384, 168, 8, 29, 3, 144, 4, 0,
399 FB_VMODE_NONINTERLACED},
400 {960, 720, 13100, 160, 40, 32, 8, 80, 4, 0,
401 FB_VMODE_NONINTERLACED},
402 {1152, 864, 12004, 200, 64, 32, 16, 80, 4, 0,
403 FB_VMODE_NONINTERLACED}
411 /*******************************************************************************
416 /*******************************************************************************
418 * Read CT ISA register
422 ctRead (unsigned short index)
424 GraphicDevice *pGD = (GraphicDevice *) & ctfb;
425 if (index == CT_AR_O)
426 /* synch the Flip Flop */
427 in8 (pGD->isaBase + CT_STATUS_REG1_O);
429 return (in8 (pGD->isaBase + index));
432 /*******************************************************************************
434 * Write CT ISA register
437 ctWrite (unsigned short index, unsigned char val)
439 GraphicDevice *pGD = (GraphicDevice *) & ctfb;
441 out8 ((pGD->isaBase + index), val);
444 /*******************************************************************************
446 * Read CT ISA register indexed
449 ctRead_i (unsigned short index, char reg)
451 GraphicDevice *pGD = (GraphicDevice *) & ctfb;
452 if (index == CT_AR_O)
453 /* synch the Flip Flop */
454 in8 (pGD->isaBase + CT_STATUS_REG1_O);
455 out8 ((pGD->isaBase + index), reg);
456 return (in8 (pGD->isaBase + index + 1));
459 /*******************************************************************************
461 * Write CT ISA register indexed
464 ctWrite_i (unsigned short index, char reg, char val)
466 GraphicDevice *pGD = (GraphicDevice *) & ctfb;
467 if (index == CT_AR_O) {
468 /* synch the Flip Flop */
469 in8 (pGD->isaBase + CT_STATUS_REG1_O);
470 out8 ((pGD->isaBase + index), reg);
471 out8 ((pGD->isaBase + index), val);
473 out8 ((pGD->isaBase + index), reg);
474 out8 ((pGD->isaBase + index + 1), val);
478 /*******************************************************************************
480 * Write a table of CT ISA register
483 ctLoadRegs (unsigned short index, CT_CFG_TABLE * regTab)
485 while (regTab->reg != 0xFF) {
486 ctWrite_i (index, regTab->reg, regTab->val);
491 /*****************************************************************************/
497 for (i = 0; i < 0x10; i++)
498 ctWrite_i (CT_AR_O, i, i);
504 ctWrite_i (CT_AR_O, 0x10, tmp); /* Mode Control Register */
505 ctWrite_i (CT_AR_O, 0x11, 0x00); /* Overscan Color Register */
506 ctWrite_i (CT_AR_O, 0x12, 0x0f); /* Memory Plane Enable Register */
511 ctWrite_i (CT_AR_O, 0x13, tmp); /* Horizontal Pixel Panning */
512 ctWrite_i (CT_AR_O, 0x14, 0x00); /* Color Select Register */
513 ctWrite (CT_AR_O, 0x20); /* enable video */
516 /*****************************************************************************/
519 { /* Set Graphics Mode */
522 for (i = 0; i < 0x05; i++)
523 ctWrite_i (CT_GR_O, i, 0);
525 ctWrite_i (CT_GR_O, 0x05, 0x10);
526 ctWrite_i (CT_GR_O, 0x06, 0x02);
528 ctWrite_i (CT_GR_O, 0x05, 0x40);
529 ctWrite_i (CT_GR_O, 0x06, 0x05);
531 ctWrite_i (CT_GR_O, 0x07, 0x0f);
532 ctWrite_i (CT_GR_O, 0x08, 0xff);
535 /*****************************************************************************/
541 ctWrite_i (CT_SR_O, 0x00, 0x00); /* reset */
542 /*rr( sr, 0x01, tmp );
543 if( fntwidth == 8 ) tmp |= 0x01; else tmp &= ~0x01;
544 wr( sr, 0x01, tmp ); */
546 ctWrite_i (CT_SR_O, 0x01, 0x01); /* Clocking Mode Register */
548 ctWrite_i (CT_SR_O, 0x01, 0x00); /* Clocking Mode Register */
549 ctWrite_i (CT_SR_O, 0x02, 0x0f); /* Enable CPU wr access to given memory plane */
550 ctWrite_i (CT_SR_O, 0x03, 0x00); /* Character Map Select Register */
555 ctWrite_i (CT_SR_O, 0x04, tmp); /* Enable CPU accesses to the rest of the 256KB
556 total VGA memory beyond the first 64KB and set
558 ctWrite_i (CT_SR_O, 0x00, 0x03); /* enable */
561 /*****************************************************************************/
563 SetBitsPerPixelIntoXrRegs (int bpp)
565 unsigned int n = (bpp >> 3), tmp; /* only for 15, 8, 16, 24 bpp */
566 static char md[4] = { 0x04, 0x02, 0x05, 0x06 }; /* DisplayColorMode */
567 static char off[4] = { ~0x20, ~0x30, ~0x20, ~0x10 }; /* mask */
568 static char on[4] = { 0x10, 0x00, 0x10, 0x20 }; /* mask */
571 tmp = ctRead_i (CT_XR_O, 0x20);
574 ctWrite_i (CT_XR_O, 0x20, tmp); /* BitBLT Configuration */
575 ctWrite_i (CT_XR_O, 0x81, md[n]);
578 /*****************************************************************************/
580 SetCrRegs (struct ctfb_res_modes *var, int bits_per_pixel)
581 { /* he -le- ht|0 hd -ri- hs -h- he */
582 unsigned char cr[0x7a];
584 unsigned int hd, hs, he, ht, hbe; /* Horizontal. */
585 unsigned int vd, vs, ve, vt; /* vertical */
586 unsigned int bpp, wd, dblscan, interlaced, bcast, CrtHalfLine;
587 unsigned int CompSyncCharClkDelay, CompSyncPixelClkDelay;
588 unsigned int NTSC_PAL_HorizontalPulseWidth, BlDelayCtrl;
589 unsigned int HorizontalEqualizationPulses;
590 unsigned int HorizontalSerration1Start, HorizontalSerration2Start;
592 const int LineCompare = 0x3ff;
593 unsigned int TextScanLines = 1; /* this is in fact a vertical zoom factor */
594 unsigned int RAMDAC_BlankPedestalEnable = 0; /* 1=en-, 0=disable, see XR82 */
596 hd = (var->xres) / 8; /* HDisp. */
597 hs = (var->xres + var->right_margin) / 8; /* HsStrt */
598 he = (var->xres + var->right_margin + var->hsync_len) / 8; /* HsEnd */
599 ht = (var->left_margin + var->xres + var->right_margin + var->hsync_len) / 8; /* HTotal */
600 hbe = ht - 1; /* HBlankEnable todo docu wants ht here, but it does not work */
601 /* ve -up- vt|0 vd -lo- vs -v- ve */
602 vd = var->yres; /* VDisplay */
603 vs = var->yres + var->lower_margin; /* VSyncStart */
604 ve = var->yres + var->lower_margin + var->vsync_len; /* VSyncEnd */
605 vt = var->upper_margin + var->yres + var->lower_margin + var->vsync_len; /* VTotal */
606 bpp = bits_per_pixel;
607 dblscan = (var->vmode & FB_VMODE_DOUBLE) ? 1 : 0;
608 interlaced = var->vmode & FB_VMODE_INTERLACED;
609 bcast = var->sync & FB_SYNC_BROADCAST;
610 CrtHalfLine = bcast ? (hd >> 1) : 0;
611 BlDelayCtrl = bcast ? 1 : 0;
612 CompSyncCharClkDelay = 0; /* 2 bit */
613 CompSyncPixelClkDelay = 0; /* 3 bit */
615 NTSC_PAL_HorizontalPulseWidth = 7; /*( var->hsync_len >> 1 ) + 1 */
616 HorizontalEqualizationPulses = 0; /* inverse value */
617 HorizontalSerration1Start = 31; /* ( ht >> 1 ) */
618 HorizontalSerration2Start = 89; /* ( ht >> 1 ) */
620 NTSC_PAL_HorizontalPulseWidth = 0;
621 /* 4 bit: hsync pulse width = ( ( CR74[4:0] - CR74[5] )
622 * / 2 ) + 1 --> CR74[4:0] = 2*(hs-1) + CR74[5] */
623 HorizontalEqualizationPulses = 1; /* inverse value */
624 HorizontalSerration1Start = 0; /* ( ht >> 1 ) */
625 HorizontalSerration2Start = 0; /* ( ht >> 1 ) */
630 wd = var->xres * bpp / 64; /* double words per line */
631 if (interlaced) { /* we divide all vertical timings, exept vd */
636 memset (cr, 0, sizeof (cr));
637 cr[0x00] = 0xff & (ht - 5);
638 cr[0x01] = hd - 1; /* soll:4f ist 59 */
640 cr[0x03] = (hbe & 0x1F) | 0x80; /* hd + ht - hd */
642 cr[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f);
643 cr[0x06] = (vt - 2) & 0xFF;
644 cr[0x30] = (vt - 2) >> 8;
645 cr[0x07] = ((vt & 0x100) >> 8)
646 | ((vd & 0x100) >> 7)
647 | ((vs & 0x100) >> 6)
648 | ((vs & 0x100) >> 5)
649 | ((LineCompare & 0x100) >> 4)
650 | ((vt & 0x200) >> 4)
651 | ((vd & 0x200) >> 3)
652 | ((vs & 0x200) >> 2);
654 cr[0x09] = (dblscan << 7)
655 | ((LineCompare & 0x200) >> 3)
656 | ((vs & 0x200) >> 4)
657 | (TextScanLines - 1);
658 cr[0x10] = vs & 0xff; /* VSyncPulseStart */
659 cr[0x32] = (vs & 0xf00) >> 8; /* VSyncPulseStart */
660 cr[0x11] = (ve & 0x0f); /* | 0x20; */
661 cr[0x12] = (vd - 1) & 0xff; /* LineCount */
662 cr[0x31] = ((vd - 1) & 0xf00) >> 8; /* LineCount */
663 cr[0x13] = wd & 0xff;
664 cr[0x41] = (wd & 0xf00) >> 8;
665 cr[0x15] = vs & 0xff;
666 cr[0x33] = (vs & 0xf00) >> 8;
667 cr[0x38] = (0x100 & (ht - 5)) >> 8;
668 cr[0x3C] = 0xc0 & hbe;
669 cr[0x16] = (vt - 1) & 0xff; /* vbe - docu wants vt here, */
670 cr[0x17] = 0xe3; /* but it does not work */
671 cr[0x18] = 0xff & LineCompare;
672 cr[0x22] = 0xff; /* todo? */
673 cr[0x70] = interlaced ? (0x80 | CrtHalfLine) : 0x00; /* check:0xa6 */
674 cr[0x71] = 0x80 | (RAMDAC_BlankPedestalEnable << 6)
676 | ((0x03 & CompSyncCharClkDelay) << 3)
677 | (0x07 & CompSyncPixelClkDelay); /* todo: see XR82 */
678 cr[0x72] = HorizontalSerration1Start;
679 cr[0x73] = HorizontalSerration2Start;
680 cr[0x74] = (HorizontalEqualizationPulses << 5)
681 | NTSC_PAL_HorizontalPulseWidth;
682 /* todo: ct69000 has also 0x75-79 */
683 /* now set the registers */
684 for (i = 0; i <= 0x0d; i++) { /*CR00 .. CR0D */
685 ctWrite_i (CT_CR_O, i, cr[i]);
687 for (i = 0x10; i <= 0x18; i++) { /*CR10 .. CR18 */
688 ctWrite_i (CT_CR_O, i, cr[i]);
691 ctWrite_i (CT_CR_O, i, cr[i]);
692 for (i = 0x30; i <= 0x33; i++) { /*CR30 .. CR33 */
693 ctWrite_i (CT_CR_O, i, cr[i]);
696 ctWrite_i (CT_CR_O, i, cr[i]);
698 ctWrite_i (CT_CR_O, i, cr[i]);
699 for (i = 0x40; i <= 0x41; i++) { /*CR40 .. CR41 */
700 ctWrite_i (CT_CR_O, i, cr[i]);
702 for (i = 0x70; i <= 0x74; i++) { /*CR70 .. CR74 */
703 ctWrite_i (CT_CR_O, i, cr[i]);
705 tmp = ctRead_i (CT_CR_O, 0x40);
708 ctWrite_i (CT_CR_O, 0x40, tmp); /* StartAddressEnable */
711 /* pixelclock control */
713 /*****************************************************************************
714 We have a rational number p/q and need an m/n which is very close to p/q
715 but has m and n within mnmin and mnmax. We have no floating point in the
716 kernel. We can use long long without divide. And we have time to compute...
717 ******************************************************************************/
719 FindBestPQFittingMN (unsigned int p, unsigned int q, unsigned int mnmin,
720 unsigned int mnmax, unsigned int *pm, unsigned int *pn)
722 /* this code is not for general purpose usable but good for our number ranges */
723 unsigned int n = mnmin, m = 0;
724 long long int L = 0, P = p, Q = q, H = P >> 1;
725 long long int D = 0x7ffffffffffffffLL;
726 for (n = mnmin; n <= mnmax; n++) {
727 m = mnmin; /* p/q ~ m/n -> p*n ~ m*q -> p*n-x*q ~ 0 */
728 L = P * n - m * Q; /* n * vco - m * fref should be near 0 */
729 while (L > 0 && m < mnmax) {
730 L -= q; /* difference is greater as 0 subtract fref */
731 m++; /* and increment m */
733 /* difference is less or equal than 0 or m > maximum */
735 break; /* no solution: if we increase n we get the same situation */
737 if (-L > H && m > mnmin) { /* if difference > the half fref */
738 L += q; /* we take the situation before */
739 m--; /* because its closer to 0 */
741 L = (L < 0) ? -L : +L; /* absolute value */
742 if (D < L) /* if last difference was better take next n */
746 *pn = n; /* keep improved data */
748 break; /* best result we can get */
750 return (unsigned int) (0xffffffff & D);
753 /* that is the hardware < 69000 we have to manage
754 +---------+ +-------------------+ +----------------------+ +--+
755 | REFCLK |__|NTSC Divisor Select|__|FVCO Reference Divisor|__|÷N|__
756 | 14.3MHz | |(NTSCDS) (÷1, ÷5) | |Select (RDS) (÷1, ÷4) | | | |
757 +---------+ +-------------------+ +----------------------+ +--+ |
758 ___________________________________________________________________|
761 | +--------+ +------------+ +-----+ +-------------------+ +----+
762 +-| Phase |__|Charge Pump |__| VCO |_____|Post Divisor (PD) |___|CLK |--->
763 +-| Detect | |& Filter VCO| | | | |÷1, 2, 4, 8, 16, 32| | |
764 | +--------+ +------------+ +-----+ | +-------------------+ +----+
766 | +--+ +---------------+ |
767 |____|÷M|___|VCO Loop Divide|__________|
768 | | |(VLD)(÷4, ÷16) |
769 +--+ +---------------+
770 ****************************************************************************
771 that is the hardware >= 69000 we have to manage
779 | +--------+ +------------+ +-----+ +-------------------+ +----+
780 +-| Phase |__|Charge Pump |__| VCO |_____|Post Divisor (PD) |___|CLK |--->
781 +-| Detect | |& Filter VCO| | | | |÷1, 2, 4, 8, 16, 32| | |
782 | +--------+ +------------+ +-----+ | +-------------------+ +----+
784 | +--+ +---------------+ |
785 |____|÷M|___|VCO Loop Divide|__________|
786 | | |(VLD)(÷1, ÷4) |
787 +--+ +---------------+
792 #define VIDEO_FREF 14318180; /* Hz */
793 /*****************************************************************************/
795 ReadPixClckFromXrRegsBack (struct ctfb_chips_properties *param)
797 unsigned int m, n, vld, pd, PD, fref, xr_cb, i, pixclock;
801 m = ctRead_i (CT_XR_O, 0xc8);
802 n = ctRead_i (CT_XR_O, 0xc9);
805 xr_cb = ctRead_i (CT_XR_O, 0xcb);
806 PD = (0x70 & xr_cb) >> 4;
808 for (i = 0; i < PD; i++) {
811 vld = (0x04 & xr_cb) ? param->vld_set : param->vld_not_set;
813 unsigned long long p = 1000000000000LL * pd * n;
814 unsigned long long q = (long long) fref * vld * m;
815 while ((p > 0xffffffffLL) || (q > 0xffffffffLL)) {
816 p >>= 1; /* can't divide with long long so we scale down */
819 pixclock = (unsigned) p / (unsigned) q;
821 printf ("Invalid data in xr regs.\n");
825 /*****************************************************************************/
827 FindAndSetPllParamIntoXrRegs (unsigned int pixelclock,
828 struct ctfb_chips_properties *param)
830 unsigned int m, n, vld, pd, PD, fref, xr_cb;
831 unsigned int fvcomin, fvcomax, pclckmin, pclckmax, pclk;
832 unsigned int pfreq, fvco, new_pixclock;
837 fvcomin = param->vco_min;
838 fvcomax = param->vco_max; /* MHz */
839 pclckmin = 1000000 / fvcomax + 1; /* 4546 */
840 pclckmax = 32000000 / fvcomin - 1; /* 666665 */
841 pclk = minmax (pclckmin, pixelclock, pclckmax); /* ps pp */
842 pfreq = 250 * (4000000000U / pclk);
843 fvco = pfreq; /* Hz */
845 while (fvco < fvcomin * 1000000) {
846 /* double VCO starting with the pixelclock frequency
847 * as long as it is lower than the minimal VCO frequency */
852 /* fvco is exactly pd * pixelclock and higher than the ninmal VCO frequency */
853 vld = (param->vld_set > param->vld_not_set) ?
854 param->vld_not_set : param->vld_set;
855 /* start with lower VLD (higher VLD is NOT yet implemented */
856 FindBestPQFittingMN (fvco / vld, fref, param->mn_min, param->mn_max, &m, &n); /* rds = 1 */
859 PRINTF ("VCO %d, pd %d, m %d n %d vld %d \n", fvco, pd, m, n, vld);
860 xr_cb = ((0x7 & PD) << 4) | (vld == param->vld_set ? 0x04 : 0);
861 /* All four of the registers used for dot clock 2 (XRC8 - XRCB) must be
862 * written, and in order from XRC8 to XRCB, before the hardware will
863 * update the synthesizer s settings.
865 ctWrite_i (CT_XR_O, 0xc8, m);
866 ctWrite_i (CT_XR_O, 0xc9, n); /* xrca does not exist in CT69000 and CT69030 */
867 ctWrite_i (CT_XR_O, 0xca, 0); /* because of a hw bug I guess, but we write */
868 ctWrite_i (CT_XR_O, 0xcb, xr_cb); /* 0 to it for savety */
869 new_pixclock = ReadPixClckFromXrRegsBack (param);
870 PRINTF ("pixelclock.set = %d, pixelclock.real = %d \n",
871 pixelclock, new_pixclock);
874 /*****************************************************************************/
876 SetMsrRegs (struct ctfb_res_modes *mode)
878 unsigned char h_synch_high, v_synch_high;
880 h_synch_high = (mode->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 0x40; /* horizontal Synch High active */
881 v_synch_high = (mode->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 0x80; /* vertical Synch High active */
882 ctWrite (CT_MSR_W_O, (h_synch_high | v_synch_high | 0x29));
883 /* upper64K==0x20, CLC2select==0x08, RAMenable==0x02!(todo), CGA==0x01
884 * Selects the upper 64KB page.Bit5=1
885 * CLK2 (left reserved in standard VGA) Bit3|2=1|0
886 * Disables CPU access to frame buffer. Bit1=0
887 * Sets the I/O address decode for ST01, FCR, and all CR registers
888 * to the 3Dx I/O address range (CGA emulation). Bit0=1
892 /************************************************************************************/
896 ctDispRegs (unsigned short index, int from, int to)
898 unsigned char status;
901 for (i = from; i < to; i++) {
902 status = ctRead_i (index, i);
903 printf ("%02X: is %02X\n", i, status);
908 video_dump_reg (void)
912 printf ("Extended Regs:\n");
913 ctDispRegs (CT_XR_O, 0, 0xC);
914 ctDispRegs (CT_XR_O, 0xe, 0xf);
915 ctDispRegs (CT_XR_O, 0x20, 0x21);
916 ctDispRegs (CT_XR_O, 0x40, 0x50);
917 ctDispRegs (CT_XR_O, 0x60, 0x64);
918 ctDispRegs (CT_XR_O, 0x67, 0x68);
919 ctDispRegs (CT_XR_O, 0x70, 0x72);
920 ctDispRegs (CT_XR_O, 0x80, 0x83);
921 ctDispRegs (CT_XR_O, 0xA0, 0xB0);
922 ctDispRegs (CT_XR_O, 0xC0, 0xD3);
923 printf ("Sequencer Regs:\n");
924 ctDispRegs (CT_SR_O, 0, 0x8);
925 printf ("Graphic Regs:\n");
926 ctDispRegs (CT_GR_O, 0, 0x9);
927 printf ("CRT Regs:\n");
928 ctDispRegs (CT_CR_O, 0, 0x19);
929 ctDispRegs (CT_CR_O, 0x22, 0x23);
930 ctDispRegs (CT_CR_O, 0x30, 0x34);
931 ctDispRegs (CT_CR_O, 0x38, 0x39);
932 ctDispRegs (CT_CR_O, 0x3C, 0x3D);
933 ctDispRegs (CT_CR_O, 0x40, 0x42);
934 ctDispRegs (CT_CR_O, 0x70, 0x80);
935 /* don't display the attributes */
940 #ifdef CONFIG_VIDEO_HW_CURSOR
941 /***************************************************************
942 * Set Hardware Cursor in Pixel
945 video_set_hw_cursor (int x, int y)
947 int sig_x = 0, sig_y = 0;
956 ctWrite_i (CT_XR_O, 0xa4, x & 0xff);
957 ctWrite_i (CT_XR_O, 0xa5, (x >> 8) & 0x7);
958 ctWrite_i (CT_XR_O, 0xa6, y & 0xff);
959 ctWrite_i (CT_XR_O, 0xa7, (y >> 8) & 0x7);
962 /***************************************************************
963 * Init Hardware Cursor. To know the size of the Cursor,
964 * we have to know the Font size.
967 video_init_hw_cursor (int font_width, int font_height)
970 unsigned long *curs, pattern;
973 GraphicDevice *pGD = (GraphicDevice *) & ctfb;
975 cursor_start = pGD->dprBase;
976 xr_80 = ctRead_i (CT_XR_O, 0x80);
977 /* set start address */
978 ctWrite_i (CT_XR_O, 0xa2, (cursor_start >> 8) & 0xf0);
979 ctWrite_i (CT_XR_O, 0xa3, (cursor_start >> 16) & 0x3f);
980 /* set cursor shape */
981 curs = (unsigned long *) cursor_start;
984 curs[i++] = 0xffffffff; /* AND mask */
985 curs[i++] = 0xffffffff; /* AND mask */
986 curs[i++] = 0; /* XOR mask */
987 curs[i++] = 0; /* XOR mask */
990 pattern = 0xffffffff >> font_width;
992 while (i < (font_height * 2)) {
993 curs[i++] = pattern; /* AND mask */
994 curs[i++] = pattern; /* AND mask */
995 curs[i++] = 0; /* XOR mask */
996 curs[i++] = 0; /* XOR mask */
1000 ctWrite_i (CT_FP_O, 0x19, 0xf);
1002 /* set cursors colors */
1003 xr_80 = ctRead_i (CT_XR_O, 0x80);
1004 xr_80 |= 0x1; /* alternate palette select */
1005 ctWrite_i (CT_XR_O, 0x80, xr_80);
1006 video_set_lut (4, CONSOLE_FG_COL, CONSOLE_FG_COL, CONSOLE_FG_COL);
1007 /* position 4 is color 0 cursor 0 */
1008 xr_80 &= 0xfe; /* normal palette select */
1009 ctWrite_i (CT_XR_O, 0x80, xr_80);
1011 ctWrite_i (CT_XR_O, 0xa0, 0x91);
1012 xr_80 |= 0x10; /* enable hwcursor */
1013 ctWrite_i (CT_XR_O, 0x80, xr_80);
1014 video_set_hw_cursor (0, 0);
1016 #endif /* CONFIG_VIDEO_HW_CURSOR */
1018 /***************************************************************
1019 * Wait for BitBlt ready
1022 video_wait_bitblt (unsigned long addr)
1026 br04 = in32r (addr);
1027 while (br04 & 0x80000000) {
1029 br04 = in32r (addr);
1030 if (i++ > 1000000) {
1031 printf ("ERROR Timeout %lx\n", br04);
1038 /***************************************************************
1039 * Set up BitBlt Registrs
1042 SetDrawingEngine (int bits_per_pixel)
1044 unsigned long br04, br00;
1047 GraphicDevice *pGD = (GraphicDevice *) & ctfb;
1049 tmp = ctRead_i (CT_XR_O, 0x20); /* BitBLT Configuration */
1050 tmp |= 0x02; /* reset BitBLT */
1051 ctWrite_i (CT_XR_O, 0x20, tmp); /* BitBLT Configuration */
1053 tmp &= 0xfd; /* release reset BitBLT */
1054 ctWrite_i (CT_XR_O, 0x20, tmp); /* BitBLT Configuration */
1055 video_wait_bitblt (pGD->pciBase + BR04_o);
1057 /* set pattern Address */
1058 out32r (pGD->pciBase + BR05_o, PATTERN_ADR & 0x003ffff8);
1060 if (bits_per_pixel == 1) {
1061 br04 |= 0x00040000; /* monochome Pattern */
1062 br04 |= 0x00001000; /* monochome source */
1064 br00 = ((pGD->winSizeX * pGD->gdfBytesPP) << 16) + (pGD->winSizeX * pGD->gdfBytesPP); /* bytes per scanline */
1065 out32r (pGD->pciBase + BR00_o, br00); /* */
1066 out32r (pGD->pciBase + BR08_o, (10 << 16) + 10); /* dummy */
1067 out32r (pGD->pciBase + BR04_o, br04); /* write all 0 */
1068 out32r (pGD->pciBase + BR07_o, 0); /* destination */
1069 video_wait_bitblt (pGD->pciBase + BR04_o);
1072 /************************************************************************
1073 * Get Parameters for the video mode:
1075 /*********************************************************************
1076 * returns the length to the next seperator
1079 video_get_param_len (char *start, char sep)
1082 while ((*start != 0) && (*start != sep)) {
1090 video_search_param (char *start, char *param)
1092 int len, totallen, i;
1094 len = strlen (param);
1095 totallen = len + strlen (start);
1096 for (i = 0; i < totallen; i++) {
1097 if (strncmp (p++, param, len) == 0)
1103 /***************************************************************
1104 * Get parameter via the environment as it is done for the
1106 * video=ctfb:x:800,xv:1280,y:600,yv:1024,depth:16,mode:0,pclk:25000,
1107 * le:56,ri:48,up:26,lo:5,hs:152,vs:2,sync:0,vmode:0,accel:0
1109 * penv is a pointer to the environment, containing the string, or the name of
1110 * another environment variable. It could even be the term "bootargs"
1113 #define GET_OPTION(name,var) \
1114 if(strncmp(p,name,strlen(name))==0) { \
1115 val_s=p+strlen(name); \
1116 var=simple_strtoul(val_s, NULL, 10); \
1120 video_get_params (struct ctfb_res_modes *pPar, char *penv)
1122 char *p, *s, *val_s;
1126 /* first search for the environment containing the real param string */
1128 if ((p = getenv (s)) != NULL) {
1131 /* in case of the bootargs line, we have to start
1132 * after "video=ctfb:"
1134 i = video_search_param (s, "video=ctfb:");
1137 s += strlen ("video=ctfb:");
1139 /* search for mode as a default value */
1142 mode = 0; /* default */
1143 while ((i = video_get_param_len (p, ',')) != 0) {
1144 GET_OPTION ("mode:", mode)
1149 if (mode >= RES_MODES_COUNT)
1151 *pPar = res_mode_init[mode]; /* copy default values */
1152 bpp = 24 - ((mode % 3) * 8);
1153 p = s; /* restart */
1154 while ((i = video_get_param_len (p, ',')) != 0) {
1155 GET_OPTION ("x:", pPar->xres)
1156 GET_OPTION ("y:", pPar->yres)
1157 GET_OPTION ("le:", pPar->left_margin)
1158 GET_OPTION ("ri:", pPar->right_margin)
1159 GET_OPTION ("up:", pPar->upper_margin)
1160 GET_OPTION ("lo:", pPar->lower_margin)
1161 GET_OPTION ("hs:", pPar->hsync_len)
1162 GET_OPTION ("vs:", pPar->vsync_len)
1163 GET_OPTION ("sync:", pPar->sync)
1164 GET_OPTION ("vmode:", pPar->vmode)
1165 GET_OPTION ("pclk:", pPar->pixclock)
1166 GET_OPTION ("depth:", bpp)
1174 /****************************************************************************
1175 * supported Video Chips
1177 static struct pci_device_id supported[] = {
1178 {PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69000},
1182 /*******************************************************************************
1187 video_hw_init (void)
1189 GraphicDevice *pGD = (GraphicDevice *) & ctfb;
1190 unsigned short device_id;
1193 unsigned long t1, hsynch, vsynch;
1194 unsigned int pci_mem_base, *vm;
1195 int tmp, i, bits_per_pixel;
1197 struct ctfb_res_modes *res_mode;
1198 struct ctfb_res_modes var_mode;
1199 struct ctfb_chips_properties *chips_param;
1200 /* Search for video chip */
1202 if ((devbusfn = pci_find_devices (supported, 0)) < 0) {
1203 #ifdef CONFIG_VIDEO_ONBOARD
1204 printf ("Video: Controller not found !\n");
1210 pci_write_config_dword (devbusfn, PCI_COMMAND,
1211 (PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
1212 pci_read_config_word (devbusfn, PCI_DEVICE_ID, &device_id);
1213 pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &pci_mem_base);
1214 pci_mem_base = pci_mem_to_phys (devbusfn, pci_mem_base);
1216 /* get chips params */
1217 for (chips_param = (struct ctfb_chips_properties *) &chips[0];
1218 chips_param->device_id != 0; chips_param++) {
1219 if (chips_param->device_id == device_id)
1222 if (chips_param->device_id == 0) {
1223 #ifdef CONFIG_VIDEO_ONBOARD
1224 printf ("Video: controller 0x%X not supported\n", device_id);
1228 /* supported Video controller found */
1233 /* get video mode via environment */
1234 if ((penv = getenv ("videomode")) != NULL) {
1235 /* deceide if it is a string */
1236 if (penv[0] <= '9') {
1237 videomode = (int) simple_strtoul (penv, NULL, 16);
1244 /* parameter are vesa modes */
1246 for (i = 0; i < VESA_MODES_COUNT; i++) {
1247 if (vesa_modes[i].vesanr == videomode)
1250 if (i == VESA_MODES_COUNT) {
1251 printf ("no VESA Mode found, switching to mode 0x301 ");
1255 (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].
1257 bits_per_pixel = vesa_modes[i].bits_per_pixel;
1260 res_mode = (struct ctfb_res_modes *) &var_mode;
1261 bits_per_pixel = video_get_params (res_mode, penv);
1264 /* calculate available color depth for controller memory */
1265 if (bits_per_pixel == 15)
1268 tmp = bits_per_pixel >> 3; /* /8 */
1269 if (((chips_param->max_mem -
1270 ACCELMEMORY) / (res_mode->xres * res_mode->yres)) < tmp) {
1272 ((chips_param->max_mem -
1273 ACCELMEMORY) / (res_mode->xres * res_mode->yres));
1276 ("No matching videomode found .-> reduce resolution\n");
1279 printf ("Switching back to %d Bits per Pixel ",
1281 bits_per_pixel = tmp << 3;
1285 /* calculate hsynch and vsynch freq (info only) */
1286 t1 = (res_mode->left_margin + res_mode->xres +
1287 res_mode->right_margin + res_mode->hsync_len) / 8;
1289 t1 *= res_mode->pixclock;
1291 hsynch = 1000000000L / t1;
1293 (res_mode->upper_margin + res_mode->yres +
1294 res_mode->lower_margin + res_mode->vsync_len);
1296 vsynch = 1000000000L / t1;
1298 /* fill in Graphic device struct */
1299 sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
1300 res_mode->yres, bits_per_pixel, (hsynch / 1000),
1302 printf ("%s\n", pGD->modeIdent);
1303 pGD->winSizeX = res_mode->xres;
1304 pGD->winSizeY = res_mode->yres;
1305 pGD->plnSizeX = res_mode->xres;
1306 pGD->plnSizeY = res_mode->yres;
1307 switch (bits_per_pixel) {
1309 pGD->gdfBytesPP = 1;
1310 pGD->gdfIndex = GDF__8BIT_INDEX;
1313 pGD->gdfBytesPP = 2;
1314 pGD->gdfIndex = GDF_15BIT_555RGB;
1317 pGD->gdfBytesPP = 2;
1318 pGD->gdfIndex = GDF_16BIT_565RGB;
1321 pGD->gdfBytesPP = 3;
1322 pGD->gdfIndex = GDF_24BIT_888RGB;
1325 pGD->isaBase = CFG_ISA_IO_BASE_ADDRESS;
1326 pGD->pciBase = pci_mem_base;
1327 pGD->frameAdrs = pci_mem_base;
1328 pGD->memSize = chips_param->max_mem;
1329 /* Cursor Start Address */
1331 (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) + pci_mem_base;
1332 if ((pGD->dprBase & 0x0fff) != 0) {
1334 pGD->dprBase &= 0xfffff000;
1335 pGD->dprBase += 0x00001000;
1337 PRINTF ("Cursor Start %x Pattern Start %x\n", pGD->dprBase,
1339 pGD->vprBase = pci_mem_base; /* Dummy */
1340 pGD->cprBase = pci_mem_base; /* Dummy */
1341 /* set up Hardware */
1343 ctWrite (CT_MSR_W_O, 0x01);
1345 /* set the extended Registers */
1346 ctLoadRegs (CT_XR_O, xreg);
1347 /* set atribute registers */
1349 /* set Graphics register */
1355 SetMsrRegs (res_mode);
1357 /* set CRT Registers */
1358 SetCrRegs (res_mode, bits_per_pixel);
1359 /* set color mode */
1360 SetBitsPerPixelIntoXrRegs (bits_per_pixel);
1363 FindAndSetPllParamIntoXrRegs (res_mode->pixclock, chips_param);
1365 ctWrite_i (CT_SR_O, 0, 0x03); /* clear synchronous reset */
1366 /* Clear video memory */
1367 i = pGD->memSize / 4;
1368 vm = (unsigned int *) pGD->pciBase;
1371 SetDrawingEngine (bits_per_pixel);
1376 return ((void *) &ctfb);
1379 /*******************************************************************************
1381 * Set a RGB color in the LUT (8 bit index)
1384 video_set_lut (unsigned int index, /* color number */
1385 unsigned char r, /* red */
1386 unsigned char g, /* green */
1387 unsigned char b /* blue */
1391 ctWrite (CT_LUT_MASK_O, 0xff);
1393 ctWrite (CT_LUT_START_O, (char) index);
1395 ctWrite (CT_LUT_RGB_O, r); /* red */
1396 ctWrite (CT_LUT_RGB_O, g); /* green */
1397 ctWrite (CT_LUT_RGB_O, b); /* blue */
1399 ctWrite (CT_LUT_MASK_O, 0xff);
1402 /*******************************************************************************
1404 * Drawing engine fill on screen region
1407 video_hw_rectfill (unsigned int bpp, /* bytes per pixel */
1408 unsigned int dst_x, /* dest pos x */
1409 unsigned int dst_y, /* dest pos y */
1410 unsigned int dim_x, /* frame width */
1411 unsigned int dim_y, /* frame height */
1412 unsigned int color /* fill color */
1415 GraphicDevice *pGD = (GraphicDevice *) & ctfb;
1416 unsigned long *p, br04;
1418 video_wait_bitblt (pGD->pciBase + BR04_o);
1420 p = (unsigned long *) PATTERN_ADR;
1423 bpp++; /* 24Bit needs a 32bit pattern */
1424 memset (p, color, (bpp * sizeof (unsigned char) * 8 * 8)); /* 8 x 8 pattern data */
1425 out32r (pGD->pciBase + BR07_o, ((pGD->winSizeX * dst_y) + dst_x) * pGD->gdfBytesPP); /* destination */
1426 br04 = in32r (pGD->pciBase + BR04_o) & 0xffffff00;
1427 br04 |= 0xF0; /* write Pattern P -> D */
1428 out32r (pGD->pciBase + BR04_o, br04); /* */
1429 out32r (pGD->pciBase + BR08_o, (dim_y << 16) + dim_x); /* starts the BITBlt */
1430 video_wait_bitblt (pGD->pciBase + BR04_o);
1433 /*******************************************************************************
1435 * Drawing engine bitblt with screen region
1438 video_hw_bitblt (unsigned int bpp, /* bytes per pixel */
1439 unsigned int src_x, /* source pos x */
1440 unsigned int src_y, /* source pos y */
1441 unsigned int dst_x, /* dest pos x */
1442 unsigned int dst_y, /* dest pos y */
1443 unsigned int dim_x, /* frame width */
1444 unsigned int dim_y /* frame height */
1447 GraphicDevice *pGD = (GraphicDevice *) & ctfb;
1450 br04 = in32r (pGD->pciBase + BR04_o);
1452 /* to prevent data corruption due to overlap, we have to
1453 * find out if, and how the frames overlaps */
1454 if (src_x < dst_x) {
1455 /* src is more left than dest
1456 * the frame may overlap -> start from right to left */
1457 br04 |= 0x00000100; /* set bit 8 */
1461 br04 &= 0xfffffeff; /* clear bit 8 left to right */
1463 if (src_y < dst_y) {
1464 /* src is higher than dst
1465 * the frame may overlap => start from bottom */
1466 br04 |= 0x00000200; /* set bit 9 */
1470 br04 &= 0xfffffdff; /* clear bit 9 top to bottom */
1473 out32r (pGD->pciBase + BR06_o, ((pGD->winSizeX * src_y) + src_x) * pGD->gdfBytesPP); /* source */
1474 out32r (pGD->pciBase + BR07_o, ((pGD->winSizeX * dst_y) + dst_x) * pGD->gdfBytesPP); /* destination */
1476 br04 |= 0x000000CC; /* S -> D */
1477 out32r (pGD->pciBase + BR04_o, br04); /* */
1478 out32r (pGD->pciBase + BR08_o, (dim_y << 16) + dim_x); /* start the BITBlt */
1479 video_wait_bitblt (pGD->pciBase + BR04_o);
1482 #endif /* CONFIG_CT69000 */
1484 #endif /* CONFIG_VIDEO */