Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ic Make colour depths higher than 8bit work in X.



details:   https://anonhg.NetBSD.org/src/rev/ad2a7fdbf641
branches:  trunk
changeset: 749136:ad2a7fdbf641
user:      macallan <macallan%NetBSD.org@localhost>
date:      Wed Nov 18 21:59:38 2009 +0000

description:
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.

diffstat:

 sys/dev/ic/igsfb.c      |  18 ++++++++---
 sys/dev/ic/igsfb_subr.c |  76 +++++++++++++++++++++++++++++++++++++++---------
 sys/dev/ic/igsfbvar.h   |   4 +-
 3 files changed, 77 insertions(+), 21 deletions(-)

diffs (259 lines):

diff -r 00b098238ade -r ad2a7fdbf641 sys/dev/ic/igsfb.c
--- a/sys/dev/ic/igsfb.c        Wed Nov 18 21:04:12 2009 +0000
+++ b/sys/dev/ic/igsfb.c        Wed Nov 18 21:59:38 2009 +0000
@@ -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)
diff -r 00b098238ade -r ad2a7fdbf641 sys/dev/ic/igsfb_subr.c
--- a/sys/dev/ic/igsfb_subr.c   Wed Nov 18 21:04:12 2009 +0000
+++ b/sys/dev/ic/igsfb_subr.c   Wed Nov 18 21:59:38 2009 +0000
@@ -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);
 }
 
 
diff -r 00b098238ade -r ad2a7fdbf641 sys/dev/ic/igsfbvar.h
--- a/sys/dev/ic/igsfbvar.h     Wed Nov 18 21:04:12 2009 +0000
+++ b/sys/dev/ic/igsfbvar.h     Wed Nov 18 21:59:38 2009 +0000
@@ -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];
 



Home | Main Index | Thread Index | Old Index