Make colour depths higher than 8bit work in X.
Now igsfb will switch to 16 or 32 bit colour when entering graphics mode, depending on available video memory and the given mode. While there re-initialize the colour map etc. when leaving graphics mode.
This commit is contained in:
parent
c32688c3c2
commit
910612113d
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: igsfb.c,v 1.46 2009/11/11 17:01:17 macallan Exp $ */
|
||||
/* $NetBSD: igsfb.c,v 1.47 2009/11/18 21:59:38 macallan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002, 2003 Valeriy E. Ushakov
|
||||
@ -31,7 +31,7 @@
|
||||
* Integraphics Systems IGA 168x and CyberPro series.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: igsfb.c,v 1.46 2009/11/11 17:01:17 macallan Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: igsfb.c,v 1.47 2009/11/18 21:59:38 macallan Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -201,7 +201,8 @@ igsfb_attach_subr(struct igsfb_softc *sc, int isconsole)
|
||||
? "hardware bswap, " : "software bswap, "
|
||||
: "",
|
||||
dc->dc_width, dc->dc_height, dc->dc_depth);
|
||||
|
||||
printf("%s: using %dbpp for X\n", device_xname(&sc->sc_dev),
|
||||
dc->dc_maxdepth);
|
||||
ri = &dc->dc_console.scr_ri;
|
||||
ri->ri_ops.eraserows(ri, 0, ri->ri_rows, defattr);
|
||||
|
||||
@ -613,13 +614,13 @@ igsfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
|
||||
#define wsd_fbip ((struct wsdisplay_fbinfo *)data)
|
||||
wsd_fbip->height = dc->dc_height;
|
||||
wsd_fbip->width = dc->dc_width;
|
||||
wsd_fbip->depth = dc->dc_depth;
|
||||
wsd_fbip->depth = dc->dc_maxdepth;
|
||||
wsd_fbip->cmsize = IGS_CMAP_SIZE;
|
||||
#undef wsd_fbip
|
||||
return 0;
|
||||
|
||||
case WSDISPLAYIO_LINEBYTES:
|
||||
*(int *)data = dc->dc_stride;
|
||||
*(int *)data = dc->dc_width * (dc->dc_maxdepth >> 3);
|
||||
return 0;
|
||||
|
||||
case WSDISPLAYIO_SMODE:
|
||||
@ -632,8 +633,14 @@ igsfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
|
||||
igsfb_update_cursor(dc,
|
||||
WSDISPLAY_CURSOR_DOCUR);
|
||||
}
|
||||
if ((dc->dc_mode != NULL) && (dc->dc_maxdepth != 8))
|
||||
igsfb_set_mode(dc, dc->dc_mode,
|
||||
dc->dc_maxdepth);
|
||||
} else {
|
||||
dc->dc_mapped = 0;
|
||||
if ((dc->dc_mode != NULL) && (dc->dc_maxdepth != 8))
|
||||
igsfb_set_mode(dc, dc->dc_mode, 8);
|
||||
igsfb_init_cmap(dc);
|
||||
/* reinit sprite for text cursor */
|
||||
if (dc->dc_hwflags & IGSFB_HW_TEXT_CURSOR) {
|
||||
igsfb_make_text_cursor(dc, dc->dc_vd.active);
|
||||
@ -1170,6 +1177,7 @@ igsfb_accel_wait(struct igsfb_devconfig *dc)
|
||||
int timo = 100000;
|
||||
uint8_t reg;
|
||||
|
||||
bus_space_write_1(t, h, IGS_COP_MAP_FMT_REG, (dc->dc_depth >> 3) - 1);
|
||||
while (timo--) {
|
||||
reg = bus_space_read_1(t, h, IGS_COP_CTL_REG);
|
||||
if ((reg & IGS_COP_CTL_BUSY) == 0)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: igsfb_subr.c,v 1.11 2009/11/18 06:10:50 macallan Exp $ */
|
||||
/* $NetBSD: igsfb_subr.c,v 1.12 2009/11/18 21:59:38 macallan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002 Valeriy E. Ushakov
|
||||
@ -32,7 +32,7 @@
|
||||
* Integraphics Systems IGA 168x and CyberPro series.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: igsfb_subr.c,v 1.11 2009/11/18 06:10:50 macallan Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: igsfb_subr.c,v 1.12 2009/11/18 21:59:38 macallan Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -427,7 +427,7 @@ void
|
||||
igsfb_hw_setup(struct igsfb_devconfig *dc)
|
||||
{
|
||||
const struct videomode *mode = NULL;
|
||||
int i;
|
||||
int i, size, d;
|
||||
|
||||
igsfb_init_seq(dc);
|
||||
igsfb_init_crtc(dc);
|
||||
@ -443,20 +443,36 @@ igsfb_hw_setup(struct igsfb_devconfig *dc)
|
||||
}
|
||||
|
||||
if (i < videomode_count) {
|
||||
size = videomode_list[i].hdisplay * videomode_list[i].vdisplay;
|
||||
/* found a mode, now let's see if we can display it */
|
||||
if ((videomode_list[i].dot_clock <= IGS_MAX_CLOCK) &&
|
||||
(videomode_list[i].hdisplay <= 2048) &&
|
||||
(videomode_list[i].hdisplay >= 320) &&
|
||||
(videomode_list[i].vdisplay <= 2048) &&
|
||||
(videomode_list[i].vdisplay >= 200)) {
|
||||
(videomode_list[i].vdisplay >= 200) &&
|
||||
(size <= (dc->dc_memsz - 0x1000))) {
|
||||
mode = &videomode_list[i];
|
||||
/*
|
||||
* now let's see which maximum depth we can support
|
||||
* in that mode
|
||||
*/
|
||||
d = (dc->dc_vmemsz - 0x1000) / size;
|
||||
if (d >= 4) {
|
||||
dc->dc_maxdepth = 32;
|
||||
} else if (d >= 2) {
|
||||
dc->dc_maxdepth = 16;
|
||||
} else
|
||||
dc->dc_maxdepth = 8;
|
||||
}
|
||||
}
|
||||
dc->dc_mode = mode;
|
||||
|
||||
if (mode != NULL) {
|
||||
igsfb_set_mode(dc, mode, 8);
|
||||
} else
|
||||
} else {
|
||||
igsfb_1024x768_8bpp_60Hz(dc);
|
||||
dc->dc_maxdepth = 8;
|
||||
}
|
||||
|
||||
igsfb_video_on(dc);
|
||||
}
|
||||
@ -470,30 +486,32 @@ igsfb_set_mode(struct igsfb_devconfig *dc, const struct videomode *mode,
|
||||
int i, m, n, p, hoffset, bytes_per_pixel, memfetch;
|
||||
int vsync_start, hsync_start, vsync_end, hsync_end;
|
||||
int vblank_start, vblank_end, hblank_start, hblank_end;
|
||||
uint8_t vclk1, vclk2, vclk3, overflow;
|
||||
int croffset;
|
||||
uint8_t vclk1, vclk2, vclk3, overflow, reg, seq_mode;
|
||||
|
||||
switch (depth) {
|
||||
case 8:
|
||||
bytes_per_pixel = IGS_EXT_SEQ_8BPP;
|
||||
seq_mode = IGS_EXT_SEQ_8BPP;
|
||||
break;
|
||||
case 15:
|
||||
bytes_per_pixel = IGS_EXT_SEQ_15BPP; /* 5-5-5 */
|
||||
seq_mode = IGS_EXT_SEQ_15BPP; /* 5-5-5 */
|
||||
break;
|
||||
case 16:
|
||||
bytes_per_pixel = IGS_EXT_SEQ_16BPP; /* 5-6-5 */
|
||||
seq_mode = IGS_EXT_SEQ_16BPP; /* 5-6-5 */
|
||||
break;
|
||||
case 24:
|
||||
bytes_per_pixel = IGS_EXT_SEQ_24BPP; /* 8-8-8 */
|
||||
seq_mode = IGS_EXT_SEQ_24BPP; /* 8-8-8 */
|
||||
break;
|
||||
case 32:
|
||||
bytes_per_pixel = IGS_EXT_SEQ_32BPP;
|
||||
seq_mode = IGS_EXT_SEQ_32BPP;
|
||||
break;
|
||||
default:
|
||||
aprint_error("igsfb: unsupported depth (%d), reverting"
|
||||
" to 8 bit\n", depth);
|
||||
depth = 8;
|
||||
bytes_per_pixel = IGS_EXT_SEQ_8BPP;
|
||||
seq_mode = IGS_EXT_SEQ_8BPP;
|
||||
}
|
||||
bytes_per_pixel = depth >> 3;
|
||||
|
||||
hoffset = (mode->hdisplay >> 3) * bytes_per_pixel;
|
||||
memfetch = hoffset + 1;
|
||||
@ -503,6 +521,11 @@ igsfb_set_mode(struct igsfb_devconfig *dc, const struct videomode *mode,
|
||||
((mode->vsync_start & 0x400) >> 7) |
|
||||
0x10;
|
||||
|
||||
/* RAMDAC address 2 select */
|
||||
reg = igs_ext_read(iot, ioh, IGS_EXT_SPRITE_CTL);
|
||||
igs_ext_write(iot, ioh, IGS_EXT_SPRITE_CTL,
|
||||
reg | IGS_EXT_SPRITE_DAC_PEL);
|
||||
|
||||
if (depth == 8) {
|
||||
/* palette mode */
|
||||
bus_space_write_1(dc->dc_iot, dc->dc_ioh, IGS_DAC_CMD, 0x06);
|
||||
@ -510,6 +533,10 @@ igsfb_set_mode(struct igsfb_devconfig *dc, const struct videomode *mode,
|
||||
/* bypass palette */
|
||||
bus_space_write_1(dc->dc_iot, dc->dc_ioh, IGS_DAC_CMD, 0x16);
|
||||
}
|
||||
/* restore */
|
||||
igs_ext_write(iot, ioh, IGS_EXT_SPRITE_CTL, reg);
|
||||
|
||||
bus_space_write_1(iot, ioh, IGS_PEL_MASK, 0xff);
|
||||
|
||||
igs_crtc_write(iot, ioh, 0x11, 0x00); /* write enable CRTC 0..7 */
|
||||
|
||||
@ -593,11 +620,10 @@ igsfb_set_mode(struct igsfb_devconfig *dc, const struct videomode *mode,
|
||||
igsfb_freq_latch(dc);
|
||||
|
||||
igs_ext_write(iot, ioh, IGS_EXT_VOVFL, overflow);
|
||||
igs_ext_write(iot, ioh, IGS_EXT_SEQ_MISC, bytes_per_pixel);
|
||||
igs_ext_write(iot, ioh, IGS_EXT_SEQ_MISC, seq_mode);
|
||||
igs_ext_write(iot, ioh, 0x14, memfetch & 0xff);
|
||||
igs_ext_write(iot, ioh, 0x15,
|
||||
((memfetch & 0x300) >> 8) | ((hoffset & 0x300) >> 4));
|
||||
igs_ext_write(iot, ioh, IGS_EXT_SPRITE_CTL, 0x00);
|
||||
|
||||
/* finally set the dot clock */
|
||||
igsfb_calc_pll(mode->dot_clock, &m, &n, &p, 2047, 255, 7, IGS_MIN_VCO);
|
||||
@ -613,10 +639,30 @@ igsfb_set_mode(struct igsfb_devconfig *dc, const struct videomode *mode,
|
||||
igsfb_freq_latch(dc);
|
||||
DPRINTF("clock: %d\n", IGS_CLOCK(m, n, p));
|
||||
|
||||
if (dc->dc_id > 0x2000) {
|
||||
/* we have a blitter, so configure it as well */
|
||||
bus_space_write_1(dc->dc_iot, dc->dc_coph, IGS_COP_MAP_FMT_REG,
|
||||
bytes_per_pixel - 1);
|
||||
bus_space_write_2(dc->dc_iot, dc->dc_coph,
|
||||
IGS_COP_SRC_MAP_WIDTH_REG, dc->dc_width - 1);
|
||||
bus_space_write_2(dc->dc_iot, dc->dc_coph,
|
||||
IGS_COP_DST_MAP_WIDTH_REG, dc->dc_width - 1);
|
||||
}
|
||||
|
||||
/* re-init the cursor data address too */
|
||||
croffset = dc->dc_vmemsz - IGS_CURSOR_DATA_SIZE;
|
||||
croffset >>= 10; /* bytes -> kilobytes */
|
||||
igs_ext_write(dc->dc_iot, dc->dc_ioh,
|
||||
IGS_EXT_SPRITE_DATA_LO, croffset & 0xff);
|
||||
igs_ext_write(dc->dc_iot, dc->dc_ioh,
|
||||
IGS_EXT_SPRITE_DATA_HI, (croffset >> 8) & 0xf);
|
||||
|
||||
dc->dc_width = mode->hdisplay;
|
||||
dc->dc_height = mode->vdisplay;
|
||||
dc->dc_depth = depth;
|
||||
dc->dc_stride = dc->dc_width * bytes_per_pixel;
|
||||
dc->dc_stride = dc->dc_width * (depth >> 3);
|
||||
|
||||
igsfb_video_on(dc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: igsfbvar.h,v 1.18 2009/11/11 17:01:17 macallan Exp $ */
|
||||
/* $NetBSD: igsfbvar.h,v 1.19 2009/11/18 21:59:38 macallan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002, 2003 Valeriy E. Ushakov
|
||||
@ -78,6 +78,8 @@ struct igsfb_devconfig {
|
||||
|
||||
/* resolution */
|
||||
int dc_width, dc_height, dc_depth, dc_stride;
|
||||
int dc_maxdepth;
|
||||
const struct videomode *dc_mode;
|
||||
|
||||
char dc_modestring[128];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user