From b835a00fa881ea5394ceec622463c125a7b56f28 Mon Sep 17 00:00:00 2001 From: veego Date: Wed, 5 Mar 1997 22:46:32 +0000 Subject: [PATCH] - 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) --- sys/arch/amiga/dev/grf_cl.c | 624 +++++++++++++++++++++++------------- 1 file changed, 409 insertions(+), 215 deletions(-) diff --git a/sys/arch/amiga/dev/grf_cl.c b/sys/arch/amiga/dev/grf_cl.c index 1dadcfd404c8..d077c63552a2 100644 --- a/sys/arch/amiga/dev/grf_cl.c +++ b/sys/arch/amiga/dev/grf_cl.c @@ -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 #include -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);