- PicassoIV support

- Fixes for Interlace and DoubleScan
- Memorysizedetction for 1MB Bords
- Clockdoubling for PicassoIV and PiccoloSD64
  NOTE: Don't use the X11R6.1 Xserver with -useHWC on the SD64
       with a gfxmode >80Mhz or you get a broken mousepointer.
- HiColor and TrueColor Support
  (doesn't work yet, since it needs some fixes for the XServer)
This commit is contained in:
veego 1997-03-05 22:46:32 +00:00
parent 8f5155b610
commit b835a00fa8
1 changed files with 409 additions and 215 deletions

View File

@ -1,6 +1,7 @@
/* $NetBSD: grf_cl.c,v 1.18 1996/12/23 09:10:04 veego Exp $ */
/* $NetBSD: grf_cl.c,v 1.19 1997/03/05 22:46:32 veego Exp $ */
/*
* Copyright (c) 1997 Klaus Burkert
* Copyright (c) 1995 Ezra Story
* Copyright (c) 1995 Kari Mettinen
* Copyright (c) 1994 Markus Wild
@ -50,6 +51,10 @@
* Extensively hacked and rewritten by Ezra Story (Ezy) 01/95
* Picasso/040 patches (wee!) by crest 01/96
*
* PicassoIV support bz Klaus "crest" Burkert.
* Fixed interlace and doublescan, added clockdoubling and
* HiColor&TrueColor suuport by crest 01/97
*
* Thanks to Village Tronic Marketing Gmbh for providing me with
* a Picasso-II board.
* Thanks for Integrated Electronics Oy Ab for providing me with
@ -77,37 +82,37 @@
#include <amiga/dev/grf_clreg.h>
#include <amiga/dev/zbusvar.h>
int cl_mondefok __P((struct grfvideo_mode *));
void cl_boardinit __P((struct grf_softc *));
static void cl_CompFQ __P((u_int, u_char *, u_char *));
int cl_getvmode __P((struct grf_softc *, struct grfvideo_mode *));
int cl_setvmode __P((struct grf_softc *, unsigned int));
int cl_toggle __P((struct grf_softc *, unsigned short));
int cl_getcmap __P((struct grf_softc *, struct grf_colormap *));
int cl_putcmap __P((struct grf_softc *, struct grf_colormap *));
int cl_mondefok __P((struct grfvideo_mode *));
void cl_boardinit __P((struct grf_softc *));
static void cl_CompFQ __P((u_int, u_char *, u_char *, u_char *));
int cl_getvmode __P((struct grf_softc *, struct grfvideo_mode *));
int cl_setvmode __P((struct grf_softc *, unsigned int));
int cl_toggle __P((struct grf_softc *, unsigned short));
int cl_getcmap __P((struct grf_softc *, struct grf_colormap *));
int cl_putcmap __P((struct grf_softc *, struct grf_colormap *));
#ifndef CL5426CONSOLE
void cl_off __P((struct grf_softc *));
void cl_off __P((struct grf_softc *));
#endif
void cl_inittextmode __P((struct grf_softc *));
int cl_ioctl __P((register struct grf_softc *, u_long, void *));
int cl_getmousepos __P((struct grf_softc *, struct grf_position *));
int cl_setmousepos __P((struct grf_softc *, struct grf_position *));
static int cl_setspriteinfo __P((struct grf_softc *, struct grf_spriteinfo *));
int cl_getspriteinfo __P((struct grf_softc *, struct grf_spriteinfo *));
static int cl_getspritemax __P((struct grf_softc *, struct grf_position *));
int cl_blank __P((struct grf_softc *, int *));
int cl_setmonitor __P((struct grf_softc *, struct grfvideo_mode *));
void cl_writesprpos __P((volatile char *, short, short));
void writeshifted __P((volatile char *, char, char));
void cl_inittextmode __P((struct grf_softc *));
int cl_ioctl __P((register struct grf_softc *, u_long, void *));
int cl_getmousepos __P((struct grf_softc *, struct grf_position *));
int cl_setmousepos __P((struct grf_softc *, struct grf_position *));
static int cl_setspriteinfo __P((struct grf_softc *, struct grf_spriteinfo *));
int cl_getspriteinfo __P((struct grf_softc *, struct grf_spriteinfo *));
static int cl_getspritemax __P((struct grf_softc *, struct grf_position *));
int cl_blank __P((struct grf_softc *, int *));
int cl_setmonitor __P((struct grf_softc *, struct grfvideo_mode *));
void cl_writesprpos __P((volatile char *, short, short));
void writeshifted __P((volatile char *, char, char));
static void RegWakeup __P((volatile caddr_t));
static void RegOnpass __P((volatile caddr_t));
static void RegOffpass __P((volatile caddr_t));
static void RegWakeup __P((volatile caddr_t));
static void RegOnpass __P((volatile caddr_t));
static void RegOffpass __P((volatile caddr_t));
void grfclattach __P((struct device *, struct device *, void *));
int grfclprint __P((void *, const char *));
int grfclmatch __P((struct device *, struct cfdata *, void *));
void cl_memset __P((unsigned char *, unsigned char, int));
void grfclattach __P((struct device *, struct device *, void *));
int grfclprint __P((void *, const char *));
int grfclmatch __P((struct device *, struct cfdata *, void *));
void cl_memset __P((unsigned char *, unsigned char, int));
/* Graphics display definitions.
* These are filled by 'grfconfig' using GRFIOCSETMON.
@ -147,10 +152,11 @@ unsigned char clconscolors[3][3] = { /* background, foreground, hilite */
};
int cltype = 0; /* Picasso, Spectrum or Piccolo */
int cl_sd64 = 0;
int cl_64bit = 0; /* PiccoloSD64 or PicassoIV */
unsigned char pass_toggle; /* passthru status tracker */
/* because all 5426-boards have 2 configdev entries, one for
/*
* because all 542x-boards have 2 configdev entries, one for
* framebuffer mem and the other for regs, we have to hold onto
* the pointers globally until we match on both. This and 'cltype'
* are the primary obsticles to multiple board support, but if you
@ -159,8 +165,11 @@ unsigned char pass_toggle; /* passthru status tracker */
static void *cl_fbaddr = 0; /* framebuffer */
static void *cl_regaddr = 0; /* registers */
static int cl_fbsize; /* framebuffer size */
static int cl_fbautosize; /* framebuffer autoconfig size */
/* current sprite info, if you add support for multiple boards
/*
* current sprite info, if you add support for multiple boards
* make this an array or something
*/
struct grf_spriteinfo cl_cursprite;
@ -188,9 +197,10 @@ grfclmatch(pdp, cfp, auxp)
void *auxp;
{
struct zbus_args *zap;
static int regprod, fbprod;
static int regprod, fbprod, fbprod2;
int error;
fbprod2 = 0;
zap = auxp;
#ifndef CL5426CONSOLE
@ -204,11 +214,38 @@ grfclmatch(pdp, cfp, auxp)
if (cltype == 0) {
switch (zap->manid) {
case PICASSO:
if (zap->prodid != 12 && zap->prodid != 11)
return (0);
regprod = 12;
fbprod = 11;
break;
switch (zap->prodid) {
case 11:
case 12:
regprod = 12;
fbprod = 11;
error = 0;
break;
case 22:
fbprod2 = 22;
error = 0;
break;
case 21:
case 23:
regprod = 23;
fbprod = 21;
cl_64bit = 1;
error = 0;
break;
case 24:
regprod = 24;
fbprod = 24;
cl_64bit = 1;
error = 0;
break;
default:
error = 1;
break;
}
if (error == 1)
return (0);
else
break;
case SPECTRUM:
if (zap->prodid != 2 && zap->prodid != 1)
return (0);
@ -227,7 +264,7 @@ grfclmatch(pdp, cfp, auxp)
case 11:
regprod = 11;
fbprod = 10;
cl_sd64 = 1;
cl_64bit = 1;
error = 0;
break;
default:
@ -249,21 +286,44 @@ grfclmatch(pdp, cfp, auxp)
}
/* Configure either registers or framebuffer in any order */
if (zap->prodid == regprod)
cl_regaddr = zap->va;
else
if (zap->prodid == fbprod) {
if ((cltype == PICASSO) && (cl_64bit == 1)) {
switch (zap->prodid) {
case 21:
cl_fbaddr = zap->va;
cl_fbsize = zap->size;
} else
cl_fbautosize = zap->size;
break;
case 22:
cl_fbautosize += zap->size;
break;
case 23:
cl_regaddr = (void *)((unsigned long)(zap->va) + 0x10000);
break;
case 24:
cl_regaddr = (void *)((unsigned long)(zap->va) + 0x600000);
cl_fbaddr = (void *)((unsigned long)(zap->va) + 0x01000000);
cl_fbautosize = 0x400000;
break;
default:
return (0);
}
}
else {
if (zap->prodid == regprod)
cl_regaddr = zap->va;
else
if (zap->prodid == fbprod) {
cl_fbaddr = zap->va;
cl_fbautosize = zap->size;
} else
return (0);
}
#ifdef CL5426CONSOLE
if (amiga_realconfig == 0) {
cfdata = cfp;
}
if (amiga_realconfig == 0) {
cfdata = cfp;
}
#endif
return (1);
}
@ -323,15 +383,42 @@ grfclattach(pdp, dp, auxp)
printf("grfcl: %dMB ", cl_fbsize / 0x100000);
switch (cltype) {
case PICASSO:
printf("Picasso II");
cl_maxpixelclock = 86000000;
if (cl_64bit == 1) {
printf("Picasso IV");
/* 135MHz will be supported if we
* have a palette doubling mode.
*/
cl_maxpixelclock = 86000000;
}
else {
printf("Picasso II");
/* check for PicassoII+ (crest) */
if(zap->serno == 0x00100000)
printf("+");
/* determine used Gfx/chipset (crest) */
vgaw(gp->g_regkva, CRT_ADDRESS, 0x27); /* Chip ID */
switch(vgar(gp->g_regkva, CRT_ADDRESS_R)>>2) {
case 0x24:
printf(" (with CL-GD5426)");
break;
case 0x26:
printf(" (with CL-GD5428)");
break;
case 0x27:
printf(" (with CL-GD5429)");
break;
}
cl_maxpixelclock = 86000000;
}
break;
case SPECTRUM:
printf("Spectrum");
cl_maxpixelclock = 90000000;
break;
case PICCOLO:
if (cl_sd64 == 1) {
if (cl_64bit == 1) {
printf("Piccolo SD64");
/* 110MHz will be supported if we
* have a palette doubling mode.
@ -370,98 +457,104 @@ cl_boardinit(gp)
unsigned char *ba = gp->g_regkva;
int x;
/* wakeup board and flip passthru OFF */
RegWakeup(ba);
RegOnpass(ba);
vgaw(ba, 0x46e8, 0x16);
vgaw(ba, 0x102, 1);
vgaw(ba, 0x46e8, 0x0e);
if (cl_sd64 != 1)
vgaw(ba, 0x3c3, 1);
/* setup initial unchanging parameters */
WSeq(ba, SEQ_ID_CLOCKING_MODE, 0x21); /* 8 dot - display off */
vgaw(ba, GREG_MISC_OUTPUT_W, 0xed); /* mem disable */
WGfx(ba, GCT_ID_OFFSET_1, 0xec); /* magic cookie */
WSeq(ba, SEQ_ID_UNLOCK_EXT, 0x12); /* yum! cookies! */
if (cl_sd64 == 1) {
WSeq(ba, SEQ_ID_CONF_RBACK, 0x00);
WSeq(ba, SEQ_ID_DRAM_CNTL, (cl_fbsize / 0x100000 == 2) ? 0x38 : 0xb8);
if ((cltype == PICASSO) && (cl_64bit == 1)) { /* PicassoIV */
WCrt(ba, 0x51, 0x00); /* disable capture (FlickerFixer) */
delay(200000); /* wait some time (two frames as of now) */
WGfx(ba, 0x2f, 0x00); /* get Blitter into 542x */
WGfx(ba, GCT_ID_RESERVED, 0x00); /* compatibility mode */
WGfx(ba, GCT_ID_BLT_STAT_START, 0x00); /* or at least, try so... */
cl_fbsize = cl_fbautosize;
} else {
WSeq(ba, SEQ_ID_DRAM_CNTL, 0xb0);
}
WSeq(ba, SEQ_ID_RESET, 0x03);
WSeq(ba, SEQ_ID_MAP_MASK, 0xff);
WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x00);
WSeq(ba, SEQ_ID_MEMORY_MODE, 0x0e); /* a or 6? */
WSeq(ba, SEQ_ID_EXT_SEQ_MODE, (cltype == PICASSO) ? 0x20 : 0x80);
WSeq(ba, SEQ_ID_EEPROM_CNTL, 0x00);
if (cl_sd64 == 1)
WSeq(ba, SEQ_ID_PERF_TUNE, 0x5a);
else
WSeq(ba, SEQ_ID_PERF_TUNE, 0x0a); /* mouse 0a fa */
WSeq(ba, SEQ_ID_SIG_CNTL, 0x02);
WSeq(ba, SEQ_ID_CURSOR_ATTR, 0x04);
if (cl_sd64 == 1)
WSeq(ba, SEQ_ID_MCLK_SELECT, 0x1c);
else
/* wakeup board and flip passthru OFF */
RegWakeup(ba);
RegOnpass(ba);
vgaw(ba, 0x46e8, 0x16);
vgaw(ba, 0x102, 1);
vgaw(ba, 0x46e8, 0x0e);
if (cl_64bit != 1)
vgaw(ba, 0x3c3, 1);
cl_fbsize = cl_fbautosize;
/* setup initial unchanging parameters */
WSeq(ba, SEQ_ID_CLOCKING_MODE, 0x21); /* 8 dot - display off */
vgaw(ba, GREG_MISC_OUTPUT_W, 0xed); /* mem disable */
WGfx(ba, GCT_ID_OFFSET_1, 0xec); /* magic cookie */
WSeq(ba, SEQ_ID_UNLOCK_EXT, 0x12); /* yum! cookies! */
if (cl_64bit == 1) {
WSeq(ba, SEQ_ID_CONF_RBACK, 0x00);
WSeq(ba, SEQ_ID_DRAM_CNTL, (cl_fbsize / 0x100000 == 2) ? 0x38 : 0xb8);
} else {
WSeq(ba, SEQ_ID_DRAM_CNTL, 0xb0);
}
WSeq(ba, SEQ_ID_RESET, 0x03);
WSeq(ba, SEQ_ID_MAP_MASK, 0xff);
WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x00);
WSeq(ba, SEQ_ID_MEMORY_MODE, 0x0e); /* a or 6? */
WSeq(ba, SEQ_ID_EXT_SEQ_MODE, (cltype == PICASSO) ? 0x21 : 0x81);
WSeq(ba, SEQ_ID_EEPROM_CNTL, 0x00);
if (cl_64bit == 1)
WSeq(ba, SEQ_ID_PERF_TUNE, 0x5a);
else
WSeq(ba, SEQ_ID_PERF_TUNE, 0x0a); /* mouse 0a fa */
WSeq(ba, SEQ_ID_SIG_CNTL, 0x02);
WSeq(ba, SEQ_ID_CURSOR_ATTR, 0x04);
if (cl_64bit == 1)
WSeq(ba, SEQ_ID_MCLK_SELECT, 0x1c);
else
WSeq(ba, SEQ_ID_MCLK_SELECT, 0x22);
WCrt(ba, CRT_ID_PRESET_ROW_SCAN, 0x00);
WCrt(ba, CRT_ID_CURSOR_START, 0x00);
WCrt(ba, CRT_ID_CURSOR_END, 0x08);
WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00);
WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00);
WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00);
WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00);
WCrt(ba, CRT_ID_PRESET_ROW_SCAN, 0x00);
WCrt(ba, CRT_ID_CURSOR_START, 0x00);
WCrt(ba, CRT_ID_CURSOR_END, 0x08);
WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00);
WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00);
WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00);
WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00);
WCrt(ba, CRT_ID_UNDERLINE_LOC, 0x07);
WCrt(ba, CRT_ID_MODE_CONTROL, 0xa3); /* c3 */
WCrt(ba, CRT_ID_LINE_COMPARE, 0xff); /* ff */
WCrt(ba, CRT_ID_EXT_DISP_CNTL, 0x22);
if (cl_sd64 == 1) {
WCrt(ba, CRT_ID_SYNC_ADJ_GENLOCK, 0x00);
WCrt(ba, CRT_ID_OVERLAY_EXT_CTRL_REG, 0x40);
WCrt(ba, CRT_ID_UNDERLINE_LOC, 0x07);
WCrt(ba, CRT_ID_MODE_CONTROL, 0xe3);
WCrt(ba, CRT_ID_LINE_COMPARE, 0xff); /* ff */
WCrt(ba, CRT_ID_EXT_DISP_CNTL, 0x22);
if (cl_64bit == 1) {
WCrt(ba, CRT_ID_SYNC_ADJ_GENLOCK, 0x00);
WCrt(ba, CRT_ID_OVERLAY_EXT_CTRL_REG, 0x40);
}
WSeq(ba, SEQ_ID_CURSOR_STORE, 0x3c); /* mouse 0x00 */
WGfx(ba, GCT_ID_SET_RESET, 0x00);
WGfx(ba, GCT_ID_ENABLE_SET_RESET, 0x00);
WGfx(ba, GCT_ID_DATA_ROTATE, 0x00);
WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00);
WGfx(ba, GCT_ID_GRAPHICS_MODE, 0x00);
WGfx(ba, GCT_ID_MISC, 0x01);
WGfx(ba, GCT_ID_COLOR_XCARE, 0x0f);
WGfx(ba, GCT_ID_BITMASK, 0xff);
WGfx(ba, GCT_ID_MODE_EXT, 0x28);
for (x = 0; x < 0x10; x++)
WAttr(ba, x, x);
WAttr(ba, ACT_ID_ATTR_MODE_CNTL, 0x01);
WAttr(ba, ACT_ID_OVERSCAN_COLOR, 0x00);
WAttr(ba, ACT_ID_COLOR_PLANE_ENA, 0x0f);
WAttr(ba, ACT_ID_HOR_PEL_PANNING, 0x00);
WAttr(ba, ACT_ID_COLOR_SELECT, 0x00);
WAttr(ba, 0x34, 0x00);
vgaw(ba, VDAC_MASK, 0xff);
vgaw(ba, GREG_MISC_OUTPUT_W, 0xef);
WGfx(ba, GCT_ID_BLT_STAT_START, 0x04);
WGfx(ba, GCT_ID_BLT_STAT_START, 0x00);
}
WSeq(ba, SEQ_ID_CURSOR_STORE, 0x3c); /* mouse 0x00 */
WGfx(ba, GCT_ID_SET_RESET, 0x00);
WGfx(ba, GCT_ID_ENABLE_SET_RESET, 0x00);
WGfx(ba, GCT_ID_DATA_ROTATE, 0x00);
WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00);
WGfx(ba, GCT_ID_GRAPHICS_MODE, 0x00);
WGfx(ba, GCT_ID_MISC, 0x01);
WGfx(ba, GCT_ID_COLOR_XCARE, 0x0f);
WGfx(ba, GCT_ID_BITMASK, 0xff);
WGfx(ba, GCT_ID_MODE_EXT, 0x28);
for (x = 0; x < 0x10; x++)
WAttr(ba, x, x);
WAttr(ba, ACT_ID_ATTR_MODE_CNTL, 0x01);
WAttr(ba, ACT_ID_OVERSCAN_COLOR, 0x00);
WAttr(ba, ACT_ID_COLOR_PLANE_ENA, 0x0f);
WAttr(ba, ACT_ID_HOR_PEL_PANNING, 0x00);
WAttr(ba, ACT_ID_COLOR_SELECT, 0x00);
delay(200000);
WAttr(ba, 0x34, 0x00);
delay(200000);
vgaw(ba, VDAC_MASK, 0xff);
delay(200000);
vgaw(ba, GREG_MISC_OUTPUT_W, 0xef);
WGfx(ba, GCT_ID_BLT_STAT_START, 0x04);
WGfx(ba, GCT_ID_BLT_STAT_START, 0x00);
/* colors initially set to greyscale */
vgaw(ba, VDAC_ADDRESS_W, 0);
for (x = 255; x >= 0; x--) {
vgaw(ba, VDAC_DATA, x);
@ -474,6 +567,26 @@ cl_boardinit(gp)
cl_cursprite.cmap.red = cl_sprred;
cl_cursprite.cmap.green = cl_sprgreen;
cl_cursprite.cmap.blue = cl_sprblue;
if (cl_64bit == 0) {
/* check for 1MB or 2MB board (crest) */
volatile unsigned long *cl_fbtestaddr;
cl_fbtestaddr = (volatile unsigned long *)gp->g_fbkva;
WGfx(ba, GCT_ID_OFFSET_0, 0x40);
*cl_fbtestaddr = 0x12345678;
if (*cl_fbtestaddr != 0x12345678) {
WSeq(ba, SEQ_ID_DRAM_CNTL, 0x30);
cl_fbsize = 0x100000;
}
else
{
cl_fbsize = 0x200000;
}
}
WGfx(ba, GCT_ID_OFFSET_0, 0x00);
}
@ -537,11 +650,14 @@ cl_off(gp)
{
char *ba = gp->g_regkva;
/* we'll put the pass-through on for cc ite and set Full Bandwidth bit
/*
* we'll put the pass-through on for cc ite and set Full Bandwidth bit
* on just in case it didn't work...but then it doesn't matter does
* it? =) */
* it? =)
*/
RegOnpass(ba);
WSeq(ba, SEQ_ID_CLOCKING_MODE, 0x21);
vgaw(ba, SEQ_ADDRESS, SEQ_ID_CLOCKING_MODE);
vgaw(ba, SEQ_ADDRESS_W, vgar(ba, SEQ_ADDRESS_W) | 0x20);
}
#endif
@ -676,13 +792,14 @@ cl_writesprpos(ba, x, y)
cwp = ba + 0x3c4;
wp = (unsigned short *)cwp;
/* don't ask me why, but apparently you can't do a 16-bit write with
* x-position like with y-position below (dagge) */
/*
* don't ask me why, but apparently you can't do a 16-bit write with
* x-position like with y-position below (dagge)
*/
cwp[0] = 0x10 | ((x << 5) & 0xff);
cwp[1] = (x >> 3) & 0xff;
*wp = 0x1100 | ((y & 7) << 13) | ((y >> 3) & 0xff);
}
void
@ -744,7 +861,8 @@ cl_setmousepos(gp, data)
prx = cl_cursprite.pos.x - cl_cursprite.hot.x;
pry = cl_cursprite.pos.y - cl_cursprite.hot.y;
/* if we are/were on an edge, create (un)shifted bitmap --
/*
* if we are/were on an edge, create (un)shifted bitmap --
* ripped out optimization (not extremely worthwhile,
* and kind of buggy anyhow).
*/
@ -984,10 +1102,20 @@ cl_getcmap(gfp, cmap)
vgaw(ba, VDAC_ADDRESS_R, cmap->index);
x = cmap->count - 1;
/* Some sort 'o Magic. Spectrum has some changes on the board to speed
/*
* Some sort 'o Magic. Spectrum has some changes on the board to speed
* up 15 and 16Bit modes. They can access these modes with easy-to-programm
* rgbrgbrgb instead of rrrgggbbb. Side effect: when in 8Bit mode, rgb
* is swapped to bgr. I wonder if we need to check for 8Bit though, ill
*/
/*
* The source for the above comment is somewhat unknow to me.
* The Spectrum, Piccolo and PiccoloSD64 have the analog Red and Blue
* lines swapped. In 24BPP this provides RGB instead of BGR as it would
* be native to the chipset. This requires special programming for the
* CLUT in 8BPP to compensate and avoid false colors.
* I didn't find any special stuff for 15 and 16BPP though, crest.
*/
switch (cltype) {
@ -1085,19 +1213,17 @@ cl_toggle(gp, wopp)
if (pass_toggle) {
RegOffpass(ba);
} else {
/* This was in the original.. is it needed? */
if (cltype == PICASSO || cltype == PICCOLO)
RegWakeup(ba);
RegOnpass(ba);
}
return (0);
}
static void
cl_CompFQ(fq, num, denom)
cl_CompFQ(fq, num, denom, clkdoub)
u_int fq;
u_char *num;
u_char *denom;
u_char *clkdoub;
{
#define OSC 14318180
/* OK, here's what we're doing here:
@ -1133,20 +1259,38 @@ denom = 0x00 - 0x1f (1) 0x20 - 0x3e (even)
mind = 0;
p = 0;
for (d = 1; d < 0x20; d++) {
for (n = 1; n < 0x80; n++) {
err = abs(count(n, d, p) - fq);
if (err < minerr) {
minerr = err;
minn = n;
mind = d;
minp = p;
if ((cl_64bit == 1) && (fq >= 86000000))
{
for (d = 1; d < 0x20; d++) {
for (n = 1; n < 0x80; n++) {
err = abs(count(n, d, 0) - fq);
if (err < minerr) {
minerr = err;
minn = n;
mind = d;
minp = 1;
}
}
}
if (d == 0x1f && p == 0) {
p = 1;
d = 0x0f;
*clkdoub = 1;
}
else {
for (d = 1; d < 0x20; d++) {
for (n = 1; n < 0x80; n++) {
err = abs(count(n, d, p) - fq);
if (err < minerr) {
minerr = err;
minn = n;
mind = d;
minp = p;
}
}
if (d == 0x1f && p == 0) {
p = 1;
d = 0x0f;
}
}
*clkdoub = 0;
}
*num = minn;
@ -1172,14 +1316,33 @@ cl_mondefok(gv)
return(0);
case 1:
case 8:
maxpix = cl_maxpixelclock;
maxpix = cl_maxpixelclock;
if (cl_64bit == 1)
{
if (cltype == PICASSO) /* Picasso IV */
maxpix = 135000000;
else /* Piccolo SD64 */
maxpix = 110000000;
}
break;
case 15:
case 16:
maxpix = cl_maxpixelclock - (cl_maxpixelclock / 3);
if (cl_64bit == 1)
maxpix = 85000000;
else
maxpix = cl_maxpixelclock - (cl_maxpixelclock / 3);
break;
case 24:
maxpix = cl_maxpixelclock / 3;
if ((cltype == PICASSO) && (cl_64bit == 1))
maxpix = 85000000;
else
maxpix = cl_maxpixelclock / 3;
break;
case 32:
if ((cltype == PICCOLO) && (cl_64bit == 1))
maxpix = 50000000;
else
maxpix = 0;
break;
default:
return (0);
@ -1197,13 +1360,13 @@ cl_load_mon(gp, md)
struct grfvideo_mode *gv;
struct grfinfo *gi;
volatile caddr_t ba, fb;
unsigned char num0, denom0;
unsigned char num0, denom0, clkdoub;
unsigned short HT, HDE, HBS, HBE, HSS, HSE, VDE, VBS, VBE, VSS,
VSE, VT;
char LACE, DBLSCAN, TEXT;
unsigned short clkdiv;
int uplim, lowlim;
int sr15;
int clkmul, offsmul, clkmode;
/* identity */
gv = &md->gv;
@ -1219,7 +1382,7 @@ cl_load_mon(gp, md)
/* provide all needed information in grf device-independant locations */
gp->g_data = (caddr_t) gv;
gi = &gp->g_display;
gi->gd_regaddr = (caddr_t) ztwopa(ba);
gi->gd_regaddr = (caddr_t) kvtop(ba);
gi->gd_regsize = 64 * 1024;
gi->gd_fbaddr = (caddr_t) kvtop(fb);
gi->gd_fbsize = cl_fbsize;
@ -1266,19 +1429,66 @@ cl_load_mon(gp, md)
DBLSCAN = (((VT / 2) > lowlim) && ((VT / 2) < uplim)) ? 1 : 0;
/* adjustments */
switch (gv->depth) {
case 8:
clkmul = 1;
offsmul = 1;
clkmode = 0x0;
break;
case 15:
case 16:
clkmul = 1;
offsmul = 2;
clkmode = 0x6;
break;
case 24:
if ((cltype == PICASSO) && (cl_64bit == 1)) /* Picasso IV */
clkmul = 1;
else
clkmul = 3;
offsmul = 3;
clkmode = 0x4;
break;
case 32:
clkmul = 1;
offsmul = 2;
clkmode = 0x8;
break;
default:
clkmul = 1;
offsmul = 1;
clkmode = 0x0;
break;
}
if (LACE)
VDE /= 2;
if (DBLSCAN)
VDE *= 2;
if ((VT > 1023) && (!LACE)) {
VDE /= 2;
VBS /= 2;
VSS /= 2;
VSE /= 2;
VBE /= 2;
VT /= 2;
WCrt(ba, CRT_ID_MODE_CONTROL, 0xe7);
}
else
WCrt(ba, CRT_ID_MODE_CONTROL, 0xe3);
WSeq(ba, SEQ_ID_MEMORY_MODE, (TEXT || (gv->depth == 1)) ? 0x06 : 0x0e);
if (cl_sd64 == 1) {
if (cl_64bit == 1) {
if (TEXT || (gv->depth == 1))
sr15 = 0x90;
sr15 = 0xd0;
else
sr15 = ((cl_fbsize / 0x100000 == 2) ? 0x38 : 0xb8);
WSeq(ba, SEQ_ID_CONF_RBACK, 0x00);
} else {
sr15 = (TEXT || (gv->depth == 1)) ? 0xd0 : 0xb0;
sr15 &= ((cl_fbsize / 0x100000) == 2) ? 0xff : 0x7f;
}
WSeq(ba, SEQ_ID_DRAM_CNTL, sr15);
WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00);
@ -1287,8 +1497,18 @@ cl_load_mon(gp, md)
/* Set clock */
cl_CompFQ((gv->depth == 24) ? gv->pixel_clock * 3 : gv->pixel_clock,
&num0, &denom0);
cl_CompFQ(gv->pixel_clock * clkmul, &num0, &denom0, &clkdoub);
if (clkdoub) {
HDE /= 2;
HBS /= 2;
HSS /= 2;
HSE /= 2;
HBE /= 2;
HT /= 2;
clkmode = 0x6;
}
WSeq(ba, SEQ_ID_VCLK_3_NUM, num0);
WSeq(ba, SEQ_ID_VCLK_3_DENOM, denom0);
@ -1313,13 +1533,11 @@ cl_load_mon(gp, md)
((VDE & 0x200) ? 0x40 : 0x00) |
((VSS & 0x200) ? 0x80 : 0x00));
WCrt(ba, CRT_ID_CHAR_HEIGHT,
0x40 | /* TEXT ? 0x00 ??? */
(DBLSCAN ? 0x80 : 0x00) |
((VBS & 0x200) ? 0x20 : 0x00) |
(TEXT ? ((md->fy - 1) & 0x1f) : 0x00));
WCrt(ba, CRT_ID_MODE_CONTROL, 0xe3);
/* text cursor */
@ -1354,42 +1572,17 @@ cl_load_mon(gp, md)
((VBE & 0x100) ? 0x40 : 0x00) |
((VBE & 0x200) ? 0x80 : 0x00));
/* depth dependent stuff */
switch (gv->depth) {
case 1:
case 4:
case 8:
clkdiv = 0;
break;
case 15:
case 16:
clkdiv = 3;
break;
case 24:
clkdiv = 2;
break;
default:
clkdiv = 0;
panic("grfcl: Unsuported depth: %i", gv->depth);
break;
}
WGfx(ba, GCT_ID_GRAPHICS_MODE,
((TEXT || (gv->depth == 1)) ? 0x00 : 0x40));
WGfx(ba, GCT_ID_MISC, (TEXT ? 0x04 : 0x01));
WSeq(ba, SEQ_ID_EXT_SEQ_MODE,
((TEXT || (gv->depth == 1)) ? 0x00 : 0x01) |
((cltype == PICASSO) ? 0x20 : 0x80) |
(clkdiv << 1));
delay(200000);
((cltype == PICASSO) ? 0x20 : 0x80) | clkmode);
/* write 0x00 to VDAC_MASK before accessing HDR this helps
sometimes, out of "secret" application note (crest) */
vgaw(ba, VDAC_MASK, 0);
delay(200000);
/* reset HDR "magic" access counter (crest) */
vgar(ba, VDAC_ADDRESS);
@ -1409,7 +1602,10 @@ cl_load_mon(gp, md)
HDE = gv->disp_width / 16;
break;
case 8:
vgaw(ba, VDAC_MASK, 0);
if (clkdoub)
vgaw(ba, VDAC_MASK, 0x4a); /* Clockdouble Magic */
else
vgaw(ba, VDAC_MASK, 0);
HDE = gv->disp_width / 8;
break;
case 15:
@ -1424,32 +1620,30 @@ cl_load_mon(gp, md)
vgaw(ba, VDAC_MASK, 0xc5);
HDE = (gv->disp_width / 8) * 3;
break;
case 32:
vgaw(ba, VDAC_MASK, 0xc5);
HDE = (gv->disp_width / 4);
break;
}
delay(20000);
/* reset HDR "magic" access counter (crest) */
vgar(ba, VDAC_ADDRESS);
delay(200000);
/* then enable all bit in VDAC_MASK afterwards (crest) */
vgaw(ba, VDAC_MASK, 0xff);
delay(20000);
WCrt(ba, CRT_ID_OFFSET, HDE);
if (cl_sd64 == 1) {
if (cl_64bit == 1) {
WCrt(ba, CRT_ID_SYNC_ADJ_GENLOCK, 0x00);
WCrt(ba, CRT_ID_OVERLAY_EXT_CTRL_REG, 0x40);
}
WCrt(ba, CRT_ID_EXT_DISP_CNTL,
((TEXT && gv->pixel_clock > 29000000) ? 0x40 : 0x00) |
0x22 |
((HDE > 0xff) ? 0x10 : 0x00)); /* text? */
((HDE > 0xff) ? 0x10 : 0x00));
delay(200000);
WAttr(ba, ACT_ID_ATTR_MODE_CNTL, (TEXT ? 0x0a : 0x01));
delay(200000);
WAttr(ba, 0x20 | ACT_ID_COLOR_PLANE_ENA,
(gv->depth == 1) ? 0x01 : 0x0f);
delay(200000);
/* text initialization */
@ -1503,7 +1697,6 @@ cl_inittextmode(gp)
/* set colors (B&W) */
vgaw(ba, VDAC_ADDRESS_W, 0);
for (z = 0; z < 256; z++) {
unsigned char r, g, b;
@ -1535,7 +1728,8 @@ cl_memset(d, c, l)
*d++ = c;
}
/* Special wakeup/passthrough registers on graphics boards
/*
* Special wakeup/passthrough registers on graphics boards
*
* The methods have diverged a bit for each board, so
* WPass(P) has been converted into a set of specific
@ -1551,10 +1745,10 @@ RegWakeup(ba)
vgaw(ba, PASS_ADDRESS_W, 0x1f);
break;
case PICASSO:
vgaw(ba, PASS_ADDRESS_W, 0xff);
/* Picasso needs no wakeup */
break;
case PICCOLO:
if (cl_sd64 == 1)
if (cl_64bit == 1)
vgaw(ba, PASS_ADDRESS_W, 0x1f);
else
vgaw(ba, PASS_ADDRESS_W, vgar(ba, PASS_ADDRESS) | 0x10);
@ -1573,10 +1767,11 @@ RegOnpass(ba)
vgaw(ba, PASS_ADDRESS_W, 0x4f);
break;
case PICASSO:
vgaw(ba, PASS_ADDRESS_WP, 0x01);
if (cl_64bit == 0)
vgaw(ba, PASS_ADDRESS_WP, 0x01);
break;
case PICCOLO:
if (cl_sd64 == 1)
if (cl_64bit == 1)
vgaw(ba, PASS_ADDRESS_W, 0x4f);
else
vgaw(ba, PASS_ADDRESS_W, vgar(ba, PASS_ADDRESS) & 0xdf);
@ -1596,12 +1791,11 @@ RegOffpass(ba)
vgaw(ba, PASS_ADDRESS_W, 0x6f);
break;
case PICASSO:
vgaw(ba, PASS_ADDRESS_W, 0xff);
delay(200000);
vgaw(ba, PASS_ADDRESS_W, 0xff);
if (cl_64bit == 0)
vgaw(ba, PASS_ADDRESS_W, 0xff);
break;
case PICCOLO:
if (cl_sd64 == 1)
if (cl_64bit == 1)
vgaw(ba, PASS_ADDRESS_W, 0x6f);
else
vgaw(ba, PASS_ADDRESS_W, vgar(ba, PASS_ADDRESS) | 0x20);