xenocara/driver/xf86-video-i128/src/i128IBMDAC.c
2012-08-11 10:07:25 +00:00

661 lines
22 KiB
C

/*
* Copyright 1996-2000 by Robin Cutshaw <robin@XFree86.Org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Robin Cutshaw not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Robin Cutshaw makes no representations
* about the suitability of this software for any purpose. It is provided
* "as is" without express or implied warranty.
*
* ROBIN CUTSHAW DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL ROBIN CUTSHAW BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "xf86.h"
#include "xf86PciInfo.h"
#include "xf86Pci.h"
#include "cursorstr.h"
#include "servermd.h"
#include "i128.h"
#include "i128reg.h"
#include "IBMRGB.h"
#include <unistd.h>
static void I128IBMShowCursor(ScrnInfoPtr pScrn);
static void I128IBMHideCursor(ScrnInfoPtr pScrn);
static void I128IBMSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
static void I128IBMSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
static void I128IBMLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
static Bool I128IBMUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs);
Bool
I128IBMHWCursorInit(ScrnInfoPtr pScrn)
{
xf86CursorInfoPtr infoPtr;
ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
I128Ptr pI128 = I128PTR(pScrn);
if (!pI128->HWCursor)
return FALSE;
infoPtr = xf86CreateCursorInfoRec();
if (!infoPtr) return FALSE;
pI128->CursorInfoRec = infoPtr;
infoPtr->MaxWidth = 64;
infoPtr->MaxHeight = 64;
infoPtr->SetCursorColors = I128IBMSetCursorColors;
infoPtr->SetCursorPosition = I128IBMSetCursorPosition;
infoPtr->LoadCursorImage = I128IBMLoadCursorImage;
infoPtr->HideCursor = I128IBMHideCursor;
infoPtr->ShowCursor = I128IBMShowCursor;
infoPtr->UseHWCursor = I128IBMUseHWCursor;
infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1;
#if X_BYTE_ORDER == X_BIG_ENDIAN
infoPtr->Flags |= HARDWARE_CURSOR_NIBBLE_SWAPPED;
#endif
return(xf86InitCursor(pScreen, infoPtr));
}
static void
I128IBMShowCursor(ScrnInfoPtr pScrn)
{
CARD32 tmpl, tmph;
I128Ptr pI128 = I128PTR(pScrn);
/* Enable cursor - X11 mode */
tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF;
tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF;
pI128->mem.rbase_g[IDXCTL_I] = 0; MB;
pI128->mem.rbase_g[IDXH_I] = 0; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs; MB;
pI128->mem.rbase_g[DATA_I] = 0x27; MB;
pI128->mem.rbase_g[IDXH_I] = tmph; MB;
pI128->mem.rbase_g[IDXL_I] = tmpl; MB;
return;
}
static void
I128IBMHideCursor(ScrnInfoPtr pScrn)
{
CARD32 tmpl, tmph, tmp1;
I128Ptr pI128 = I128PTR(pScrn);
tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF;
tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF;
pI128->mem.rbase_g[IDXCTL_I] = 0; MB;
pI128->mem.rbase_g[IDXH_I] = 0; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs; MB;
tmp1 = pI128->mem.rbase_g[DATA_I] & 0xFC;
pI128->mem.rbase_g[DATA_I] = tmp1; MB;
pI128->mem.rbase_g[IDXH_I] = tmph; MB;
pI128->mem.rbase_g[IDXL_I] = tmpl; MB;
return;
}
static void
I128IBMSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
{
CARD32 tmpl, tmph;
I128Ptr pI128 = I128PTR(pScrn);
x += 64;
y += 64;
tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF;
tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF;
pI128->mem.rbase_g[IDXH_I] = 0; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_hot_x; MB;
pI128->mem.rbase_g[DATA_I] = 0x3F; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_hot_y; MB;
pI128->mem.rbase_g[DATA_I] = 0x3F; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_xl; MB;
pI128->mem.rbase_g[DATA_I] = x & 0xFF; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_xh; MB;
pI128->mem.rbase_g[DATA_I] = (x >> 8) & 0x0F; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_yl; MB;
pI128->mem.rbase_g[DATA_I] = y & 0xFF; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_yh; MB;
pI128->mem.rbase_g[DATA_I] = (y >> 8) & 0x0F; MB;
pI128->mem.rbase_g[IDXH_I] = tmph; MB;
pI128->mem.rbase_g[IDXL_I] = tmpl; MB;
return;
}
static void
I128IBMSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
{
CARD32 tmp;
I128Ptr pI128 = I128PTR(pScrn);
tmp = pI128->mem.rbase_g[IDXL_I] & 0xFF;
/* Background color */
pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_col1_r; MB;
pI128->mem.rbase_g[DATA_I] = (bg & 0x00FF0000) >> 16; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_col1_g; MB;
pI128->mem.rbase_g[DATA_I] = (bg & 0x0000FF00) >> 8; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_col1_b; MB;
pI128->mem.rbase_g[DATA_I] = (bg & 0x000000FF); MB;
/* Foreground color */
pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_col2_r; MB;
pI128->mem.rbase_g[DATA_I] = (fg & 0x00FF0000) >> 16; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_col2_g; MB;
pI128->mem.rbase_g[DATA_I] = (fg & 0x0000FF00) >> 8; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_col2_b; MB;
pI128->mem.rbase_g[DATA_I] = (fg & 0x000000FF); MB;
pI128->mem.rbase_g[IDXL_I] = tmp; MB;
return;
}
static void
I128IBMLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
{
I128Ptr pI128 = I128PTR(pScrn);
register int i;
CARD32 tmph, tmpl, tmpc;
tmpc = pI128->mem.rbase_g[IDXCTL_I] & 0xFF;
tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF;
tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF;
pI128->BlockCursor = TRUE;
pI128->mem.rbase_g[IDXCTL_I] = 0; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_hot_x; MB;
pI128->mem.rbase_g[DATA_I] = 0x00; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_hot_y; MB;
pI128->mem.rbase_g[DATA_I] = 0x00; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_xl; MB;
pI128->mem.rbase_g[DATA_I] = 0xFF; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_xh; MB;
pI128->mem.rbase_g[DATA_I] = 0x7F; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_yl; MB;
pI128->mem.rbase_g[DATA_I] = 0xFF; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_yh; MB;
pI128->mem.rbase_g[DATA_I] = 0x7F; MB;
pI128->mem.rbase_g[IDXH_I] = (IBMRGB_curs_array >> 8) & 0xFF; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_array & 0xFF; MB;
pI128->mem.rbase_g[IDXCTL_I] = 1; /* enable auto-inc */ MB;
/*
* Output the cursor data. The realize function has put the planes into
* their correct order, so we can just blast this out.
*/
for (i = 0; i < 1024; i++,src++) {
pI128->mem.rbase_g[DATA_I] = (CARD32 )*src; MB;
}
pI128->mem.rbase_g[IDXCTL_I] = tmpc; MB;
pI128->mem.rbase_g[IDXH_I] = tmph; MB;
pI128->mem.rbase_g[IDXL_I] = tmpl; MB;
pI128->BlockCursor = FALSE;
return;
}
static Bool
I128IBMUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs)
{
if( XF86SCRNINFO(pScrn)->currentMode->Flags & V_DBLSCAN )
return FALSE;
return TRUE;
}
Bool I128TIHWCursorInit(ScrnInfoPtr pScrn) { return FALSE; }
Bool I128ProgramTi3025(ScrnInfoPtr pScrn, DisplayModePtr mode) { return FALSE; }
Bool
I128ProgramIBMRGB(ScrnInfoPtr pScrn, DisplayModePtr mode)
{
I128Ptr pI128 = I128PTR(pScrn);
unsigned char tmp2, m, n, df, best_m, best_n, best_df, max_n;
CARD32 tmpl, tmph, tmpc;
long f, vrf, outf, best_diff, best_outf = 0, diff;
long requested_freq;
int freq = mode->SynthClock;
int flags = mode->Flags;
#define REF_FREQ 25175000
#define MAX_VREF 3380000
/* Actually, MIN_VREF can be as low as 1000000;
* this allows clock speeds down to 17 MHz */
#define MIN_VREF 1500000
#define MAX_VCO 220000000
#define MIN_VCO 65000000
if (freq < 25000) {
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"Specified dot clock (%.3f) too low for IBM RGB52x",
freq / 1000.0);
return(FALSE);
} else if (freq > MAX_VCO) {
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"Specified dot clock (%.3f) too high for IBM RGB52x",
freq / 1000.0);
return(FALSE);
}
requested_freq = freq * 1000;
best_m = best_n = best_df = 0;
best_diff = requested_freq; /* worst case */
for (df=0; df<4; df++) {
max_n = REF_FREQ / MIN_VREF;
if (df < 3)
max_n >>= 1;
for (n=2; n<max_n; n++)
for (m=65; m<=128; m++) {
vrf = REF_FREQ / n;
if (df < 3)
vrf >>= 1;
if ((vrf > MAX_VREF) || (vrf < MIN_VREF))
continue;
f = vrf * m;
outf = f;
if (df < 2)
outf >>= 2 - df;
if ((f > MAX_VCO) || (f < MIN_VCO))
continue;
/* outf is a valid freq, pick the closest now */
if ((diff = (requested_freq - outf)) < 0)
diff = -diff;;
if (diff < best_diff) {
best_diff = diff;
best_m = m;
best_n = n;
best_df = df;
best_outf = outf;
}
}
}
/* do we have an acceptably close frequency? (less than 1% diff) */
if (best_diff > (requested_freq/100)) {
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"Specified dot clock (%.3f) too far (best %.3f) IBM RGB52x",
requested_freq / 1000.0, best_outf / 1000.0);
return(FALSE);
}
pI128->mem.rbase_g[PEL_MASK] = 0xFF; MB;
tmpc = pI128->mem.rbase_g[IDXCTL_I] & 0xFF;
tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF;
tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF;
pI128->mem.rbase_g[IDXH_I] = 0; MB;
pI128->mem.rbase_g[IDXCTL_I] = 0; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc_clock; MB;
tmp2 = pI128->mem.rbase_g[DATA_I] & 0xFF;
pI128->mem.rbase_g[DATA_I] = tmp2 | 0x81; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_m0+4; MB;
pI128->mem.rbase_g[DATA_I] = (best_df<<6) | (best_m&0x3f); MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_n0+4; MB;
pI128->mem.rbase_g[DATA_I] = best_n; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_pll_ctrl1; MB;
tmp2 = pI128->mem.rbase_g[DATA_I] & 0xFF;
pI128->mem.rbase_g[DATA_I] = (tmp2&0xf8) | 3; /* 8 M/N pairs in PLL */ MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_pll_ctrl2; MB;
tmp2 = pI128->mem.rbase_g[DATA_I] & 0xFF;
pI128->mem.rbase_g[DATA_I] = (tmp2&0xf0) | 2; /* clock number 2 */ MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc_clock; MB;
tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf0;
pI128->mem.rbase_g[DATA_I] = tmp2 | ((flags & V_DBLCLK) ? 0x03 : 0x01); MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_sync; MB;
pI128->mem.rbase_g[DATA_I] = ((flags & V_PHSYNC) ? 0x10 : 0x00)
| ((flags & V_PVSYNC) ? 0x20 : 0x00); MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_hsync_pos; MB;
pI128->mem.rbase_g[DATA_I] = 0x01; /* Delay syncs by 1 pclock */ MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_pwr_mgmt; MB;
pI128->mem.rbase_g[DATA_I] = 0x00; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_dac_op; MB;
tmp2 = (pI128->RamdacType == IBM528_DAC) ? 0x02 : 0x00; /* fast slew */
if (pI128->DACSyncOnGreen) tmp2 |= 0x08;
pI128->mem.rbase_g[DATA_I] = tmp2; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_pal_ctrl; MB;
pI128->mem.rbase_g[DATA_I] = 0x00; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk; MB;
pI128->mem.rbase_g[DATA_I] = 0x01; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc1; MB;
tmp2 = pI128->mem.rbase_g[DATA_I] & 0xbc;
tmp2 |= 0x20;
if ((pI128->MemoryType != I128_MEMORY_DRAM) &&
(pI128->MemoryType != I128_MEMORY_SGRAM))
tmp2 |= (pI128->RamdacType == IBM528_DAC) ? 3 : 1;
pI128->mem.rbase_g[DATA_I] = tmp2; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc2; MB;
tmp2 = 0x03;
if (pI128->DAC8Bit)
tmp2 |= 0x04;
if (!((pI128->MemoryType == I128_MEMORY_DRAM) &&
(pI128->bitsPerPixel > 16)))
tmp2 |= 0x40;
if ((pI128->MemoryType == I128_MEMORY_SGRAM) &&
(pI128->bitsPerPixel > 16) &&
(pI128->RamdacType != SILVER_HAMMER_DAC) )
tmp2 &= 0x3F;
pI128->mem.rbase_g[DATA_I] = tmp2; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc3; MB;
pI128->mem.rbase_g[DATA_I] = 0x00; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc4; MB;
pI128->mem.rbase_g[DATA_I] = 0x00; MB;
/* ?? There is no write to cursor control register */
if (pI128->RamdacType == IBM526_DAC) {
if (pI128->MemoryType == I128_MEMORY_SGRAM) {
pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_ref_div; MB;
pI128->mem.rbase_g[DATA_I] = 0x09; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_vco_div; MB;
pI128->mem.rbase_g[DATA_I] = 0x83; MB;
} else {
/* program mclock to 52MHz */
pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_ref_div; MB;
pI128->mem.rbase_g[DATA_I] = 0x08; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_vco_div; MB;
pI128->mem.rbase_g[DATA_I] = 0x41; MB;
}
/* should delay at least a millisec so we'll wait 50 */
usleep(50000);
}
switch (pI128->depth) {
case 24: /* 32 bit */
pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt; MB;
tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8;
pI128->mem.rbase_g[DATA_I] = tmp2 | 0x06; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_32bpp; MB;
pI128->mem.rbase_g[DATA_I] = 0x03; MB;
break;
case 16:
pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt; MB;
tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8;
pI128->mem.rbase_g[DATA_I] = tmp2 | 0x04; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_16bpp; MB;
pI128->mem.rbase_g[DATA_I] = 0xC7; MB;
break;
case 15:
pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt; MB;
tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8;
pI128->mem.rbase_g[DATA_I] = tmp2 | 0x04; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_16bpp; MB;
pI128->mem.rbase_g[DATA_I] = 0xC5; MB;
break;
default: /* 8 bit */
pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt; MB;
tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8;
pI128->mem.rbase_g[DATA_I] = tmp2 | 0x03; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_8bpp; MB;
pI128->mem.rbase_g[DATA_I] = 0x00; MB;
break;
}
pI128->mem.rbase_g[IDXCTL_I] = tmpc; MB;
pI128->mem.rbase_g[IDXH_I] = tmph; MB;
pI128->mem.rbase_g[IDXL_I] = tmpl; MB;
return(TRUE);
}
Bool
I128ProgramSilverHammer(ScrnInfoPtr pScrn, DisplayModePtr mode)
{
/* The SilverHammer DAC is essentially the same as the IBMRGBxxx DACs,
* but with fewer options and a different reference frequency.
*/
I128Ptr pI128 = I128PTR(pScrn);
unsigned char tmp2, m, n, df, best_m, best_n, best_df, max_n;
CARD32 tmpl, tmph, tmpc;
long f, vrf, outf, best_diff, best_outf = 0, diff;
long requested_freq;
int freq = mode->SynthClock;
int flags = mode->Flags;
int skew = mode->HSkew;
#undef REF_FREQ
#define REF_FREQ 37500000
#undef MAX_VREF
#define MAX_VREF 9000000
#define MIN_VREF 1500000
#undef MAX_VCO
#define MAX_VCO 270000000
#define MIN_VCO 65000000
if (freq < 25000) {
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"Specified dot clock (%.3f) too low for SilverHammer",
freq / 1000.0);
return(FALSE);
} else if (freq > MAX_VCO) {
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"Specified dot clock (%.3f) too high for SilverHammer",
freq / 1000.0);
return(FALSE);
}
requested_freq = freq * 1000;
best_m = best_n = best_df = 0;
best_diff = requested_freq; /* worst case */
for (df=0; df<4; df++) {
max_n = REF_FREQ / MIN_VREF;
if (df < 3)
max_n >>= 1;
for (n=2; n<max_n; n++)
for (m=65; m<=128; m++) {
vrf = REF_FREQ / n;
if (df < 3)
vrf >>= 1;
if ((vrf > MAX_VREF) || (vrf < MIN_VREF))
continue;
f = vrf * m;
outf = f;
if (df < 2)
outf >>= 2 - df;
if ((f > MAX_VCO) || (f < MIN_VCO))
continue;
/* outf is a valid freq, pick the closest now */
if ((diff = (requested_freq - outf)) < 0)
diff = -diff;;
if (diff < best_diff) {
best_diff = diff;
best_m = m;
best_n = n;
best_df = df;
best_outf = outf;
}
}
}
/* do we have an acceptably close frequency? (less than 1% diff) */
if (best_diff > (requested_freq/100)) {
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"Specified dot clock (%.3f) too far (best %.3f) SilverHammer",
requested_freq / 1000.0, best_outf / 1000.0);
return(FALSE);
}
pI128->mem.rbase_g[PEL_MASK] = 0xFF; MB;
tmpc = pI128->mem.rbase_g[IDXCTL_I] & 0xFF;
tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF;
tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF;
pI128->mem.rbase_g[IDXH_I] = 0; MB;
pI128->mem.rbase_g[IDXCTL_I] = 0; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc_clock; MB;
tmp2 = pI128->mem.rbase_g[DATA_I] & 0xFF;
pI128->mem.rbase_g[DATA_I] = tmp2 | 0x81; MB;
if (!pI128->Primary) {
pI128->mem.rbase_g[IDXL_I] = IBMRGB_m0; MB;
pI128->mem.rbase_g[DATA_I] = 0x15; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_m0+1; MB;
pI128->mem.rbase_g[DATA_I] = 0x10; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_m0+2; MB;
pI128->mem.rbase_g[DATA_I] = 0x2c; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_m0+3; MB;
pI128->mem.rbase_g[DATA_I] = 0x12; MB;
}
pI128->mem.rbase_g[IDXL_I] = IBMRGB_m0+4; MB;
pI128->mem.rbase_g[DATA_I] = (best_df<<6) | (best_m&0x3f); MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_n0+4; MB;
pI128->mem.rbase_g[DATA_I] = best_n; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_pll_ctrl1; MB;
tmp2 = pI128->mem.rbase_g[DATA_I] & 0xFF;
pI128->mem.rbase_g[DATA_I] = (tmp2&0xf8) | 3; /* 8 M/N pairs in PLL */ MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_pll_ctrl2; MB;
tmp2 = pI128->mem.rbase_g[DATA_I] & 0xFF;
pI128->mem.rbase_g[DATA_I] = (tmp2&0xf0) | 2; /* clock number 2 */ MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc_clock; MB;
tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf0;
pI128->mem.rbase_g[DATA_I] = tmp2 | ((flags & V_DBLCLK) ? 0x03 : 0x01); MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_sync; MB;
pI128->mem.rbase_g[DATA_I] = ((flags & V_PHSYNC) ? 0x10 : 0x00)
| ((flags & V_PVSYNC) ? 0x20 : 0x00); MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_hsync_pos; MB;
pI128->mem.rbase_g[DATA_I] = ((flags & V_HSKEW) ? skew : 0x01); MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_pwr_mgmt; MB;
/* Use 0x01 below with digital flat panel to conserve energy and reduce noise */
pI128->mem.rbase_g[DATA_I] = (pI128->FlatPanel ? 0x01 : 0x00); MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_dac_op; MB;
pI128->mem.rbase_g[DATA_I] = (pI128->DACSyncOnGreen ? 0x08 : 0x00); MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_pal_ctrl; MB;
pI128->mem.rbase_g[DATA_I] = 0x00; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk; MB;
pI128->mem.rbase_g[DATA_I] = 0x01; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc1; MB;
tmp2 = pI128->mem.rbase_g[DATA_I] & 0xbc;
if ((pI128->MemoryType != I128_MEMORY_DRAM) &&
(pI128->MemoryType != I128_MEMORY_SGRAM))
tmp2 |= (pI128->RamdacType == IBM528_DAC) ? 3 : 1;
pI128->mem.rbase_g[DATA_I] = tmp2; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc2; MB;
tmp2 = 0x03;
if (pI128->DAC8Bit)
tmp2 |= 0x04;
if (!((pI128->MemoryType == I128_MEMORY_DRAM) &&
(pI128->bitsPerPixel > 16)))
tmp2 |= 0x40;
if ((pI128->MemoryType == I128_MEMORY_SGRAM) &&
(pI128->bitsPerPixel > 16) &&
(pI128->RamdacType != SILVER_HAMMER_DAC) )
tmp2 &= 0x3F;
pI128->mem.rbase_g[DATA_I] = tmp2; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc3; MB;
pI128->mem.rbase_g[DATA_I] = 0x00; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc4; MB;
pI128->mem.rbase_g[DATA_I] = 0x00; MB;
/* ?? There is no write to cursor control register */
/* Set the memory clock speed to 95 MHz */
pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_ref_div; MB;
pI128->mem.rbase_g[DATA_I] = 0x08; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_vco_div; MB;
pI128->mem.rbase_g[DATA_I] = 0x50; MB;
/* should delay at least a millisec so we'll wait 50 */
usleep(50000);
switch (pI128->depth) {
case 24: /* 32 bit */
pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt; MB;
tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8;
pI128->mem.rbase_g[DATA_I] = tmp2 | 0x06; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_32bpp; MB;
pI128->mem.rbase_g[DATA_I] = 0x03; MB;
break;
case 16:
pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt; MB;
tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8;
pI128->mem.rbase_g[DATA_I] = tmp2 | 0x04; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_16bpp; MB;
pI128->mem.rbase_g[DATA_I] = 0xC7; MB;
break;
case 15:
pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt; MB;
tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8;
pI128->mem.rbase_g[DATA_I] = tmp2 | 0x04; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_16bpp; MB;
pI128->mem.rbase_g[DATA_I] = 0xC5; MB;
break;
default: /* 8 bit */
pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt; MB;
tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8;
pI128->mem.rbase_g[DATA_I] = tmp2 | 0x03; MB;
pI128->mem.rbase_g[IDXL_I] = IBMRGB_8bpp; MB;
pI128->mem.rbase_g[DATA_I] = 0x00; MB;
break;
}
pI128->mem.rbase_g[IDXCTL_I] = tmpc; MB;
pI128->mem.rbase_g[IDXH_I] = tmph; MB;
pI128->mem.rbase_g[IDXL_I] = tmpl; MB;
return(TRUE);
}