summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/sparc/dev/p9100.c556
1 files changed, 500 insertions, 56 deletions
diff --git a/sys/arch/sparc/dev/p9100.c b/sys/arch/sparc/dev/p9100.c
index 066241abeb3..6b1296f3a93 100644
--- a/sys/arch/sparc/dev/p9100.c
+++ b/sys/arch/sparc/dev/p9100.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: p9100.c,v 1.41 2006/12/02 11:24:02 miod Exp $ */
+/* $OpenBSD: p9100.c,v 1.42 2006/12/27 18:54:04 miod Exp $ */
/*
- * Copyright (c) 2003, 2005, Miodrag Vallat.
+ * Copyright (c) 2003, 2005, 2006, Miodrag Vallat.
* Copyright (c) 1999 Jason L. Wright (jason@thought.net)
* All rights reserved.
*
@@ -69,6 +69,15 @@
#include <sparc/dev/tctrlvar.h>
#endif
+#undef FIDDLE_WITH_PCI_REGISTERS
+
+/*
+ * Built-in LCD panel geometry
+ */
+
+#define LCD_WIDTH 800
+#define LCD_HEIGHT 600
+
/*
* SBus registers mappings
*/
@@ -78,21 +87,46 @@
#define P9100_REG_VRAM 2
#define P9100_REG_CONFIG 3
+#ifdef FIDDLE_WITH_PCI_REGISTERS
+/*
+ * This structure, mapped at register address 0x9100, allows non-PCI
+ * designs (such as the SPARCbook) to access the PCI configuration space.
+ */
+struct p9100_pci {
+ volatile u_int32_t address; /* within configuration space */
+ volatile u_int32_t data; /* _byte_ to read or write */
+};
+#endif
+
/* per-display variables */
struct p9100_softc {
struct sunfb sc_sunfb; /* common base part */
- struct rom_reg sc_phys;
+ struct rom_reg sc_phys[P9100_NREG - 1];
volatile u_int8_t *sc_cmd; /* command registers (dac, etc) */
volatile u_int8_t *sc_ctl; /* control registers (draw engine) */
+#ifdef FIDDLE_WITH_PCI_REGISTERS
+ struct p9100_pci *sc_pci; /* pci configuration space access */
+#endif
+ vsize_t sc_vramsize; /* total VRAM available */
union bt_cmap sc_cmap; /* Brooktree color map */
struct intrhand sc_ih;
- int sc_flags;
-#define SCF_EXTERNAL 0x01 /* external video enabled */
+ int sc_mapmode;
+ u_int sc_flags;
+#define SCF_INTERNAL 0x01 /* internal video enabled */
+#define SCF_EXTERNAL 0x02 /* external video enabled */
+#if NTCTRL > 0
+#define SCF_MAPPEDSWITCH 0x04 /* switch mode when leaving emul */
+ u_int sc_mapwidth; /* non-emul video mode parameters */
+ u_int sc_mapheight;
+ u_int sc_mapdepth;
+#endif
+
u_int32_t sc_junk; /* throwaway value */
};
void p9100_burner(void *, u_int, u_int);
void p9100_external_video(void *, int);
+void p9100_initialize_ramdac(struct p9100_softc *, u_int, u_int);
int p9100_intr(void *);
int p9100_ioctl(void *, u_long, caddr_t, int, struct proc *);
static __inline__
@@ -100,6 +134,7 @@ void p9100_loadcmap_deferred(struct p9100_softc *, u_int, u_int);
void p9100_loadcmap_immediate(struct p9100_softc *, u_int, u_int);
paddr_t p9100_mmap(void *, off_t, int);
int p9100_pick_romfont(struct p9100_softc *);
+void p9100_prom(void *);
void p9100_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);
u_int p9100_read_ramdac(struct p9100_softc *, u_int);
void p9100_write_ramdac(struct p9100_softc *, u_int, u_int);
@@ -229,61 +264,98 @@ p9100attach(struct device *parent, struct device *self, void *args)
struct p9100_softc *sc = (struct p9100_softc *)self;
struct rasops_info *ri = &sc->sc_sunfb.sf_ro;
struct confargs *ca = args;
- int node, scr, fb_depth;
- int isconsole, fontswitch, clear;
+ struct romaux *ra = &ca->ca_ra;
+ int node, scr, force_reset;
+ int isconsole, fontswitch, clear = 0;
#ifdef DIAGNOSTIC
- if (ca->ca_ra.ra_nreg < P9100_NREG - 1) {
+ if (ra->ra_nreg < P9100_NREG) {
printf(": expected %d registers, got only %d\n",
- P9100_NREG, ca->ca_ra.ra_nreg);
+ P9100_NREG, ra->ra_nreg);
return;
}
#endif
- sc->sc_flags = 0;
+ sc->sc_flags = SCF_INTERNAL;
+ sc->sc_mapmode = WSDISPLAYIO_MODE_EMUL;
- sc->sc_phys = ca->ca_ra.ra_reg[P9100_REG_VRAM];
+ bcopy(ra->ra_reg, sc->sc_phys, sizeof(sc->sc_phys));
- sc->sc_ctl = mapiodev(&ca->ca_ra.ra_reg[P9100_REG_CTL], 0,
- ca->ca_ra.ra_reg[P9100_REG_CTL].rr_len);
- sc->sc_cmd = mapiodev(&ca->ca_ra.ra_reg[P9100_REG_CMD], 0,
- ca->ca_ra.ra_reg[P9100_REG_CMD].rr_len);
+ sc->sc_ctl = mapiodev(&ra->ra_reg[P9100_REG_CTL], 0,
+ ra->ra_reg[P9100_REG_CTL].rr_len);
+ sc->sc_cmd = mapiodev(&ra->ra_reg[P9100_REG_CMD], 0,
+ ra->ra_reg[P9100_REG_CMD].rr_len);
+#ifdef FIDDLE_WITH_PCI_REGISTERS
+ sc->sc_pci = (struct p9100_pci *)
+ mapiodev(&ra->ra_reg[P9100_REG_CONFIG], 0,
+ ra->ra_reg[P9100_REG_CONFIG].rr_len);
+#endif
- node = ca->ca_ra.ra_node;
+ node = ra->ra_node;
isconsole = node == fbnode;
P9100_SELECT_SCR(sc);
scr = P9100_READ_CTL(sc, P9000_SYSTEM_CONFIG);
switch (scr & SCR_PIXEL_MASK) {
- case SCR_PIXEL_32BPP:
- fb_depth = 32;
- break;
- case SCR_PIXEL_24BPP:
- fb_depth = 24;
- break;
- case SCR_PIXEL_16BPP:
- fb_depth = 16;
- break;
default:
#ifdef DIAGNOSTIC
- printf(": unknown color depth code 0x%x, assuming 8\n%s",
- scr & SCR_PIXEL_MASK, self->dv_xname);
+ printf(": unknown color depth code 0x%x",
+ scr & SCR_PIXEL_MASK);
#endif
/* FALLTHROUGH */
+ case SCR_PIXEL_32BPP:
+ case SCR_PIXEL_24BPP:
+ case SCR_PIXEL_16BPP:
+ force_reset = 1;
+ break;
case SCR_PIXEL_8BPP:
- fb_depth = 8;
+ force_reset = 0;
break;
}
- fb_setsize(&sc->sc_sunfb, fb_depth, 800, 600, node, ca->ca_bustype);
+ fb_setsize(&sc->sc_sunfb, 8, LCD_WIDTH, LCD_HEIGHT, node,
+ ca->ca_bustype);
+
+#if 0
+ /*
+ * The PROM will initialize us in 800x600x8 mode anyway. If it
+ * does not, we'll force this mode right now.
+ */
+ if (sc->sc_sunfb.sf_width != LCD_WIDTH || sc->sc_sunfb.sf_depth != 8 ||
+ sc->sc_sunfb.sf_height != LCD_HEIGHT || force_reset != 0) {
+ sc->sc_sunfb.sf_width = LCD_WIDTH;
+ sc->sc_sunfb.sf_height = LCD_HEIGHT;
+ sc->sc_sunfb.sf_depth = 8;
+ sc->sc_sunfb.sf_linebytes = LCD_WIDTH;
+
+ printf("\n");
+ p9100_initialize_ramdac(sc, LCD_WIDTH, 8);
+ printf("%s", self->dv_xname);
+ clear = 1;
+ }
+#endif
+
+#if NTCTRL > 0
+ /*
+ * We want to run the frame buffer in 8bpp mode for the emulation mode,
+ * and use a potentially better mode for the mapped (X11) mode.
+ * Eventually this will become runtime user-selectable.
+ */
+
+ sc->sc_mapwidth = LCD_WIDTH;
+ sc->sc_mapheight = LCD_HEIGHT;
+ sc->sc_mapdepth = 8;
- ri->ri_bits = mapiodev(&sc->sc_phys, 0,
- round_page(sc->sc_sunfb.sf_fbsize));
+ if (sc->sc_mapwidth != sc->sc_sunfb.sf_width ||
+ sc->sc_mapdepth != sc->sc_sunfb.sf_depth)
+ SET(sc->sc_flags, SCF_MAPPEDSWITCH);
+#endif
+
+ ri->ri_bits = mapiodev(&ra->ra_reg[P9100_REG_VRAM], 0,
+ sc->sc_vramsize = round_page(ra->ra_reg[P9100_REG_VRAM].rr_len));
ri->ri_hw = sc;
- printf(": rev %x, %dx%d, depth %d\n", scr & SCR_ID_MASK,
- sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height,
- sc->sc_sunfb.sf_depth);
+ printf(": rev %x, %dx%d\n", scr & SCR_ID_MASK, LCD_WIDTH, LCD_HEIGHT);
/* Disable frame buffer interrupts */
P9100_SELECT_SCR(sc);
@@ -291,7 +363,7 @@ p9100attach(struct device *parent, struct device *self, void *args)
sc->sc_ih.ih_fun = p9100_intr;
sc->sc_ih.ih_arg = sc;
- intr_establish(ca->ca_ra.ra_intr[0].int_pri, &sc->sc_ih, IPL_FB,
+ intr_establish(ra->ra_intr[0].int_pri, &sc->sc_ih, IPL_FB,
self->dv_xname);
/*
@@ -322,25 +394,28 @@ p9100attach(struct device *parent, struct device *self, void *args)
p9100_external_video(sc, 1);
#endif
- clear = !isconsole || fontswitch;
+ if (isconsole == 0 || fontswitch)
+ clear = 1;
fbwscons_init(&sc->sc_sunfb, clear ? RI_CLEAR : 0);
- if (!clear) {
+ if (clear == 0) {
ri->ri_bits -= 2 * ri->ri_xscale;
ri->ri_xorigin -= 2 * ri->ri_xscale;
}
fbwscons_setcolormap(&sc->sc_sunfb, p9100_setcolor);
/*
- * Plug-in accelerated console operations if we can.
+ * Plug-in accelerated console operations.
*/
- if (sc->sc_sunfb.sf_depth == 8)
- p9100_ras_init(sc);
+ p9100_ras_init(sc);
/* enable video */
p9100_burner(sc, 1, 0);
if (isconsole) {
fbwscons_console_init(&sc->sc_sunfb, clear ? 0 : -1);
+#if NTCTRL > 0
+ shutdownhook_establish(p9100_prom, sc);
+#endif
}
fbwscons_attach(&sc->sc_sunfb, &p9100_accessops, isconsole);
@@ -364,23 +439,54 @@ p9100_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
break;
case WSDISPLAYIO_SMODE:
- /* Restore proper acceleration state upon leaving X11 */
- if (*(u_int *)data == WSDISPLAYIO_MODE_EMUL &&
- sc->sc_sunfb.sf_depth == 8) {
+ sc->sc_mapmode = *(u_int *)data;
+ switch (sc->sc_mapmode) {
+ case WSDISPLAYIO_MODE_DUMBFB:
+ case WSDISPLAYIO_MODE_MAPPED:
+#if NTCTRL > 0
+ if (ISSET(sc->sc_flags, SCF_MAPPEDSWITCH))
+ p9100_initialize_ramdac(sc,
+ sc->sc_mapwidth, sc->sc_mapdepth);
+#endif
+ break;
+ case WSDISPLAYIO_MODE_EMUL:
+#if NTCTRL > 0
+ if (ISSET(sc->sc_flags, SCF_MAPPEDSWITCH))
+ p9100_initialize_ramdac(sc, LCD_WIDTH, 8);
+#endif
+ fbwscons_setcolormap(&sc->sc_sunfb, p9100_setcolor);
+ /* Restore proper acceleration state as well */
p9100_ras_init(sc);
+ break;
}
break;
case WSDISPLAYIO_GINFO:
wdf = (struct wsdisplay_fbinfo *)data;
- wdf->height = sc->sc_sunfb.sf_height;
- wdf->width = sc->sc_sunfb.sf_width;
- wdf->depth = sc->sc_sunfb.sf_depth;
- wdf->cmsize = 256;
+#if NTCTRL > 0
+ if (ISSET(sc->sc_flags, SCF_MAPPEDSWITCH)) {
+ wdf->width = sc->sc_mapwidth;
+ wdf->height = sc->sc_mapheight;
+ wdf->depth = sc->sc_mapdepth;
+ wdf->cmsize = sc->sc_mapdepth == 8 ? 256 : 0;
+ } else
+#endif
+ {
+ wdf->width = LCD_WIDTH;
+ wdf->height = LCD_HEIGHT;
+ wdf->depth = 8;
+ wdf->cmsize = 256;
+ }
break;
case WSDISPLAYIO_LINEBYTES:
- *(u_int *)data = sc->sc_sunfb.sf_linebytes;
+#if NTCTRL > 0
+ if (ISSET(sc->sc_flags, SCF_MAPPEDSWITCH))
+ *(u_int *)data = sc->sc_mapwidth *
+ (sc->sc_mapdepth / 8);
+ else
+#endif
+ *(u_int *)data = sc->sc_sunfb.sf_linebytes;
break;
case WSDISPLAYIO_GETCMAP:
@@ -411,7 +517,11 @@ p9100_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
case WSDISPLAYIO_PARAM_BACKLIGHT:
dp->min = 0;
dp->max = 1;
- dp->curval = tadpole_get_video() & TV_ON ? 1 : 0;
+ if (ISSET(sc->sc_flags, SCF_INTERNAL))
+ dp->curval =
+ tadpole_get_video() & TV_ON ? 1 : 0;
+ else
+ dp->curval = 0;
break;
default:
return (-1);
@@ -426,7 +536,8 @@ p9100_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
tadpole_set_brightness(dp->curval);
break;
case WSDISPLAYIO_PARAM_BACKLIGHT:
- tadpole_set_video(dp->curval);
+ if (ISSET(sc->sc_flags, SCF_INTERNAL))
+ tadpole_set_video(dp->curval);
break;
default:
return (-1);
@@ -454,15 +565,38 @@ paddr_t
p9100_mmap(void *v, off_t offset, int prot)
{
struct p9100_softc *sc = v;
+ struct rom_reg *rr;
if ((offset & PAGE_MASK) != 0)
return (-1);
- if (offset >= 0 && offset < sc->sc_sunfb.sf_fbsize) {
- return (REG2PHYS(&sc->sc_phys, offset) | PMAP_NC);
+ switch (sc->sc_mapmode) {
+ case WSDISPLAYIO_MODE_MAPPED:
+ /*
+ * We provide the following mapping:
+ * 000000 - 0000ff control registers
+ * 002000 - 003fff command registers
+ * 800000 - 9fffff vram
+ */
+ rr = &sc->sc_phys[P9100_REG_CTL];
+ if (offset >= 0 && offset < rr->rr_len)
+ break;
+ offset -= 0x2000;
+ rr = &sc->sc_phys[P9100_REG_CMD];
+ if (offset >= 0 && offset < rr->rr_len)
+ break;
+ offset -= (0x800000 - 0x2000);
+ /* FALLTHROUGH */
+ case WSDISPLAYIO_MODE_DUMBFB:
+ rr = &sc->sc_phys[P9100_REG_VRAM];
+ if (offset >= 0 && offset < sc->sc_vramsize)
+ break;
+ /* FALLTHROUGH */
+ default:
+ return (-1);
}
- return (-1);
+ return (REG2PHYS(rr, offset) | PMAP_NC);
}
void
@@ -544,7 +678,8 @@ p9100_burner(void *v, u_int on, u_int flags)
vcr &= ~SRTC1_VIDEN;
P9100_WRITE_CTL(sc, P9000_SRTC1, vcr);
#if NTCTRL > 0
- tadpole_set_video(on);
+ if (ISSET(sc->sc_flags, SCF_INTERNAL))
+ tadpole_set_video(on);
#endif
splx(s);
}
@@ -887,6 +1022,7 @@ p9100_pick_romfont(struct p9100_softc *sc)
/*
* External video control
*/
+
void
p9100_external_video(void *v, int on)
{
@@ -898,12 +1034,320 @@ p9100_external_video(void *v, int on)
if (on) {
p9100_write_ramdac(sc, IBM525_POWER,
p9100_read_ramdac(sc, IBM525_POWER) & ~P_DAC_PWR_DISABLE);
- sc->sc_flags |= SCF_EXTERNAL;
+ SET(sc->sc_flags, SCF_EXTERNAL);
} else {
p9100_write_ramdac(sc, IBM525_POWER,
p9100_read_ramdac(sc, IBM525_POWER) | P_DAC_PWR_DISABLE);
- sc->sc_flags &= ~SCF_EXTERNAL;
+ CLR(sc->sc_flags, SCF_EXTERNAL);
}
splx(s);
}
+
+/*
+ * Video mode programming
+ *
+ * All magic values come from s3gxtrmb.pdf.
+ */
+
+#if NTCTRL > 0
+
+/* IBM RGB525 registers and values */
+
+static const u_int8_t p9100_dacreg[] = {
+ IBM525_MISC1,
+ IBM525_MISC2,
+ IBM525_MISC3,
+ IBM525_MISC4,
+ IBM525_MISC_CLOCK,
+ IBM525_SYNC,
+ IBM525_HSYNC_POS,
+ IBM525_POWER,
+ IBM525_DAC_OP,
+ IBM525_PALETTE,
+ IBM525_PIXEL,
+ IBM525_PF8,
+ IBM525_PF16,
+ IBM525_PF24,
+ IBM525_PF32,
+ IBM525_PLL1,
+ IBM525_PLL2,
+ IBM525_PLL_FIXED_REF,
+ IBM525_SYSCLK,
+ IBM525_PLL_REF_DIV,
+ IBM525_PLL_VCO_DIV,
+ 0
+};
+
+static u_int8_t p9100_dacval[] = {
+ M1_SENSE_DISABLE | M1_VRAM_64,
+ M2_PCLK_PLL | M2_PALETTE_8 | M2_MODE_VRAM,
+ 0,
+ 0, /* will be computed */
+ MC_B24P_SCLK | MC_PLL_ENABLE, /* will be modified */
+ S_HSYN_NORMAL | S_VSYN_NORMAL,
+ 0,
+ 0, /* will be computed */
+ DO_FAST_SLEW,
+ 0,
+ 0, /* will be computed */
+ PF8_INDIRECT,
+ PF16_DIRECT | PF16_LINEAR | PF16_565,
+ PF24_DIRECT,
+ PF32_DIRECT,
+ P1_CLK_REF | P1_SRC_EXT_F | P1_SRC_DIRECT_F,
+ 0, /* F0, will be set before */
+ 5,
+ SC_ENABLE,
+ 5,
+ MHZ_TO_PLL(50)
+};
+
+/* Power 9100 registers and values */
+
+static const u_int32_t p9100_reg[] = {
+ P9000_HTR,
+ P9000_HSRE,
+ P9000_HBRE,
+ P9000_HBFE,
+ P9000_HCP,
+ P9000_VL,
+ P9000_VSRE,
+ P9000_VBRE,
+ P9000_VBFE,
+ P9000_VCP,
+ 0
+};
+
+static const u_int32_t p9100_val_800_32[] = {
+ 0x1f3, 0x023, 0x053, 0x1e3, 0x000, 0x271, 0x002, 0x016, 0x26e, 0x000
+};
+#if 0 /* No X server for this mode, yet */
+static const u_int32_t p9100_val_800_24[] = {
+ 0x176, 0x01a, 0x03d, 0x169, 0x000, 0x271, 0x002, 0x016, 0x26e, 0x000
+};
+#endif
+static const u_int32_t p9100_val_800_8[] = {
+ 0x07c, 0x008, 0x011, 0x075, 0x000, 0x271, 0x002, 0x016, 0x26e, 0x000
+};
+#if NTCTRL > 0
+static const u_int32_t p9100_val_640_32[] = {
+ 0x18f, 0x02f, 0x043, 0x183, 0x000, 0x205, 0x003, 0x022, 0x202, 0x000
+};
+static const u_int32_t p9100_val_640_8[] = {
+ 0x063, 0x00b, 0x00d, 0x05d, 0x000, 0x205, 0x003, 0x022, 0x202, 0x000
+};
+static const u_int32_t p9100_val_1024_8[] = {
+ 0x0a7, 0x019, 0x022, 0x0a2, 0x000, 0x325, 0x003, 0x023, 0x323, 0x000
+};
+#endif
+
+void
+p9100_initialize_ramdac(struct p9100_softc *sc, u_int width, u_int depth)
+{
+ int s;
+ const u_int8_t *dacregp, *dacvalp;
+ const u_int32_t *p9regp, *p9valp;
+ u_int8_t pllclk, dacval;
+ u_int32_t scr;
+
+ /*
+ * XXX Switching to a low-res 8bpp mode causes kernel faults
+ * XXX unless coming from an high-res 8bpp mode, and I have
+ * XXX no idea why.
+ */
+ if (depth == 8 && width != 1024)
+ p9100_initialize_ramdac(sc, 1024, 8);
+
+ switch (width) {
+ case 1024:
+ p9valp = p9100_val_1024_8;
+ pllclk = MHZ_TO_PLL(65);
+ /* 1024 bytes scanline */
+ scr = SCR_SC(0, 0, 0, 1) | SCR_PIXEL_8BPP;
+ break;
+ default:
+ /* FALLTHROUGH */
+ case 800:
+ switch (depth) {
+ case 32:
+ p9valp = p9100_val_800_32;
+ /* 3200 = 128 + 1024 + 2048 bytes scanline */
+ scr = SCR_SC(3, 6, 7, 0) |
+ SCR_PIXEL_32BPP | SCR_SWAP_WORDS | SCR_SWAP_BYTES;
+ break;
+#if 0
+ case 24:
+ p9valp = p9100_val_800_24;
+ /* 2400 = 32 + 64 + 256 + 2048 bytes scanline */
+ scr = SCR_SC(1, 2, 4, 2) | SCR_PIXEL_24BPP;
+ break;
+#endif
+ default:
+ case 8:
+ p9valp = p9100_val_800_8;
+ /* 800 = 32 + 256 + 512 bytes scanline */
+ scr = SCR_SC(1, 4, 5, 0) | SCR_PIXEL_8BPP;
+ break;
+ }
+ pllclk = MHZ_TO_PLL(36);
+ break;
+ case 640:
+ switch (depth) {
+ case 32:
+ p9valp = p9100_val_640_32;
+ /* 2560 = 512 + 2048 bytes scanline */
+ scr = SCR_SC(5, 7, 0, 0) |
+ SCR_PIXEL_32BPP | SCR_SWAP_WORDS | SCR_SWAP_BYTES;
+ break;
+ default:
+ case 8:
+ p9valp = p9100_val_640_8;
+ /* 640 = 128 + 512 bytes scanline */
+ scr = SCR_SC(3, 5, 0, 0) | SCR_PIXEL_8BPP;
+ break;
+ }
+ pllclk = MHZ_TO_PLL(25);
+ break;
+ }
+ dacvalp = p9100_dacval;
+
+ s = splhigh();
+
+#ifdef FIDDLE_WITH_PCI_REGISTERS
+ /*
+ * Magical initialization sequence, from s3gxtrmb.pdf.
+ * DANGER! Sometimes freezes the machine solid, cause unknown.
+ */
+ sc->sc_pci->address = 0x13000000;
+ sc->sc_pci->data = 0;
+ sc->sc_pci->address = 0x30000000;
+ sc->sc_pci->data = 0;
+ sc->sc_pci->address = 0x41000000;
+ sc->sc_pci->data = 0; /* No register mapping at a0000 */
+ sc->sc_pci->address = 0x04000000;
+ sc->sc_pci->data = 0xa3000000;
+#endif
+
+ /*
+ * Initialize the RAMDAC
+ */
+ P9100_SELECT_DAC(sc);
+ P9100_WRITE_RAMDAC(sc, IBM525_PIXMASK, 0xff);
+ P9100_FLUSH_DAC(sc);
+ P9100_WRITE_RAMDAC(sc, IBM525_IDXCONTROL, 0x00);
+ P9100_FLUSH_DAC(sc);
+
+ p9100_write_ramdac(sc, IBM525_F(0), pllclk);
+ for (dacregp = p9100_dacreg; *dacregp != 0; dacregp++, dacvalp++) {
+ switch (*dacregp) {
+ case IBM525_MISC4:
+ dacval = pllclk >= MHZ_TO_PLL(50) ?
+ M4_FAST : M4_INVERT_DCLK;
+ break;
+ case IBM525_MISC_CLOCK:
+ dacval = *dacvalp & ~MC_DDOT_DIV_MASK;
+ switch (depth) {
+ case 32:
+ dacval |= MC_DDOT_DIV_2;
+ break;
+ case 16:
+ dacval |= MC_DDOT_DIV_4;
+ break;
+ default:
+ case 24:
+ case 8:
+ dacval |= MC_DDOT_DIV_8;
+ break;
+ }
+ break;
+ case IBM525_POWER:
+ if (depth == 24)
+ dacval = 0;
+ else
+ dacval = P_SCLK_DISABLE;
+ break;
+ case IBM525_PIXEL:
+ switch (depth) {
+ case 32:
+ dacval = PIX_32BPP;
+ break;
+ case 24:
+ dacval = PIX_24BPP;
+ break;
+ case 16:
+ dacval = PIX_16BPP;
+ break;
+ default:
+ case 8:
+ dacval = PIX_8BPP;
+ break;
+ }
+ break;
+ default:
+ dacval = *dacvalp;
+ break;
+ }
+ p9100_write_ramdac(sc, *dacregp, dacval);
+ }
+
+ /*
+ * Initialize the Power 9100
+ */
+
+ P9100_SELECT_SCR(sc);
+ P9100_WRITE_CTL(sc, P9000_SYSTEM_CONFIG, scr);
+ P9100_SELECT_VCR(sc);
+ P9100_WRITE_CTL(sc, P9000_SRTC1,
+ SRTC1_VSYNC_INTERNAL | SRTC1_HSYNC_INTERNAL | SRTC1_VIDEN | 0x03);
+ P9100_WRITE_CTL(sc, P9000_SRTC2, 0x05);
+ P9100_SELECT_VRAM(sc);
+ P9100_WRITE_CTL(sc, P9000_MCR, 0xc808007d);
+ delay(3000);
+
+ P9100_SELECT_VCR(sc);
+ for (p9regp = p9100_reg; *p9regp != 0; p9regp++, p9valp++)
+ P9100_WRITE_CTL(sc, *p9regp, *p9valp);
+
+ P9100_SELECT_VRAM(sc);
+ P9100_WRITE_CTL(sc, P9000_REFRESH_PERIOD, 0x3ff);
+
+ /* Disable frame buffer interrupts */
+ P9100_SELECT_SCR(sc);
+ P9100_WRITE_CTL(sc, P9000_INTERRUPT_ENABLE, IER_MASTER_ENABLE | 0);
+
+ /*
+ * Enable internal video... (it's a kind of magic)
+ */
+ p9100_write_ramdac(sc, IBM525_MISC4,
+ p9100_read_ramdac(sc, IBM525_MISC4) | 0xc0);
+
+ /*
+ * ... unless it does not fit.
+ */
+ if (width != LCD_WIDTH) {
+ CLR(sc->sc_flags, SCF_INTERNAL);
+ tadpole_set_video(0);
+ } else {
+ SET(sc->sc_flags, SCF_INTERNAL);
+ tadpole_set_video(1);
+ }
+
+ p9100_external_video(sc, ISSET(sc->sc_flags, SCF_EXTERNAL));
+
+ splx(s);
+}
+
+void
+p9100_prom(void *v)
+{
+ struct p9100_softc *sc = v;
+
+ if (ISSET(sc->sc_flags, SCF_MAPPEDSWITCH) &&
+ sc->sc_mapmode != WSDISPLAYIO_MODE_EMUL) {
+ p9100_initialize_ramdac(sc, LCD_WIDTH, 8);
+ fbwscons_setcolormap(&sc->sc_sunfb, p9100_setcolor);
+ p9100_ras_init(sc);
+ }
+}
+#endif /* NTCTRL > 0 */