i128IBMDAC.c revision 7965d9ac
150806d53Smrg/*
250806d53Smrg * Copyright 1996-2000 by Robin Cutshaw <robin@XFree86.Org>
350806d53Smrg *
450806d53Smrg * Permission to use, copy, modify, distribute, and sell this software and its
550806d53Smrg * documentation for any purpose is hereby granted without fee, provided that
650806d53Smrg * the above copyright notice appear in all copies and that both that
750806d53Smrg * copyright notice and this permission notice appear in supporting
850806d53Smrg * documentation, and that the name of Robin Cutshaw not be used in
950806d53Smrg * advertising or publicity pertaining to distribution of the software without
1050806d53Smrg * specific, written prior permission.  Robin Cutshaw makes no representations
1150806d53Smrg * about the suitability of this software for any purpose.  It is provided
1250806d53Smrg * "as is" without express or implied warranty.
1350806d53Smrg *
1450806d53Smrg * ROBIN CUTSHAW DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1550806d53Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
1650806d53Smrg * EVENT SHALL ROBIN CUTSHAW BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1750806d53Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
1850806d53Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
1950806d53Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2050806d53Smrg * PERFORMANCE OF THIS SOFTWARE.
2150806d53Smrg *
2250806d53Smrg */
2350806d53Smrg
2450806d53Smrg
2550806d53Smrg#ifdef HAVE_CONFIG_H
2650806d53Smrg#include "config.h"
2750806d53Smrg#endif
2850806d53Smrg
2950806d53Smrg#include "xf86.h"
3050806d53Smrg#include "xf86PciInfo.h"
3150806d53Smrg#include "xf86Pci.h"
3250806d53Smrg#include "cursorstr.h"
3350806d53Smrg#include "servermd.h"
3450806d53Smrg
3550806d53Smrg#include "i128.h"
3650806d53Smrg#include "i128reg.h"
3750806d53Smrg#include "IBMRGB.h"
3850806d53Smrg
397965d9acSmrg#include <unistd.h>
4050806d53Smrg
4150806d53Smrgstatic void I128IBMShowCursor(ScrnInfoPtr pScrn);
4250806d53Smrgstatic void I128IBMHideCursor(ScrnInfoPtr pScrn);
4350806d53Smrgstatic void I128IBMSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
4450806d53Smrgstatic void I128IBMSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
4550806d53Smrgstatic void I128IBMLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
4650806d53Smrgstatic unsigned char *I128IBMRealizeCursor(xf86CursorInfoPtr infoPtr,
4750806d53Smrg        CursorPtr pCurs);
4850806d53Smrgstatic Bool I128IBMUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs);
4950806d53Smrg
5050806d53Smrg
5150806d53SmrgBool
5250806d53SmrgI128IBMHWCursorInit(ScrnInfoPtr pScrn)
5350806d53Smrg{
5450806d53Smrg   xf86CursorInfoPtr infoPtr;
5550806d53Smrg   ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
5650806d53Smrg   I128Ptr pI128 = I128PTR(pScrn);
5750806d53Smrg
5850806d53Smrg   if (!pI128->HWCursor)
5950806d53Smrg      return FALSE;
6050806d53Smrg
6150806d53Smrg   infoPtr = xf86CreateCursorInfoRec();
6250806d53Smrg   if (!infoPtr) return FALSE;
6350806d53Smrg
6450806d53Smrg   pI128->CursorInfoRec = infoPtr;
6550806d53Smrg   infoPtr->MaxWidth = 64;
6650806d53Smrg   infoPtr->MaxHeight = 64;
6750806d53Smrg   infoPtr->SetCursorColors = I128IBMSetCursorColors;
6850806d53Smrg   infoPtr->SetCursorPosition = I128IBMSetCursorPosition;
6950806d53Smrg   infoPtr->LoadCursorImage = I128IBMLoadCursorImage;
7050806d53Smrg   infoPtr->HideCursor = I128IBMHideCursor;
7150806d53Smrg   infoPtr->ShowCursor = I128IBMShowCursor;
7250806d53Smrg   infoPtr->UseHWCursor = I128IBMUseHWCursor;
7350806d53Smrg   infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
7450806d53Smrg                    HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
7550806d53Smrg                    HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1;
7650806d53Smrg   infoPtr->RealizeCursor = I128IBMRealizeCursor;
7750806d53Smrg
7850806d53Smrg   return(xf86InitCursor(pScreen, infoPtr));
7950806d53Smrg}
8050806d53Smrg
8150806d53Smrg
8250806d53Smrg/*
8350806d53Smrg * Convert the cursor from server-format to hardware-format.  The IBMRGB
8450806d53Smrg * has two planes, plane 0 selects cursor color 0 or 1 and plane 1
8550806d53Smrg * selects transparent or display cursor.  The bits of these planes
8650806d53Smrg * are packed together so that one byte has 4 pixels. The organization
8750806d53Smrg * looks like:
8850806d53Smrg *             Byte 0x000 - 0x00F    top scan line, left to right
8950806d53Smrg *                  0x010 - 0x01F
9050806d53Smrg *                    .       .
9150806d53Smrg *                  0x3F0 - 0x3FF    bottom scan line
9250806d53Smrg *
9350806d53Smrg *             Byte/bit map - D7D6,D5D4,D3D2,D1D0  four pixels, two planes each
9450806d53Smrg *             Pixel/bit map - P1P0  (plane 1) == 1 maps to cursor color
9550806d53Smrg *                                   (plane 1) == 0 maps to transparent
9650806d53Smrg *                                   (plane 0) maps to cursor colors 0 and 1
9750806d53Smrg */
9850806d53Smrg
9950806d53Smrgstatic unsigned char *
10050806d53SmrgI128IBMRealizeCursor(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
10150806d53Smrg{
10250806d53Smrg   register int i, j;
10350806d53Smrg   unsigned char *pServMsk;
10450806d53Smrg   unsigned char *pServSrc;
10550806d53Smrg   int   wsrc, h;
10650806d53Smrg   unsigned char *mem, *dst;
10750806d53Smrg
10850806d53Smrg   mem = (unsigned char *)xcalloc(1,1024);  /* 64x64x2 bits */
10950806d53Smrg   dst = mem;
11050806d53Smrg
11150806d53Smrg   if (!mem)
11250806d53Smrg      return NULL;
11350806d53Smrg
11450806d53Smrg   pServSrc = (unsigned char *)pCurs->bits->source;
11550806d53Smrg   pServMsk = (unsigned char *)pCurs->bits->mask;
11650806d53Smrg
11750806d53Smrg   h = pCurs->bits->height;
11850806d53Smrg   if (h > infoPtr->MaxHeight)
11950806d53Smrg      h = infoPtr->MaxHeight;
12050806d53Smrg
12150806d53Smrg   wsrc = PixmapBytePad(pCurs->bits->width, 1);	/* bytes per line */
12250806d53Smrg
12350806d53Smrg   for (i = 0; i < infoPtr->MaxHeight; i++,mem+=16) {
12450806d53Smrg      for (j = 0; j < infoPtr->MaxWidth / 8; j++) {
12550806d53Smrg	 register unsigned char mask, source;
12650806d53Smrg
12750806d53Smrg	 if (i < h && j < wsrc) {
12850806d53Smrg	    /*
12950806d53Smrg	     * mask byte ABCDEFGH and source byte 12345678 map to two byte
13050806d53Smrg	     * cursor data H8G7F6E5 D4C3B2A1
13150806d53Smrg	     */
13250806d53Smrg	    mask = *pServMsk++;
13350806d53Smrg	    source = *pServSrc++ & mask;
13450806d53Smrg
13550806d53Smrg	    /* map 1 byte source and mask into two byte cursor data */
13650806d53Smrg	    mem[j*2] =     ((mask&0x01) << 7) | ((source&0x01) << 6) |
13750806d53Smrg		           ((mask&0x02) << 4) | ((source&0x02) << 3) |
13850806d53Smrg		           ((mask&0x04) << 1) | (source&0x04)        |
13950806d53Smrg		           ((mask&0x08) >> 2) | ((source&0x08) >> 3) ;
14050806d53Smrg	    mem[(j*2)+1] = ((mask&0x10) << 3) | ((source&0x10) << 2) |
14150806d53Smrg		           (mask&0x20)        | ((source&0x20) >> 1) |
14250806d53Smrg		           ((mask&0x40) >> 3) | ((source&0x40) >> 4) |
14350806d53Smrg		           ((mask&0x80) >> 6) | ((source&0x80) >> 7) ;
14450806d53Smrg	 } else {
14550806d53Smrg	    mem[j*2]     = 0x00;
14650806d53Smrg	    mem[(j*2)+1] = 0x00;
14750806d53Smrg	 }
14850806d53Smrg      }
14950806d53Smrg      /*
15050806d53Smrg       * if we still have more bytes on this line (j < wsrc),
15150806d53Smrg       * we have to ignore the rest of the line.
15250806d53Smrg       */
15350806d53Smrg       while (j++ < wsrc) pServMsk++,pServSrc++;
15450806d53Smrg   }
15550806d53Smrg   return dst;
15650806d53Smrg}
15750806d53Smrg
15850806d53Smrg
15950806d53Smrgstatic void
16050806d53SmrgI128IBMShowCursor(ScrnInfoPtr pScrn)
16150806d53Smrg{
16250806d53Smrg   CARD32 tmpl, tmph;
16350806d53Smrg   I128Ptr pI128 = I128PTR(pScrn);
16450806d53Smrg
16550806d53Smrg   /* Enable cursor - X11 mode */
16650806d53Smrg   tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF;
16750806d53Smrg   tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF;
16850806d53Smrg   pI128->mem.rbase_g[IDXCTL_I] = 0;					MB;
16950806d53Smrg   pI128->mem.rbase_g[IDXH_I] = 0;					MB;
17050806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs;				MB;
17150806d53Smrg   pI128->mem.rbase_g[DATA_I] = 0x27;					MB;
17250806d53Smrg
17350806d53Smrg   pI128->mem.rbase_g[IDXH_I] = tmph;					MB;
17450806d53Smrg   pI128->mem.rbase_g[IDXL_I] = tmpl;					MB;
17550806d53Smrg
17650806d53Smrg   return;
17750806d53Smrg}
17850806d53Smrg
17950806d53Smrgstatic void
18050806d53SmrgI128IBMHideCursor(ScrnInfoPtr pScrn)
18150806d53Smrg{
18250806d53Smrg   CARD32 tmpl, tmph, tmp1;
18350806d53Smrg   I128Ptr pI128 = I128PTR(pScrn);
18450806d53Smrg
18550806d53Smrg   tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF;
18650806d53Smrg   tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF;
18750806d53Smrg   pI128->mem.rbase_g[IDXCTL_I] = 0;					MB;
18850806d53Smrg   pI128->mem.rbase_g[IDXH_I] = 0;					MB;
18950806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs;				MB;
19050806d53Smrg   tmp1 = pI128->mem.rbase_g[DATA_I] & 0xFC;
19150806d53Smrg   pI128->mem.rbase_g[DATA_I] = tmp1;					MB;
19250806d53Smrg
19350806d53Smrg   pI128->mem.rbase_g[IDXH_I] = tmph;					MB;
19450806d53Smrg   pI128->mem.rbase_g[IDXL_I] = tmpl;					MB;
19550806d53Smrg
19650806d53Smrg   return;
19750806d53Smrg}
19850806d53Smrg
19950806d53Smrgstatic void
20050806d53SmrgI128IBMSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
20150806d53Smrg{
20250806d53Smrg   CARD32 tmpl, tmph;
20350806d53Smrg   I128Ptr pI128 = I128PTR(pScrn);
20450806d53Smrg
20550806d53Smrg   x += 64;
20650806d53Smrg   y += 64;
20750806d53Smrg
20850806d53Smrg   tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF;
20950806d53Smrg   tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF;
21050806d53Smrg
21150806d53Smrg   pI128->mem.rbase_g[IDXH_I] = 0;					MB;
21250806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_hot_x;			MB;
21350806d53Smrg   pI128->mem.rbase_g[DATA_I] = 0x3F;					MB;
21450806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_hot_y;			MB;
21550806d53Smrg   pI128->mem.rbase_g[DATA_I] = 0x3F;					MB;
21650806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_xl;				MB;
21750806d53Smrg   pI128->mem.rbase_g[DATA_I] = x & 0xFF;				MB;
21850806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_xh;				MB;
21950806d53Smrg   pI128->mem.rbase_g[DATA_I] = (x >> 8) & 0x0F;			MB;
22050806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_yl;				MB;
22150806d53Smrg   pI128->mem.rbase_g[DATA_I] = y & 0xFF;				MB;
22250806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_yh;				MB;
22350806d53Smrg   pI128->mem.rbase_g[DATA_I] = (y >> 8) & 0x0F;			MB;
22450806d53Smrg
22550806d53Smrg   pI128->mem.rbase_g[IDXH_I] = tmph;					MB;
22650806d53Smrg   pI128->mem.rbase_g[IDXL_I] = tmpl;					MB;
22750806d53Smrg
22850806d53Smrg   return;
22950806d53Smrg}
23050806d53Smrg
23150806d53Smrgstatic void
23250806d53SmrgI128IBMSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
23350806d53Smrg{
23450806d53Smrg   CARD32 tmp;
23550806d53Smrg   I128Ptr pI128 = I128PTR(pScrn);
23650806d53Smrg
23750806d53Smrg   tmp = pI128->mem.rbase_g[IDXL_I] & 0xFF;
23850806d53Smrg
23950806d53Smrg   /* Background color */
24050806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_col1_r;			MB;
24150806d53Smrg   pI128->mem.rbase_g[DATA_I] = (bg & 0x00FF0000) >> 16;		MB;
24250806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_col1_g;			MB;
24350806d53Smrg   pI128->mem.rbase_g[DATA_I] = (bg & 0x0000FF00) >> 8;			MB;
24450806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_col1_b;			MB;
24550806d53Smrg   pI128->mem.rbase_g[DATA_I] = (bg & 0x000000FF);			MB;
24650806d53Smrg
24750806d53Smrg   /* Foreground color */
24850806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_col2_r;			MB;
24950806d53Smrg   pI128->mem.rbase_g[DATA_I] = (fg & 0x00FF0000) >> 16;		MB;
25050806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_col2_g;			MB;
25150806d53Smrg   pI128->mem.rbase_g[DATA_I] = (fg & 0x0000FF00) >> 8;			MB;
25250806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_col2_b;			MB;
25350806d53Smrg   pI128->mem.rbase_g[DATA_I] = (fg & 0x000000FF);			MB;
25450806d53Smrg
25550806d53Smrg   pI128->mem.rbase_g[IDXL_I] = tmp;					MB;
25650806d53Smrg
25750806d53Smrg   return;
25850806d53Smrg}
25950806d53Smrg
26050806d53Smrgstatic void
26150806d53SmrgI128IBMLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
26250806d53Smrg{
26350806d53Smrg   I128Ptr pI128 = I128PTR(pScrn);
26450806d53Smrg   register int   i;
26550806d53Smrg   CARD32 tmph, tmpl, tmpc;
26650806d53Smrg
26750806d53Smrg   tmpc = pI128->mem.rbase_g[IDXCTL_I] & 0xFF;
26850806d53Smrg   tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF;
26950806d53Smrg   tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF;
27050806d53Smrg
27150806d53Smrg   pI128->BlockCursor = TRUE;
27250806d53Smrg
27350806d53Smrg   pI128->mem.rbase_g[IDXCTL_I] = 0;					MB;
27450806d53Smrg
27550806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_hot_x;			MB;
27650806d53Smrg   pI128->mem.rbase_g[DATA_I] = 0x00;					MB;
27750806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_hot_y;			MB;
27850806d53Smrg   pI128->mem.rbase_g[DATA_I] = 0x00;					MB;
27950806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_xl;				MB;
28050806d53Smrg   pI128->mem.rbase_g[DATA_I] = 0xFF;					MB;
28150806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_xh;				MB;
28250806d53Smrg   pI128->mem.rbase_g[DATA_I] = 0x7F;					MB;
28350806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_yl;				MB;
28450806d53Smrg   pI128->mem.rbase_g[DATA_I] = 0xFF;					MB;
28550806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_yh;				MB;
28650806d53Smrg   pI128->mem.rbase_g[DATA_I] = 0x7F;					MB;
28750806d53Smrg
28850806d53Smrg   pI128->mem.rbase_g[IDXH_I] = (IBMRGB_curs_array >> 8) & 0xFF;	MB;
28950806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_array & 0xFF;		MB;
29050806d53Smrg
29150806d53Smrg   pI128->mem.rbase_g[IDXCTL_I] = 1; /* enable auto-inc */		MB;
29250806d53Smrg
29350806d53Smrg   /*
29450806d53Smrg    * Output the cursor data.  The realize function has put the planes into
29550806d53Smrg    * their correct order, so we can just blast this out.
29650806d53Smrg    */
29750806d53Smrg   for (i = 0; i < 1024; i++,src++) {
29850806d53Smrg      pI128->mem.rbase_g[DATA_I] = (CARD32 )*src;			MB;
29950806d53Smrg   }
30050806d53Smrg
30150806d53Smrg   pI128->mem.rbase_g[IDXCTL_I] = tmpc;                                 MB;
30250806d53Smrg   pI128->mem.rbase_g[IDXH_I] = tmph;                                   MB;
30350806d53Smrg   pI128->mem.rbase_g[IDXL_I] = tmpl;                                   MB;
30450806d53Smrg
30550806d53Smrg   pI128->BlockCursor = FALSE;
30650806d53Smrg
30750806d53Smrg   return;
30850806d53Smrg}
30950806d53Smrg
31050806d53Smrg
31150806d53Smrgstatic Bool
31250806d53SmrgI128IBMUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs)
31350806d53Smrg{
31450806d53Smrg   if( XF86SCRNINFO(pScrn)->currentMode->Flags & V_DBLSCAN )
31550806d53Smrg      return FALSE;
31650806d53Smrg   return TRUE;
31750806d53Smrg}
31850806d53Smrg
31950806d53Smrg
32050806d53SmrgBool I128TIHWCursorInit(ScrnInfoPtr pScrn) { return FALSE; }
32150806d53SmrgBool I128ProgramTi3025(ScrnInfoPtr pScrn, DisplayModePtr mode) { return FALSE; }
32250806d53Smrg
32350806d53SmrgBool
32450806d53SmrgI128ProgramIBMRGB(ScrnInfoPtr pScrn, DisplayModePtr mode)
32550806d53Smrg{
32650806d53Smrg   I128Ptr pI128 = I128PTR(pScrn);
32750806d53Smrg   unsigned char tmp2, m, n, df, best_m, best_n, best_df, max_n;
32850806d53Smrg   CARD32 tmpl, tmph, tmpc;
32950806d53Smrg   long f, vrf, outf, best_diff, best_outf = 0, diff;
33050806d53Smrg   long requested_freq;
33150806d53Smrg   int   freq = mode->SynthClock;
33250806d53Smrg   int   flags = mode->Flags;
33350806d53Smrg
33450806d53Smrg#define REF_FREQ	 25175000
33550806d53Smrg#define MAX_VREF	  3380000
33650806d53Smrg/* Actually, MIN_VREF can be as low as 1000000;
33750806d53Smrg * this allows clock speeds down to 17 MHz      */
33850806d53Smrg#define MIN_VREF	  1500000
33950806d53Smrg#define MAX_VCO		220000000
34050806d53Smrg#define MIN_VCO		 65000000
34150806d53Smrg
34250806d53Smrg   if (freq < 25000) {
34350806d53Smrg       xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
34450806d53Smrg              "Specified dot clock (%.3f) too low for IBM RGB52x",
34550806d53Smrg	      freq / 1000.0);
34650806d53Smrg       return(FALSE);
34750806d53Smrg   } else if (freq > MAX_VCO) {
34850806d53Smrg       xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
34950806d53Smrg              "Specified dot clock (%.3f) too high for IBM RGB52x",
35050806d53Smrg	      freq / 1000.0);
35150806d53Smrg       return(FALSE);
35250806d53Smrg   }
35350806d53Smrg
35450806d53Smrg   requested_freq = freq * 1000;
35550806d53Smrg
35650806d53Smrg   best_m = best_n = best_df = 0;
35750806d53Smrg   best_diff = requested_freq;  /* worst case */
35850806d53Smrg
35950806d53Smrg   for (df=0; df<4; df++) {
36050806d53Smrg   	max_n = REF_FREQ / MIN_VREF;
36150806d53Smrg   	if (df < 3)
36250806d53Smrg   		max_n >>= 1;
36350806d53Smrg	for (n=2; n<max_n; n++)
36450806d53Smrg		for (m=65; m<=128; m++) {
36550806d53Smrg			vrf = REF_FREQ / n;
36650806d53Smrg			if (df < 3)
36750806d53Smrg				vrf >>= 1;
36850806d53Smrg			if ((vrf > MAX_VREF) || (vrf < MIN_VREF))
36950806d53Smrg				continue;
37050806d53Smrg
37150806d53Smrg			f = vrf * m;
37250806d53Smrg			outf = f;
37350806d53Smrg			if (df < 2)
37450806d53Smrg				outf >>= 2 - df;
37550806d53Smrg			if ((f > MAX_VCO) || (f < MIN_VCO))
37650806d53Smrg				continue;
37750806d53Smrg
37850806d53Smrg			/* outf is a valid freq, pick the closest now */
37950806d53Smrg
38050806d53Smrg			if ((diff = (requested_freq - outf)) < 0)
38150806d53Smrg				diff = -diff;;
38250806d53Smrg			if (diff < best_diff) {
38350806d53Smrg				best_diff = diff;
38450806d53Smrg				best_m = m;
38550806d53Smrg				best_n = n;
38650806d53Smrg				best_df = df;
38750806d53Smrg				best_outf = outf;
38850806d53Smrg			}
38950806d53Smrg		}
39050806d53Smrg   }
39150806d53Smrg
39250806d53Smrg   /* do we have an acceptably close frequency? (less than 1% diff) */
39350806d53Smrg
39450806d53Smrg   if (best_diff > (requested_freq/100)) {
39550806d53Smrg       xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
39650806d53Smrg              "Specified dot clock (%.3f) too far (best %.3f) IBM RGB52x",
39750806d53Smrg	      requested_freq / 1000.0, best_outf / 1000.0);
39850806d53Smrg       return(FALSE);
39950806d53Smrg   }
40050806d53Smrg
40150806d53Smrg   pI128->mem.rbase_g[PEL_MASK] = 0xFF;					MB;
40250806d53Smrg
40350806d53Smrg   tmpc = pI128->mem.rbase_g[IDXCTL_I] & 0xFF;
40450806d53Smrg   tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF;
40550806d53Smrg   tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF;
40650806d53Smrg
40750806d53Smrg   pI128->mem.rbase_g[IDXH_I] = 0;					MB;
40850806d53Smrg   pI128->mem.rbase_g[IDXCTL_I] = 0;					MB;
40950806d53Smrg
41050806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc_clock;			MB;
41150806d53Smrg   tmp2 = pI128->mem.rbase_g[DATA_I] & 0xFF;
41250806d53Smrg   pI128->mem.rbase_g[DATA_I] = tmp2 | 0x81;				MB;
41350806d53Smrg
41450806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_m0+4;				MB;
41550806d53Smrg   pI128->mem.rbase_g[DATA_I] = (best_df<<6) | (best_m&0x3f);		MB;
41650806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_n0+4;				MB;
41750806d53Smrg   pI128->mem.rbase_g[DATA_I] = best_n;					MB;
41850806d53Smrg
41950806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_pll_ctrl1;			MB;
42050806d53Smrg   tmp2 = pI128->mem.rbase_g[DATA_I] & 0xFF;
42150806d53Smrg   pI128->mem.rbase_g[DATA_I] = (tmp2&0xf8) | 3;  /* 8 M/N pairs in PLL */ MB;
42250806d53Smrg
42350806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_pll_ctrl2;			MB;
42450806d53Smrg   tmp2 = pI128->mem.rbase_g[DATA_I] & 0xFF;
42550806d53Smrg   pI128->mem.rbase_g[DATA_I] = (tmp2&0xf0) | 2;  /* clock number 2 */	MB;
42650806d53Smrg
42750806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc_clock;			MB;
42850806d53Smrg   tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf0;
42950806d53Smrg   pI128->mem.rbase_g[DATA_I] = tmp2 | ((flags & V_DBLCLK) ? 0x03 : 0x01); MB;
43050806d53Smrg
43150806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_sync;				MB;
43250806d53Smrg   pI128->mem.rbase_g[DATA_I] = ((flags & V_PHSYNC) ? 0x10 : 0x00)
43350806d53Smrg                           | ((flags & V_PVSYNC) ? 0x20 : 0x00);	MB;
43450806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_hsync_pos;			MB;
43550806d53Smrg   pI128->mem.rbase_g[DATA_I] = 0x01;  /* Delay syncs by 1 pclock */	MB;
43650806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_pwr_mgmt;			MB;
43750806d53Smrg   pI128->mem.rbase_g[DATA_I] = 0x00;					MB;
43850806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_dac_op;				MB;
43950806d53Smrg   tmp2 = (pI128->RamdacType == IBM528_DAC) ? 0x02 : 0x00;  /* fast slew */
44050806d53Smrg   if (pI128->DACSyncOnGreen) tmp2 |= 0x08;
44150806d53Smrg   pI128->mem.rbase_g[DATA_I] = tmp2;					MB;
44250806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_pal_ctrl;			MB;
44350806d53Smrg   pI128->mem.rbase_g[DATA_I] = 0x00;					MB;
44450806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk;				MB;
44550806d53Smrg   pI128->mem.rbase_g[DATA_I] = 0x01;					MB;
44650806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc1;				MB;
44750806d53Smrg   tmp2 = pI128->mem.rbase_g[DATA_I] & 0xbc;
44850806d53Smrg   tmp2 |= 0x20;
44950806d53Smrg   if ((pI128->MemoryType != I128_MEMORY_DRAM) &&
45050806d53Smrg       (pI128->MemoryType != I128_MEMORY_SGRAM))
45150806d53Smrg   	tmp2 |= (pI128->RamdacType == IBM528_DAC) ? 3 : 1;
45250806d53Smrg   pI128->mem.rbase_g[DATA_I] = tmp2;					MB;
45350806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc2;				MB;
45450806d53Smrg   tmp2 = 0x03;
45550806d53Smrg   if (pI128->DAC8Bit)
45650806d53Smrg	tmp2 |= 0x04;
45750806d53Smrg   if (!((pI128->MemoryType == I128_MEMORY_DRAM) &&
45850806d53Smrg	 (pI128->bitsPerPixel > 16)))
45950806d53Smrg	tmp2 |= 0x40;
46050806d53Smrg   if ((pI128->MemoryType == I128_MEMORY_SGRAM) &&
46150806d53Smrg	 (pI128->bitsPerPixel > 16) &&
46250806d53Smrg         (pI128->RamdacType != SILVER_HAMMER_DAC) )
46350806d53Smrg	tmp2 &= 0x3F;
46450806d53Smrg   pI128->mem.rbase_g[DATA_I] = tmp2;					MB;
46550806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc3;				MB;
46650806d53Smrg   pI128->mem.rbase_g[DATA_I] = 0x00;					MB;
46750806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc4;				MB;
46850806d53Smrg   pI128->mem.rbase_g[DATA_I] = 0x00;					MB;
46950806d53Smrg
47050806d53Smrg   /* ?? There is no write to cursor control register */
47150806d53Smrg
47250806d53Smrg   if (pI128->RamdacType == IBM526_DAC) {
47350806d53Smrg	if (pI128->MemoryType == I128_MEMORY_SGRAM) {
47450806d53Smrg	    pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_ref_div;		MB;
47550806d53Smrg	    pI128->mem.rbase_g[DATA_I] = 0x09;				MB;
47650806d53Smrg	    pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_vco_div;		MB;
47750806d53Smrg	    pI128->mem.rbase_g[DATA_I] = 0x83;				MB;
47850806d53Smrg	} else {
47950806d53Smrg	/* program mclock to 52MHz */
48050806d53Smrg	    pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_ref_div;		MB;
48150806d53Smrg	    pI128->mem.rbase_g[DATA_I] = 0x08;				MB;
48250806d53Smrg	    pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_vco_div;		MB;
48350806d53Smrg	    pI128->mem.rbase_g[DATA_I] = 0x41;				MB;
48450806d53Smrg	}
48550806d53Smrg	/* should delay at least a millisec so we'll wait 50 */
48650806d53Smrg   	usleep(50000);
48750806d53Smrg   }
48850806d53Smrg
48950806d53Smrg   switch (pI128->depth) {
49050806d53Smrg   	case 24: /* 32 bit */
49150806d53Smrg   		pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt;		MB;
49250806d53Smrg   		tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8;
49350806d53Smrg   		pI128->mem.rbase_g[DATA_I] = tmp2 | 0x06;		MB;
49450806d53Smrg   		pI128->mem.rbase_g[IDXL_I] = IBMRGB_32bpp;		MB;
49550806d53Smrg   		pI128->mem.rbase_g[DATA_I] = 0x03;			MB;
49650806d53Smrg   		break;
49750806d53Smrg	case 16:
49850806d53Smrg   		pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt;		MB;
49950806d53Smrg   		tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8;
50050806d53Smrg   		pI128->mem.rbase_g[DATA_I] = tmp2 | 0x04;		MB;
50150806d53Smrg   		pI128->mem.rbase_g[IDXL_I] = IBMRGB_16bpp;		MB;
50250806d53Smrg   		pI128->mem.rbase_g[DATA_I] = 0xC7;			MB;
50350806d53Smrg   		break;
50450806d53Smrg	case 15:
50550806d53Smrg   		pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt;		MB;
50650806d53Smrg   		tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8;
50750806d53Smrg   		pI128->mem.rbase_g[DATA_I] = tmp2 | 0x04;		MB;
50850806d53Smrg   		pI128->mem.rbase_g[IDXL_I] = IBMRGB_16bpp;		MB;
50950806d53Smrg   		pI128->mem.rbase_g[DATA_I] = 0xC5;			MB;
51050806d53Smrg   		break;
51150806d53Smrg	default: /* 8 bit */
51250806d53Smrg   		pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt;		MB;
51350806d53Smrg   		tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8;
51450806d53Smrg   		pI128->mem.rbase_g[DATA_I] = tmp2 | 0x03;		MB;
51550806d53Smrg   		pI128->mem.rbase_g[IDXL_I] = IBMRGB_8bpp;		MB;
51650806d53Smrg   		pI128->mem.rbase_g[DATA_I] = 0x00;			MB;
51750806d53Smrg   		break;
51850806d53Smrg   }
51950806d53Smrg
52050806d53Smrg   pI128->mem.rbase_g[IDXCTL_I] = tmpc;					MB;
52150806d53Smrg   pI128->mem.rbase_g[IDXH_I] = tmph;					MB;
52250806d53Smrg   pI128->mem.rbase_g[IDXL_I] = tmpl;					MB;
52350806d53Smrg
52450806d53Smrg   return(TRUE);
52550806d53Smrg}
52650806d53Smrg
52750806d53Smrg
52850806d53SmrgBool
52950806d53SmrgI128ProgramSilverHammer(ScrnInfoPtr pScrn, DisplayModePtr mode)
53050806d53Smrg{
53150806d53Smrg   /* The SilverHammer DAC is essentially the same as the IBMRGBxxx DACs,
53250806d53Smrg    * but with fewer options and a different reference frequency.
53350806d53Smrg    */
53450806d53Smrg
53550806d53Smrg   I128Ptr pI128 = I128PTR(pScrn);
53650806d53Smrg   unsigned char tmp2, m, n, df, best_m, best_n, best_df, max_n;
53750806d53Smrg   CARD32 tmpl, tmph, tmpc;
53850806d53Smrg   long f, vrf, outf, best_diff, best_outf = 0, diff;
53950806d53Smrg   long requested_freq;
54050806d53Smrg   int   freq = mode->SynthClock;
54150806d53Smrg   int   flags = mode->Flags;
54250806d53Smrg   int   skew = mode->HSkew;
54350806d53Smrg
54450806d53Smrg#undef  REF_FREQ
54550806d53Smrg#define REF_FREQ	 37500000
54650806d53Smrg#undef  MAX_VREF
54750806d53Smrg#define MAX_VREF	  9000000
54850806d53Smrg#define MIN_VREF	  1500000
54950806d53Smrg#undef  MAX_VCO
55050806d53Smrg#define MAX_VCO		270000000
55150806d53Smrg#define MIN_VCO		 65000000
55250806d53Smrg
55350806d53Smrg   if (freq < 25000) {
55450806d53Smrg       xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
55550806d53Smrg              "Specified dot clock (%.3f) too low for SilverHammer",
55650806d53Smrg	      freq / 1000.0);
55750806d53Smrg       return(FALSE);
55850806d53Smrg   } else if (freq > MAX_VCO) {
55950806d53Smrg       xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
56050806d53Smrg              "Specified dot clock (%.3f) too high for SilverHammer",
56150806d53Smrg	      freq / 1000.0);
56250806d53Smrg       return(FALSE);
56350806d53Smrg   }
56450806d53Smrg
56550806d53Smrg   requested_freq = freq * 1000;
56650806d53Smrg
56750806d53Smrg   best_m = best_n = best_df = 0;
56850806d53Smrg   best_diff = requested_freq;  /* worst case */
56950806d53Smrg
57050806d53Smrg   for (df=0; df<4; df++) {
57150806d53Smrg   	max_n = REF_FREQ / MIN_VREF;
57250806d53Smrg   	if (df < 3)
57350806d53Smrg   		max_n >>= 1;
57450806d53Smrg	for (n=2; n<max_n; n++)
57550806d53Smrg		for (m=65; m<=128; m++) {
57650806d53Smrg			vrf = REF_FREQ / n;
57750806d53Smrg			if (df < 3)
57850806d53Smrg				vrf >>= 1;
57950806d53Smrg			if ((vrf > MAX_VREF) || (vrf < MIN_VREF))
58050806d53Smrg				continue;
58150806d53Smrg
58250806d53Smrg			f = vrf * m;
58350806d53Smrg			outf = f;
58450806d53Smrg			if (df < 2)
58550806d53Smrg				outf >>= 2 - df;
58650806d53Smrg			if ((f > MAX_VCO) || (f < MIN_VCO))
58750806d53Smrg				continue;
58850806d53Smrg
58950806d53Smrg			/* outf is a valid freq, pick the closest now */
59050806d53Smrg
59150806d53Smrg			if ((diff = (requested_freq - outf)) < 0)
59250806d53Smrg				diff = -diff;;
59350806d53Smrg			if (diff < best_diff) {
59450806d53Smrg				best_diff = diff;
59550806d53Smrg				best_m = m;
59650806d53Smrg				best_n = n;
59750806d53Smrg				best_df = df;
59850806d53Smrg				best_outf = outf;
59950806d53Smrg			}
60050806d53Smrg		}
60150806d53Smrg   }
60250806d53Smrg
60350806d53Smrg   /* do we have an acceptably close frequency? (less than 1% diff) */
60450806d53Smrg
60550806d53Smrg   if (best_diff > (requested_freq/100)) {
60650806d53Smrg       xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
60750806d53Smrg              "Specified dot clock (%.3f) too far (best %.3f) SilverHammer",
60850806d53Smrg	      requested_freq / 1000.0, best_outf / 1000.0);
60950806d53Smrg       return(FALSE);
61050806d53Smrg   }
61150806d53Smrg
61250806d53Smrg   pI128->mem.rbase_g[PEL_MASK] = 0xFF;					MB;
61350806d53Smrg
61450806d53Smrg   tmpc = pI128->mem.rbase_g[IDXCTL_I] & 0xFF;
61550806d53Smrg   tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF;
61650806d53Smrg   tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF;
61750806d53Smrg
61850806d53Smrg   pI128->mem.rbase_g[IDXH_I] = 0;					MB;
61950806d53Smrg   pI128->mem.rbase_g[IDXCTL_I] = 0;					MB;
62050806d53Smrg
62150806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc_clock;			MB;
62250806d53Smrg   tmp2 = pI128->mem.rbase_g[DATA_I] & 0xFF;
62350806d53Smrg   pI128->mem.rbase_g[DATA_I] = tmp2 | 0x81;				MB;
62450806d53Smrg
62550806d53Smrg   if (!pI128->Primary) {
62650806d53Smrg       pI128->mem.rbase_g[IDXL_I] = IBMRGB_m0;				MB;
62750806d53Smrg       pI128->mem.rbase_g[DATA_I] = 0x15;				MB;
62850806d53Smrg       pI128->mem.rbase_g[IDXL_I] = IBMRGB_m0+1;			MB;
62950806d53Smrg       pI128->mem.rbase_g[DATA_I] = 0x10;				MB;
63050806d53Smrg       pI128->mem.rbase_g[IDXL_I] = IBMRGB_m0+2;			MB;
63150806d53Smrg       pI128->mem.rbase_g[DATA_I] = 0x2c;				MB;
63250806d53Smrg       pI128->mem.rbase_g[IDXL_I] = IBMRGB_m0+3;			MB;
63350806d53Smrg       pI128->mem.rbase_g[DATA_I] = 0x12;				MB;
63450806d53Smrg   }
63550806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_m0+4;				MB;
63650806d53Smrg   pI128->mem.rbase_g[DATA_I] = (best_df<<6) | (best_m&0x3f);		MB;
63750806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_n0+4;				MB;
63850806d53Smrg   pI128->mem.rbase_g[DATA_I] = best_n;					MB;
63950806d53Smrg
64050806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_pll_ctrl1;			MB;
64150806d53Smrg   tmp2 = pI128->mem.rbase_g[DATA_I] & 0xFF;
64250806d53Smrg   pI128->mem.rbase_g[DATA_I] = (tmp2&0xf8) | 3;  /* 8 M/N pairs in PLL */ MB;
64350806d53Smrg
64450806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_pll_ctrl2;			MB;
64550806d53Smrg   tmp2 = pI128->mem.rbase_g[DATA_I] & 0xFF;
64650806d53Smrg   pI128->mem.rbase_g[DATA_I] = (tmp2&0xf0) | 2;  /* clock number 2 */	MB;
64750806d53Smrg
64850806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc_clock;			MB;
64950806d53Smrg   tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf0;
65050806d53Smrg   pI128->mem.rbase_g[DATA_I] = tmp2 | ((flags & V_DBLCLK) ? 0x03 : 0x01); MB;
65150806d53Smrg
65250806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_sync;				MB;
65350806d53Smrg   pI128->mem.rbase_g[DATA_I] = ((flags & V_PHSYNC) ? 0x10 : 0x00)
65450806d53Smrg                           | ((flags & V_PVSYNC) ? 0x20 : 0x00);	MB;
65550806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_hsync_pos;			MB;
65650806d53Smrg   pI128->mem.rbase_g[DATA_I] = ((flags & V_HSKEW)  ? skew : 0x01);	MB;
65750806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_pwr_mgmt;			MB;
65850806d53Smrg/* Use 0x01 below with digital flat panel to conserve energy and reduce noise */
65950806d53Smrg   pI128->mem.rbase_g[DATA_I] = (pI128->FlatPanel ? 0x01 : 0x00);	MB;
66050806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_dac_op;				MB;
66150806d53Smrg   pI128->mem.rbase_g[DATA_I] = (pI128->DACSyncOnGreen ? 0x08 : 0x00);	MB;
66250806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_pal_ctrl;			MB;
66350806d53Smrg   pI128->mem.rbase_g[DATA_I] = 0x00;					MB;
66450806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk;				MB;
66550806d53Smrg   pI128->mem.rbase_g[DATA_I] = 0x01;					MB;
66650806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc1;				MB;
66750806d53Smrg   tmp2 = pI128->mem.rbase_g[DATA_I] & 0xbc;
66850806d53Smrg   if ((pI128->MemoryType != I128_MEMORY_DRAM) &&
66950806d53Smrg       (pI128->MemoryType != I128_MEMORY_SGRAM))
67050806d53Smrg   	tmp2 |= (pI128->RamdacType == IBM528_DAC) ? 3 : 1;
67150806d53Smrg   pI128->mem.rbase_g[DATA_I] = tmp2;					MB;
67250806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc2;				MB;
67350806d53Smrg   tmp2 = 0x03;
67450806d53Smrg   if (pI128->DAC8Bit)
67550806d53Smrg	tmp2 |= 0x04;
67650806d53Smrg   if (!((pI128->MemoryType == I128_MEMORY_DRAM) &&
67750806d53Smrg	 (pI128->bitsPerPixel > 16)))
67850806d53Smrg	tmp2 |= 0x40;
67950806d53Smrg   if ((pI128->MemoryType == I128_MEMORY_SGRAM) &&
68050806d53Smrg	 (pI128->bitsPerPixel > 16) &&
68150806d53Smrg         (pI128->RamdacType != SILVER_HAMMER_DAC) )
68250806d53Smrg	tmp2 &= 0x3F;
68350806d53Smrg   pI128->mem.rbase_g[DATA_I] = tmp2;					MB;
68450806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc3;				MB;
68550806d53Smrg   pI128->mem.rbase_g[DATA_I] = 0x00;					MB;
68650806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc4;				MB;
68750806d53Smrg   pI128->mem.rbase_g[DATA_I] = 0x00;					MB;
68850806d53Smrg
68950806d53Smrg   /* ?? There is no write to cursor control register */
69050806d53Smrg
69150806d53Smrg   /* Set the memory clock speed to 95 MHz */
69250806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_ref_div;		MB;
69350806d53Smrg   pI128->mem.rbase_g[DATA_I] = 0x08;				MB;
69450806d53Smrg   pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_vco_div;		MB;
69550806d53Smrg   pI128->mem.rbase_g[DATA_I] = 0x50;				MB;
69650806d53Smrg
69750806d53Smrg   /* should delay at least a millisec so we'll wait 50 */
69850806d53Smrg   usleep(50000);
69950806d53Smrg
70050806d53Smrg   switch (pI128->depth) {
70150806d53Smrg   	case 24: /* 32 bit */
70250806d53Smrg   		pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt;		MB;
70350806d53Smrg   		tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8;
70450806d53Smrg   		pI128->mem.rbase_g[DATA_I] = tmp2 | 0x06;		MB;
70550806d53Smrg   		pI128->mem.rbase_g[IDXL_I] = IBMRGB_32bpp;		MB;
70650806d53Smrg   		pI128->mem.rbase_g[DATA_I] = 0x03;			MB;
70750806d53Smrg   		break;
70850806d53Smrg	case 16:
70950806d53Smrg   		pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt;		MB;
71050806d53Smrg   		tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8;
71150806d53Smrg   		pI128->mem.rbase_g[DATA_I] = tmp2 | 0x04;		MB;
71250806d53Smrg   		pI128->mem.rbase_g[IDXL_I] = IBMRGB_16bpp;		MB;
71350806d53Smrg   		pI128->mem.rbase_g[DATA_I] = 0xC7;			MB;
71450806d53Smrg   		break;
71550806d53Smrg	case 15:
71650806d53Smrg   		pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt;		MB;
71750806d53Smrg   		tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8;
71850806d53Smrg   		pI128->mem.rbase_g[DATA_I] = tmp2 | 0x04;		MB;
71950806d53Smrg   		pI128->mem.rbase_g[IDXL_I] = IBMRGB_16bpp;		MB;
72050806d53Smrg   		pI128->mem.rbase_g[DATA_I] = 0xC5;			MB;
72150806d53Smrg   		break;
72250806d53Smrg	default: /* 8 bit */
72350806d53Smrg   		pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt;		MB;
72450806d53Smrg   		tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8;
72550806d53Smrg   		pI128->mem.rbase_g[DATA_I] = tmp2 | 0x03;		MB;
72650806d53Smrg   		pI128->mem.rbase_g[IDXL_I] = IBMRGB_8bpp;		MB;
72750806d53Smrg   		pI128->mem.rbase_g[DATA_I] = 0x00;			MB;
72850806d53Smrg   		break;
72950806d53Smrg   }
73050806d53Smrg
73150806d53Smrg   pI128->mem.rbase_g[IDXCTL_I] = tmpc;					MB;
73250806d53Smrg   pI128->mem.rbase_g[IDXH_I] = tmph;					MB;
73350806d53Smrg   pI128->mem.rbase_g[IDXL_I] = tmpl;					MB;
73450806d53Smrg
73550806d53Smrg   return(TRUE);
73650806d53Smrg}
737