Module Name: src Committed By: macallan Date: Wed Nov 18 21:59:38 UTC 2009
Modified Files: src/sys/dev/ic: igsfb.c igsfb_subr.c igsfbvar.h Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.46 -r1.47 src/sys/dev/ic/igsfb.c cvs rdiff -u -r1.11 -r1.12 src/sys/dev/ic/igsfb_subr.c cvs rdiff -u -r1.18 -r1.19 src/sys/dev/ic/igsfbvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/ic/igsfb.c diff -u src/sys/dev/ic/igsfb.c:1.46 src/sys/dev/ic/igsfb.c:1.47 --- src/sys/dev/ic/igsfb.c:1.46 Wed Nov 11 17:01:17 2009 +++ src/sys/dev/ic/igsfb.c Wed Nov 18 21:59:38 2009 @@ -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 @@ ? "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 @@ #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_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 @@ 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) Index: src/sys/dev/ic/igsfb_subr.c diff -u src/sys/dev/ic/igsfb_subr.c:1.11 src/sys/dev/ic/igsfb_subr.c:1.12 --- src/sys/dev/ic/igsfb_subr.c:1.11 Wed Nov 18 06:10:50 2009 +++ src/sys/dev/ic/igsfb_subr.c Wed Nov 18 21:59:38 2009 @@ -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 @@ 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 @@ } 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 @@ 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 @@ ((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 @@ /* 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_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_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); } Index: src/sys/dev/ic/igsfbvar.h diff -u src/sys/dev/ic/igsfbvar.h:1.18 src/sys/dev/ic/igsfbvar.h:1.19 --- src/sys/dev/ic/igsfbvar.h:1.18 Wed Nov 11 17:01:17 2009 +++ src/sys/dev/ic/igsfbvar.h Wed Nov 18 21:59:38 2009 @@ -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 @@ /* resolution */ int dc_width, dc_height, dc_depth, dc_stride; + int dc_maxdepth; + const struct videomode *dc_mode; char dc_modestring[128];