1 /*
2 * Copyright 1998 by Alan Hourihane, Wigan, England.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Alan Hourihane not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Alan Hourihane makes no representations
11 * about the suitability of this software for any purpose. It is provided
12 * "as is" without express or implied warranty.
13 *
14 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 *
22 * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
23 *
24 * IBM RAMDAC routines.
25 */
26
27 #ifdef HAVE_XORG_CONFIG_H
28 #include <xorg-config.h>
29 #endif
30
31 #include "xf86.h"
32 #include "xf86_OSproc.h"
33
34 #include "xf86Cursor.h"
35
36 #define INIT_IBM_RAMDAC_INFO
37 #include "IBMPriv.h"
38 #include "xf86RamDacPriv.h"
39
40 #define INITIALFREQERR 100000
41
42 unsigned long
IBMramdac640CalculateMNPCForClock(unsigned long RefClock,unsigned long ReqClock,char IsPixClock,unsigned long MinClock,unsigned long MaxClock,unsigned long * rM,unsigned long * rN,unsigned long * rP,unsigned long * rC)43 IBMramdac640CalculateMNPCForClock(unsigned long RefClock, /* In 100Hz units */
44 unsigned long ReqClock, /* In 100Hz units */
45 char IsPixClock, /* boolean, is this the pixel or the sys clock */
46 unsigned long MinClock, /* Min VCO rating */
47 unsigned long MaxClock, /* Max VCO rating */
48 unsigned long *rM, /* M Out */
49 unsigned long *rN, /* N Out */
50 unsigned long *rP, /* Min P In, P Out */
51 unsigned long *rC /* C Out */
52 )
53 {
54 unsigned long M, N, P, iP = *rP;
55 unsigned long IntRef, VCO, Clock;
56 long freqErr, lowestFreqErr = INITIALFREQERR;
57 unsigned long ActualClock = 0;
58
59 for (N = 0; N <= 63; N++) {
60 IntRef = RefClock / (N + 1);
61 if (IntRef < 10000)
62 break; /* IntRef needs to be >= 1MHz */
63 for (M = 2; M <= 127; M++) {
64 VCO = IntRef * (M + 1);
65 if ((VCO < MinClock) || (VCO > MaxClock))
66 continue;
67 for (P = iP; P <= 4; P++) {
68 if (P != 0)
69 Clock = (RefClock * (M + 1)) / ((N + 1) * 2 * P);
70 else
71 Clock = (RefClock * (M + 1)) / (N + 1);
72
73 freqErr = (Clock - ReqClock);
74
75 if (freqErr < 0) {
76 /* PixelClock gets rounded up always so monitor reports
77 correct frequency. */
78 if (IsPixClock)
79 continue;
80 freqErr = -freqErr;
81 }
82
83 if (freqErr < lowestFreqErr) {
84 *rM = M;
85 *rN = N;
86 *rP = P;
87 *rC = (VCO <= 1280000 ? 1 : 2);
88 ActualClock = Clock;
89
90 lowestFreqErr = freqErr;
91 /* Return if we found an exact match */
92 if (freqErr == 0)
93 return ActualClock;
94 }
95 }
96 }
97 }
98
99 return ActualClock;
100 }
101
102 unsigned long
IBMramdac526CalculateMNPCForClock(unsigned long RefClock,unsigned long ReqClock,char IsPixClock,unsigned long MinClock,unsigned long MaxClock,unsigned long * rM,unsigned long * rN,unsigned long * rP,unsigned long * rC)103 IBMramdac526CalculateMNPCForClock(unsigned long RefClock, /* In 100Hz units */
104 unsigned long ReqClock, /* In 100Hz units */
105 char IsPixClock, /* boolean, is this the pixel or the sys clock */
106 unsigned long MinClock, /* Min VCO rating */
107 unsigned long MaxClock, /* Max VCO rating */
108 unsigned long *rM, /* M Out */
109 unsigned long *rN, /* N Out */
110 unsigned long *rP, /* Min P In, P Out */
111 unsigned long *rC /* C Out */
112 )
113 {
114 unsigned long M, N, P, iP = *rP;
115 unsigned long IntRef, VCO, Clock;
116 long freqErr, lowestFreqErr = INITIALFREQERR;
117 unsigned long ActualClock = 0;
118
119 for (N = 0; N <= 63; N++) {
120 IntRef = RefClock / (N + 1);
121 if (IntRef < 10000)
122 break; /* IntRef needs to be >= 1MHz */
123 for (M = 0; M <= 63; M++) {
124 VCO = IntRef * (M + 1);
125 if ((VCO < MinClock) || (VCO > MaxClock))
126 continue;
127 for (P = iP; P <= 4; P++) {
128 if (P)
129 Clock = (RefClock * (M + 1)) / ((N + 1) * 2 * P);
130 else
131 Clock = VCO;
132
133 freqErr = (Clock - ReqClock);
134
135 if (freqErr < 0) {
136 /* PixelClock gets rounded up always so monitor reports
137 correct frequency. */
138 if (IsPixClock)
139 continue;
140 freqErr = -freqErr;
141 }
142
143 if (freqErr < lowestFreqErr) {
144 *rM = M;
145 *rN = N;
146 *rP = P;
147 *rC = (VCO <= 1280000 ? 1 : 2);
148 ActualClock = Clock;
149
150 lowestFreqErr = freqErr;
151 /* Return if we found an exact match */
152 if (freqErr == 0)
153 return ActualClock;
154 }
155 }
156 }
157 }
158
159 return ActualClock;
160 }
161
162 void
IBMramdacRestore(ScrnInfoPtr pScrn,RamDacRecPtr ramdacPtr,RamDacRegRecPtr ramdacReg)163 IBMramdacRestore(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr,
164 RamDacRegRecPtr ramdacReg)
165 {
166 int i, maxreg, dacreg;
167
168 switch (ramdacPtr->RamDacType) {
169 case IBM640_RAMDAC:
170 maxreg = 0x300;
171 dacreg = 1024;
172 break;
173 default:
174 maxreg = 0x100;
175 dacreg = 768;
176 break;
177 }
178
179 /* Here we pass a short, so that we can evaluate a mask too */
180 /* So that the mask is the high byte and the data the low byte */
181 for (i = 0; i < maxreg; i++)
182 (*ramdacPtr->WriteDAC)
183 (pScrn, i, (ramdacReg->DacRegs[i] & 0xFF00) >> 8,
184 ramdacReg->DacRegs[i]);
185
186 (*ramdacPtr->WriteAddress) (pScrn, 0);
187 for (i = 0; i < dacreg; i++)
188 (*ramdacPtr->WriteData) (pScrn, ramdacReg->DAC[i]);
189 }
190
191 void
IBMramdacSave(ScrnInfoPtr pScrn,RamDacRecPtr ramdacPtr,RamDacRegRecPtr ramdacReg)192 IBMramdacSave(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr,
193 RamDacRegRecPtr ramdacReg)
194 {
195 int i, maxreg, dacreg;
196
197 switch (ramdacPtr->RamDacType) {
198 case IBM640_RAMDAC:
199 maxreg = 0x300;
200 dacreg = 1024;
201 break;
202 default:
203 maxreg = 0x100;
204 dacreg = 768;
205 break;
206 }
207
208 (*ramdacPtr->ReadAddress) (pScrn, 0);
209 for (i = 0; i < dacreg; i++)
210 ramdacReg->DAC[i] = (*ramdacPtr->ReadData) (pScrn);
211
212 for (i = 0; i < maxreg; i++)
213 ramdacReg->DacRegs[i] = (*ramdacPtr->ReadDAC) (pScrn, i);
214 }
215
216 RamDacHelperRecPtr
IBMramdacProbe(ScrnInfoPtr pScrn,RamDacSupportedInfoRecPtr ramdacs)217 IBMramdacProbe(ScrnInfoPtr pScrn,
218 RamDacSupportedInfoRecPtr ramdacs /* , RamDacRecPtr ramdacPtr */
219 )
220 {
221 RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
222 RamDacHelperRecPtr ramdacHelperPtr = NULL;
223 Bool RamDacIsSupported = FALSE;
224 int IBMramdac_ID = -1;
225 int i;
226 unsigned char id, rev, id2, rev2;
227
228 /* read ID and revision */
229 rev = (*ramdacPtr->ReadDAC) (pScrn, IBMRGB_rev);
230 id = (*ramdacPtr->ReadDAC) (pScrn, IBMRGB_id);
231
232 /* check if ID and revision are read only */
233 (*ramdacPtr->WriteDAC) (pScrn, ~rev, 0, IBMRGB_rev);
234 (*ramdacPtr->WriteDAC) (pScrn, ~id, 0, IBMRGB_id);
235 rev2 = (*ramdacPtr->ReadDAC) (pScrn, IBMRGB_rev);
236 id2 = (*ramdacPtr->ReadDAC) (pScrn, IBMRGB_id);
237
238 switch (id) {
239 case 0x30:
240 if (rev == 0xc0)
241 IBMramdac_ID = IBM624_RAMDAC;
242 if (rev == 0x80)
243 IBMramdac_ID = IBM624DB_RAMDAC;
244 break;
245 case 0x12:
246 if (rev == 0x1c)
247 IBMramdac_ID = IBM640_RAMDAC;
248 break;
249 case 0x01:
250 IBMramdac_ID = IBM525_RAMDAC;
251 break;
252 case 0x02:
253 if (rev == 0xf0)
254 IBMramdac_ID = IBM524_RAMDAC;
255 if (rev == 0xe0)
256 IBMramdac_ID = IBM524A_RAMDAC;
257 if (rev == 0xc0)
258 IBMramdac_ID = IBM526_RAMDAC;
259 if (rev == 0x80)
260 IBMramdac_ID = IBM526DB_RAMDAC;
261 break;
262 }
263
264 if (id == 1 || id == 2) {
265 if (id == id2 && rev == rev2) { /* IBM RGB52x found */
266 /* check for 128bit VRAM -> RGB528 */
267 if (((*ramdacPtr->ReadDAC) (pScrn, IBMRGB_misc1) & 0x03) == 0x03) {
268 IBMramdac_ID = IBM528_RAMDAC; /* 128bit DAC found */
269 if (rev == 0xe0)
270 IBMramdac_ID = IBM528A_RAMDAC;
271 }
272 }
273 }
274
275 (*ramdacPtr->WriteDAC) (pScrn, rev, 0, IBMRGB_rev);
276 (*ramdacPtr->WriteDAC) (pScrn, id, 0, IBMRGB_id);
277
278 if (IBMramdac_ID == -1) {
279 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
280 "Cannot determine IBM RAMDAC type, aborting\n");
281 return NULL;
282 }
283 else {
284 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
285 "Attached RAMDAC is %s\n",
286 IBMramdacDeviceInfo[IBMramdac_ID & 0xFFFF].DeviceName);
287 }
288
289 for (i = 0; ramdacs[i].token != -1; i++) {
290 if (ramdacs[i].token == IBMramdac_ID)
291 RamDacIsSupported = TRUE;
292 }
293
294 if (!RamDacIsSupported) {
295 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
296 "This IBM RAMDAC is NOT supported by this driver, aborting\n");
297 return NULL;
298 }
299
300 ramdacHelperPtr = RamDacHelperCreateInfoRec();
301 switch (IBMramdac_ID) {
302 case IBM526_RAMDAC:
303 case IBM526DB_RAMDAC:
304 ramdacHelperPtr->SetBpp = IBMramdac526SetBpp;
305 ramdacHelperPtr->HWCursorInit = IBMramdac526HWCursorInit;
306 break;
307 case IBM640_RAMDAC:
308 ramdacHelperPtr->SetBpp = IBMramdac640SetBpp;
309 ramdacHelperPtr->HWCursorInit = IBMramdac640HWCursorInit;
310 break;
311 }
312 ramdacPtr->RamDacType = IBMramdac_ID;
313 ramdacHelperPtr->RamDacType = IBMramdac_ID;
314 ramdacHelperPtr->Save = IBMramdacSave;
315 ramdacHelperPtr->Restore = IBMramdacRestore;
316
317 return ramdacHelperPtr;
318 }
319
320 void
IBMramdac526SetBpp(ScrnInfoPtr pScrn,RamDacRegRecPtr ramdacReg)321 IBMramdac526SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg)
322 {
323 ramdacReg->DacRegs[IBMRGB_key_control] = 0x00; /* Disable Chroma Key */
324
325 switch (pScrn->bitsPerPixel) {
326 case 32:
327 ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_32BPP;
328 ramdacReg->DacRegs[IBMRGB_32bpp] = B32_DCOL_DIRECT;
329 ramdacReg->DacRegs[IBMRGB_24bpp] = 0;
330 ramdacReg->DacRegs[IBMRGB_16bpp] = 0;
331 ramdacReg->DacRegs[IBMRGB_8bpp] = 0;
332 if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) {
333 ramdacReg->DacRegs[IBMRGB_key_control] = 0x01; /* Enable Key */
334 ramdacReg->DacRegs[IBMRGB_key] = 0xFF;
335 ramdacReg->DacRegs[IBMRGB_key_mask] = 0xFF;
336 }
337 break;
338 case 24:
339 ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_24BPP;
340 ramdacReg->DacRegs[IBMRGB_32bpp] = 0;
341 ramdacReg->DacRegs[IBMRGB_24bpp] = B24_DCOL_DIRECT;
342 ramdacReg->DacRegs[IBMRGB_16bpp] = 0;
343 ramdacReg->DacRegs[IBMRGB_8bpp] = 0;
344 break;
345 case 16:
346 if (pScrn->depth == 16) {
347 ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_16BPP;
348 ramdacReg->DacRegs[IBMRGB_32bpp] = 0;
349 ramdacReg->DacRegs[IBMRGB_24bpp] = 0;
350 ramdacReg->DacRegs[IBMRGB_16bpp] = B16_DCOL_DIRECT | B16_LINEAR |
351 B16_CONTIGUOUS | B16_565;
352 ramdacReg->DacRegs[IBMRGB_8bpp] = 0;
353 }
354 else {
355 ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_16BPP;
356 ramdacReg->DacRegs[IBMRGB_32bpp] = 0;
357 ramdacReg->DacRegs[IBMRGB_24bpp] = 0;
358 ramdacReg->DacRegs[IBMRGB_16bpp] = B16_DCOL_DIRECT | B16_LINEAR |
359 B16_CONTIGUOUS | B16_555;
360 ramdacReg->DacRegs[IBMRGB_8bpp] = 0;
361 }
362 break;
363 case 8:
364 ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_8BPP;
365 ramdacReg->DacRegs[IBMRGB_32bpp] = 0;
366 ramdacReg->DacRegs[IBMRGB_24bpp] = 0;
367 ramdacReg->DacRegs[IBMRGB_16bpp] = 0;
368 ramdacReg->DacRegs[IBMRGB_8bpp] = B8_DCOL_INDIRECT;
369 break;
370 case 4:
371 ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_4BPP;
372 ramdacReg->DacRegs[IBMRGB_32bpp] = 0;
373 ramdacReg->DacRegs[IBMRGB_24bpp] = 0;
374 ramdacReg->DacRegs[IBMRGB_16bpp] = 0;
375 ramdacReg->DacRegs[IBMRGB_8bpp] = 0;
376 }
377 }
378
379 IBMramdac526SetBppProc *
IBMramdac526SetBppWeak(void)380 IBMramdac526SetBppWeak(void)
381 {
382 return IBMramdac526SetBpp;
383 }
384
385 void
IBMramdac640SetBpp(ScrnInfoPtr pScrn,RamDacRegRecPtr ramdacReg)386 IBMramdac640SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg)
387 {
388 unsigned char bpp = 0x00;
389 unsigned char overlaybpp = 0x00;
390 unsigned char offset = 0x00;
391 unsigned char dispcont = 0x44;
392
393 ramdacReg->DacRegs[RGB640_SER_WID_03_00] = 0x00;
394 ramdacReg->DacRegs[RGB640_SER_WID_07_04] = 0x00;
395 ramdacReg->DacRegs[RGB640_DIAGS] = 0x07;
396
397 switch (pScrn->depth) {
398 case 8:
399 ramdacReg->DacRegs[RGB640_SER_07_00] = 0x00;
400 ramdacReg->DacRegs[RGB640_SER_15_08] = 0x00;
401 ramdacReg->DacRegs[RGB640_SER_23_16] = 0x00;
402 ramdacReg->DacRegs[RGB640_SER_31_24] = 0x00;
403 ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_16_1; /*16:1 Mux */
404 ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PCLK_8; /* pll / 8 */
405 bpp = 0x03;
406 break;
407 case 15:
408 ramdacReg->DacRegs[RGB640_SER_07_00] = 0x10;
409 ramdacReg->DacRegs[RGB640_SER_15_08] = 0x11;
410 ramdacReg->DacRegs[RGB640_SER_23_16] = 0x00;
411 ramdacReg->DacRegs[RGB640_SER_31_24] = 0x00;
412 ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_8_1; /* 8:1 Mux */
413 ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PCLK_8; /* pll / 8 */
414 bpp = 0x0E;
415 break;
416 case 16:
417 ramdacReg->DacRegs[RGB640_SER_07_00] = 0x10;
418 ramdacReg->DacRegs[RGB640_SER_15_08] = 0x11;
419 ramdacReg->DacRegs[RGB640_SER_23_16] = 0x00;
420 ramdacReg->DacRegs[RGB640_SER_31_24] = 0x00;
421 ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_8_1; /* 8:1 Mux */
422 ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PCLK_8; /* pll / 8 */
423 bpp = 0x05;
424 break;
425 case 24:
426 ramdacReg->DacRegs[RGB640_SER_07_00] = 0x30;
427 ramdacReg->DacRegs[RGB640_SER_15_08] = 0x31;
428 ramdacReg->DacRegs[RGB640_SER_23_16] = 0x32;
429 ramdacReg->DacRegs[RGB640_SER_31_24] = 0x33;
430 ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_4_1; /* 4:1 Mux */
431 ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PCLK_8; /* pll / 8 */
432 bpp = 0x09;
433 if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) {
434 ramdacReg->DacRegs[RGB640_SER_WID_07_04] = 0x04;
435 ramdacReg->DacRegs[RGB640_CHROMA_KEY0] = 0xFF;
436 ramdacReg->DacRegs[RGB640_CHROMA_MASK0] = 0xFF;
437 offset = 0x04;
438 overlaybpp = 0x04;
439 dispcont = 0x48;
440 }
441 break;
442 case 30: /* 10 bit dac */
443 ramdacReg->DacRegs[RGB640_SER_07_00] = 0x30;
444 ramdacReg->DacRegs[RGB640_SER_15_08] = 0x31;
445 ramdacReg->DacRegs[RGB640_SER_23_16] = 0x32;
446 ramdacReg->DacRegs[RGB640_SER_31_24] = 0x33;
447 ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_4_1; /* 4:1 Mux */
448 ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PSIZE10 | IBM640_PCLK_8; /* pll / 8 */
449 bpp = 0x0D;
450 break;
451 }
452
453 {
454 int i;
455
456 for (i = 0x100; i < 0x140; i += 4) {
457 /* Initialize FrameBuffer Window Attribute Table */
458 ramdacReg->DacRegs[i + 0] = bpp;
459 ramdacReg->DacRegs[i + 1] = offset;
460 ramdacReg->DacRegs[i + 2] = 0x00;
461 ramdacReg->DacRegs[i + 3] = 0x00;
462 /* Initialize Overlay Window Attribute Table */
463 ramdacReg->DacRegs[i + 0x100] = overlaybpp;
464 ramdacReg->DacRegs[i + 0x101] = 0x00;
465 ramdacReg->DacRegs[i + 0x102] = 0x00;
466 ramdacReg->DacRegs[i + 0x103] = dispcont;
467 }
468 }
469 }
470
471 static void
IBMramdac526ShowCursor(ScrnInfoPtr pScrn)472 IBMramdac526ShowCursor(ScrnInfoPtr pScrn)
473 {
474 RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
475
476 /* Enable cursor - X11 mode */
477 (*ramdacPtr->WriteDAC) (pScrn, IBMRGB_curs, 0x00, 0x07);
478 }
479
480 static void
IBMramdac640ShowCursor(ScrnInfoPtr pScrn)481 IBMramdac640ShowCursor(ScrnInfoPtr pScrn)
482 {
483 RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
484
485 /* Enable cursor - mode2 (x11 mode) */
486 (*ramdacPtr->WriteDAC) (pScrn, RGB640_CURSOR_CONTROL, 0x00, 0x0B);
487 (*ramdacPtr->WriteDAC) (pScrn, RGB640_CROSSHAIR_CONTROL, 0x00, 0x00);
488 }
489
490 static void
IBMramdac526HideCursor(ScrnInfoPtr pScrn)491 IBMramdac526HideCursor(ScrnInfoPtr pScrn)
492 {
493 RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
494
495 /* Disable cursor - X11 mode */
496 (*ramdacPtr->WriteDAC) (pScrn, IBMRGB_curs, 0x00, 0x24);
497 }
498
499 static void
IBMramdac640HideCursor(ScrnInfoPtr pScrn)500 IBMramdac640HideCursor(ScrnInfoPtr pScrn)
501 {
502 RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
503
504 /* Disable cursor - mode2 (x11 mode) */
505 (*ramdacPtr->WriteDAC) (pScrn, RGB640_CURSOR_CONTROL, 0x00, 0x08);
506 }
507
508 static void
IBMramdac526SetCursorPosition(ScrnInfoPtr pScrn,int x,int y)509 IBMramdac526SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
510 {
511 RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
512
513 x += 64;
514 y += 64;
515
516 (*ramdacPtr->WriteDAC) (pScrn, IBMRGB_curs_hot_x, 0x00, 0x3f);
517 (*ramdacPtr->WriteDAC) (pScrn, IBMRGB_curs_hot_y, 0x00, 0x3f);
518 (*ramdacPtr->WriteDAC) (pScrn, IBMRGB_curs_xl, 0x00, x & 0xff);
519 (*ramdacPtr->WriteDAC) (pScrn, IBMRGB_curs_xh, 0x00, (x >> 8) & 0xf);
520 (*ramdacPtr->WriteDAC) (pScrn, IBMRGB_curs_yl, 0x00, y & 0xff);
521 (*ramdacPtr->WriteDAC) (pScrn, IBMRGB_curs_yh, 0x00, (y >> 8) & 0xf);
522 }
523
524 static void
IBMramdac640SetCursorPosition(ScrnInfoPtr pScrn,int x,int y)525 IBMramdac640SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
526 {
527 RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
528
529 x += 64;
530 y += 64;
531
532 (*ramdacPtr->WriteDAC) (pScrn, RGB640_CURS_OFFSETX, 0x00, 0x3f);
533 (*ramdacPtr->WriteDAC) (pScrn, RGB640_CURS_OFFSETY, 0x00, 0x3f);
534 (*ramdacPtr->WriteDAC) (pScrn, RGB640_CURS_X_LOW, 0x00, x & 0xff);
535 (*ramdacPtr->WriteDAC) (pScrn, RGB640_CURS_X_HIGH, 0x00, (x >> 8) & 0xf);
536 (*ramdacPtr->WriteDAC) (pScrn, RGB640_CURS_Y_LOW, 0x00, y & 0xff);
537 (*ramdacPtr->WriteDAC) (pScrn, RGB640_CURS_Y_HIGH, 0x00, (y >> 8) & 0xf);
538 }
539
540 static void
IBMramdac526SetCursorColors(ScrnInfoPtr pScrn,int bg,int fg)541 IBMramdac526SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
542 {
543 RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
544
545 (*ramdacPtr->WriteDAC) (pScrn, IBMRGB_curs_col1_r, 0x00, bg >> 16);
546 (*ramdacPtr->WriteDAC) (pScrn, IBMRGB_curs_col1_g, 0x00, bg >> 8);
547 (*ramdacPtr->WriteDAC) (pScrn, IBMRGB_curs_col1_b, 0x00, bg);
548 (*ramdacPtr->WriteDAC) (pScrn, IBMRGB_curs_col2_r, 0x00, fg >> 16);
549 (*ramdacPtr->WriteDAC) (pScrn, IBMRGB_curs_col2_g, 0x00, fg >> 8);
550 (*ramdacPtr->WriteDAC) (pScrn, IBMRGB_curs_col2_b, 0x00, fg);
551 }
552
553 static void
IBMramdac640SetCursorColors(ScrnInfoPtr pScrn,int bg,int fg)554 IBMramdac640SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
555 {
556 RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
557
558 (*ramdacPtr->WriteDAC) (pScrn, RGB640_CURS_COL0, 0x00, 0);
559 (*ramdacPtr->WriteData) (pScrn, fg >> 16);
560 (*ramdacPtr->WriteData) (pScrn, fg >> 8);
561 (*ramdacPtr->WriteData) (pScrn, fg);
562 (*ramdacPtr->WriteData) (pScrn, bg >> 16);
563 (*ramdacPtr->WriteData) (pScrn, bg >> 8);
564 (*ramdacPtr->WriteData) (pScrn, bg);
565 (*ramdacPtr->WriteData) (pScrn, fg >> 16);
566 (*ramdacPtr->WriteData) (pScrn, fg >> 8);
567 (*ramdacPtr->WriteData) (pScrn, fg);
568 (*ramdacPtr->WriteData) (pScrn, bg >> 16);
569 (*ramdacPtr->WriteData) (pScrn, bg >> 8);
570 (*ramdacPtr->WriteData) (pScrn, bg);
571 }
572
573 static Bool
IBMramdac526LoadCursorImage(ScrnInfoPtr pScrn,unsigned char * src)574 IBMramdac526LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
575 {
576 RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
577 int i;
578
579 /*
580 * Output the cursor data. The realize function has put the planes into
581 * their correct order, so we can just blast this out.
582 */
583 for (i = 0; i < 1024; i++)
584 (*ramdacPtr->WriteDAC) (pScrn, IBMRGB_curs_array + i, 0x00, (*src++));
585 return TRUE;
586 }
587
588 static Bool
IBMramdac640LoadCursorImage(ScrnInfoPtr pScrn,unsigned char * src)589 IBMramdac640LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
590 {
591 RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
592 int i;
593
594 /*
595 * Output the cursor data. The realize function has put the planes into
596 * their correct order, so we can just blast this out.
597 */
598 for (i = 0; i < 1024; i++)
599 (*ramdacPtr->WriteDAC) (pScrn, RGB640_CURS_WRITE + i, 0x00, (*src++));
600 return TRUE;
601 }
602
603 static Bool
IBMramdac526UseHWCursor(ScreenPtr pScr,CursorPtr pCurs)604 IBMramdac526UseHWCursor(ScreenPtr pScr, CursorPtr pCurs)
605 {
606 return TRUE;
607 }
608
609 static Bool
IBMramdac640UseHWCursor(ScreenPtr pScr,CursorPtr pCurs)610 IBMramdac640UseHWCursor(ScreenPtr pScr, CursorPtr pCurs)
611 {
612 return TRUE;
613 }
614
615 void
IBMramdac526HWCursorInit(xf86CursorInfoPtr infoPtr)616 IBMramdac526HWCursorInit(xf86CursorInfoPtr infoPtr)
617 {
618 infoPtr->MaxWidth = 64;
619 infoPtr->MaxHeight = 64;
620 infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
621 HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
622 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1;
623 infoPtr->SetCursorColors = IBMramdac526SetCursorColors;
624 infoPtr->SetCursorPosition = IBMramdac526SetCursorPosition;
625 infoPtr->LoadCursorImageCheck = IBMramdac526LoadCursorImage;
626 infoPtr->HideCursor = IBMramdac526HideCursor;
627 infoPtr->ShowCursor = IBMramdac526ShowCursor;
628 infoPtr->UseHWCursor = IBMramdac526UseHWCursor;
629 }
630
631 void
IBMramdac640HWCursorInit(xf86CursorInfoPtr infoPtr)632 IBMramdac640HWCursorInit(xf86CursorInfoPtr infoPtr)
633 {
634 infoPtr->MaxWidth = 64;
635 infoPtr->MaxHeight = 64;
636 infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
637 HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
638 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1;
639 infoPtr->SetCursorColors = IBMramdac640SetCursorColors;
640 infoPtr->SetCursorPosition = IBMramdac640SetCursorPosition;
641 infoPtr->LoadCursorImageCheck = IBMramdac640LoadCursorImage;
642 infoPtr->HideCursor = IBMramdac640HideCursor;
643 infoPtr->ShowCursor = IBMramdac640ShowCursor;
644 infoPtr->UseHWCursor = IBMramdac640UseHWCursor;
645 }
646