Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pci some preparations for mode setting support and s...



details:   https://anonhg.NetBSD.org/src/rev/d714f8bb4ac1
branches:  trunk
changeset: 781419:d714f8bb4ac1
user:      macallan <macallan%NetBSD.org@localhost>
date:      Wed Sep 05 01:48:39 2012 +0000

description:
some preparations for mode setting support and such:
- DDC2 support, so far only used for WSDISPLAYIO_GET_EDID
- fix 8 bit support, use packed mode for some extra speed
- pm2 and pm2v have different DACs, deal with it where appropriate

diffstat:

 sys/dev/pci/pm2fb.c |  251 ++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 226 insertions(+), 25 deletions(-)

diffs (truncated from 405 to 300 lines):

diff -r 0ecae6173ddc -r d714f8bb4ac1 sys/dev/pci/pm2fb.c
--- a/sys/dev/pci/pm2fb.c       Wed Sep 05 01:32:01 2012 +0000
+++ b/sys/dev/pci/pm2fb.c       Wed Sep 05 01:48:39 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pm2fb.c,v 1.14 2012/05/23 18:39:30 macallan Exp $      */
+/*     $NetBSD: pm2fb.c,v 1.15 2012/09/05 01:48:39 macallan Exp $      */
 
 /*
  * Copyright (c) 2009 Michael Lorenz
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pm2fb.c,v 1.14 2012/05/23 18:39:30 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pm2fb.c,v 1.15 2012/09/05 01:48:39 macallan Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -40,6 +40,7 @@
 #include <sys/malloc.h>
 #include <sys/lwp.h>
 #include <sys/kauth.h>
+#include <sys/atomic.h>
 
 #include <dev/videomode/videomode.h>
 
@@ -97,9 +98,12 @@
        u_char sc_cmap_blue[256];
        /* engine stuff */
        uint32_t sc_pprod;
+       int sc_is_pm2;
        /* i2c stuff */
        struct i2c_controller sc_i2c;
        uint8_t sc_edid_data[128];
+       struct edid_info sc_ei;
+       struct videomode *sc_videomode;
 };
 
 static int     pm2fb_match(device_t, cfdata_t, void *);
@@ -174,6 +178,13 @@
        }
 };
 
+#if 0
+/* mode setting stuff */
+static int pm2fb_set_pll(struct pm2fb_softc *, int);
+static uint8_t pm2fb_read_dac(struct pm2fb_softc *, int);
+static void pm2fb_write_dac(struct pm2fb_softc *, int, uint8_t);
+#endif
+
 static inline void
 pm2fb_wait(struct pm2fb_softc *sc, int slots)
 {
@@ -236,7 +247,7 @@
        sc->sc_memt = pa->pa_memt;
        sc->sc_iot = pa->pa_iot;
        sc->sc_dev = self;
-
+       sc->sc_is_pm2 = (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_3DLABS_PERMEDIA2);
        pci_aprint_devinfo(pa, NULL);
 
        /* fill in parameters from properties */
@@ -257,6 +268,10 @@
         * don't look at the linebytes property - The Raptor firmware lies
         * about it. Get it from width * depth >> 3 instead.
         */
+
+#if 0
+       sc->sc_depth = 8;
+#endif
        sc->sc_stride = sc->sc_width * (sc->sc_depth >> 3);
 
        prop_dictionary_get_bool(dict, "is_console", &is_console);
@@ -296,6 +311,11 @@
            &pm2fb_accessops);
        sc->vd.init_screen = pm2fb_init_screen;
 
+#if 0
+       pm2fb_write_dac(sc, PM2V_DAC_PIXEL_SIZE, PM2V_PS_8BIT);
+       pm2fb_write_dac(sc, PM2V_DAC_COLOR_FORMAT, PM2V_DAC_PALETTE);
+#endif
+
        /* init engine here */
        pm2fb_init(sc);
 
@@ -328,8 +348,7 @@
        } else {
                if (sc->sc_console_screen.scr_ri.ri_rows == 0) {
                        /* do some minimal setup to avoid weirdnesses later */
-                       vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
-                           &defattr);
+                       vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1, &defattr);
                }
        }
 
@@ -575,6 +594,44 @@
        return 0;
 }
 
+#if 0
+static uint8_t
+pm2fb_read_dac(struct pm2fb_softc *sc, int reg)
+{
+       if (sc->sc_is_pm2) {
+               bus_space_write_1(sc->sc_memt, sc->sc_regh,
+                   PM2_DAC_PAL_WRITE_IDX, reg);
+               return bus_space_read_1(sc->sc_memt, sc->sc_regh,
+                   PM2_DAC_INDEX_DATA);
+       } else {
+               bus_space_write_1(sc->sc_memt, sc->sc_regh,
+                   PM2V_DAC_INDEX_LOW, reg & 0xff);
+               bus_space_write_1(sc->sc_memt, sc->sc_regh,
+                   PM2V_DAC_INDEX_HIGH, (reg >> 8) & 0xff);
+               return bus_space_read_1(sc->sc_memt, sc->sc_regh,
+                   PM2V_DAC_INDEX_DATA);
+       }       
+}
+
+static void
+pm2fb_write_dac(struct pm2fb_softc *sc, int reg, uint8_t data)
+{
+       if (sc->sc_is_pm2) {
+               bus_space_write_1(sc->sc_memt, sc->sc_regh,
+                   PM2_DAC_PAL_WRITE_IDX, reg);
+               bus_space_write_1(sc->sc_memt, sc->sc_regh,
+                   PM2_DAC_INDEX_DATA, data);
+       } else {
+               bus_space_write_1(sc->sc_memt, sc->sc_regh,
+                   PM2V_DAC_INDEX_LOW, reg & 0xff);
+               bus_space_write_1(sc->sc_memt, sc->sc_regh,
+                   PM2V_DAC_INDEX_HIGH, (reg >> 8) & 0xff);
+               bus_space_write_1(sc->sc_memt, sc->sc_regh,
+                   PM2V_DAC_INDEX_DATA, data);
+       }       
+}
+#endif
+
 static void
 pm2fb_init(struct pm2fb_softc *sc)
 {
@@ -621,7 +678,7 @@
            sc->sc_pprod);
        bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_TEXMAP_FORMAT, 
            sc->sc_pprod);
-       pm2fb_wait(sc, 8);
+       pm2fb_wait(sc, 9);
        bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_DY, 1 << 16);
        bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_DXDOM, 0);
        bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_STARTXDOM, 0);
@@ -631,7 +688,22 @@
        bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_SCISSOR_MINYX, 0);
        bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_SCISSOR_MAXYX,
            0x0fff0fff);
+       switch(sc->sc_depth) {
+               case 8:
+                       bus_space_write_4(sc->sc_memt, sc->sc_regh,
+                           PM2_RE_PIXEL_SIZE, PM2PS_8BIT);
+                       break;
+               case 16:
+                       bus_space_write_4(sc->sc_memt, sc->sc_regh,
+                           PM2_RE_PIXEL_SIZE, PM2PS_16BIT);
+                       break;
+               case 32:
+                       bus_space_write_4(sc->sc_memt, sc->sc_regh,
+                           PM2_RE_PIXEL_SIZE, PM2PS_32BIT);
+                       break;
+       }
        pm2fb_flush_engine(sc);
+       DPRINTF("pixel size: %08x\n", bus_space_read_4(sc->sc_memt, sc->sc_regh, PM2_RE_PIXEL_SIZE));
 }
 
 static void
@@ -659,6 +731,7 @@
     int wi, int he, int rop)
 {
        uint32_t dir = 0;
+       int rxs, rxd, rwi;
 
        if (yd <= ys) {
                dir |= PM2RE_INC_Y;
@@ -666,24 +739,60 @@
        if (xd <= xs) {
                dir |= PM2RE_INC_X;
        }
-       pm2fb_wait(sc, 7);
+       pm2fb_wait(sc, 8);
        bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_DDA_MODE, 0);
        bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_MODE, 0);
-       if (rop == 3) {
-               bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_CONFIG,
-                   PM2RECFG_READ_SRC | PM2RECFG_WRITE_EN | PM2RECFG_ROP_EN |
-                   PM2RECFG_PACKED | (rop << 6));
+       if (sc->sc_depth == 8) {
+               /*
+                * use packed mode for some extra speed
+                * this copies 32bit quantities even in 8 bit mode, so we need
+                * to adjust for cases where the lower two bits in source and
+                * destination X don't align, and/or where the width isn't a
+                * multiple of 4
+                */
+               if (rop == 3) {
+                       bus_space_write_4(sc->sc_memt, sc->sc_regh,
+                           PM2_RE_CONFIG,
+                           PM2RECFG_READ_SRC | PM2RECFG_WRITE_EN |
+                           PM2RECFG_ROP_EN | PM2RECFG_PACKED | (rop << 6));
+               } else {
+                       bus_space_write_4(sc->sc_memt, sc->sc_regh,
+                           PM2_RE_CONFIG,
+                           PM2RECFG_READ_SRC | PM2RECFG_READ_DST |
+                           PM2RECFG_WRITE_EN | PM2RECFG_PACKED |
+                           PM2RECFG_ROP_EN | (rop << 6));
+               }
+               rxs = xs >> 2;
+               rxd = xd >> 2;
+               rwi = wi >> 2;
+               /* adjust for non-aligned x */
+               bus_space_write_4(sc->sc_memt, sc->sc_regh,
+                   PM2_RE_PACKEDDATA_LIMIT,
+                   (xd << 16) | (xd + wi) | (((xd - xs) & 3) << 29));
        } else {
-               bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_CONFIG,
-                   PM2RECFG_READ_SRC | PM2RECFG_READ_DST | PM2RECFG_WRITE_EN |
-                   PM2RECFG_PACKED | PM2RECFG_ROP_EN | (rop << 6));
-       }
+               /* we're in 16 or 32bit mode */
+               if (rop == 3) {
+                       bus_space_write_4(sc->sc_memt, sc->sc_regh,
+                           PM2_RE_CONFIG,
+                           PM2RECFG_READ_SRC | PM2RECFG_WRITE_EN |
+                           PM2RECFG_ROP_EN | PM2RECFG_PACKED | (rop << 6));
+               } else {
+                       bus_space_write_4(sc->sc_memt, sc->sc_regh,
+                           PM2_RE_CONFIG,
+                           PM2RECFG_READ_SRC | PM2RECFG_READ_DST |
+                           PM2RECFG_WRITE_EN | PM2RECFG_PACKED |
+                           PM2RECFG_ROP_EN | (rop << 6));
+               }
+               rxs = xs;
+               rxd = xd;
+               rwi = wi;
+       }               
        bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_RECT_START,
-           (yd << 16) | xd);
+           (yd << 16) | rxd);
        bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_RECT_SIZE,
-           (he << 16) | wi);
+           (he << 16) | rwi);
        bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_SOURCE_DELTA,
-           (((ys - yd) & 0xfff) << 16) | ((xs - xd) & 0xfff));
+           (((ys - yd) & 0xfff) << 16) | ((rxs - rxd) & 0xfff));
        bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_RENDER,
            PM2RE_RECTANGLE | dir);
 }
@@ -890,13 +999,14 @@
        }
 }
 
+#define MODE_IS_VALID(m) (((m)->hdisplay < 2048) && ((m)->dot_clock < 230000))
 static void
 pm2_setup_i2c(struct pm2fb_softc *sc)
 {
+       int i;
 #ifdef PM2FB_DEBUG
-       struct edid_info ei;
+       int j;
 #endif
-       int i;
 
        /* Fill in the i2c tag */
        sc->sc_i2c.ic_cookie = sc;
@@ -912,7 +1022,6 @@
        DPRINTF("data: %08x\n", bus_space_read_4(sc->sc_memt, sc->sc_regh,
                PM2_DISPLAY_DATA));
 
-       /* make sure we're in i2c mode */
        bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_DISPLAY_DATA, 0);
 
        /* zero out the EDID buffer */
@@ -920,11 +1029,67 @@
 
        /* Some monitors don't respond first time */
        i = 0;
-       while (sc->sc_edid_data[1] == 0 && i++ < 3)
+       while (sc->sc_edid_data[1] == 0 && i < 10) {
                ddc_read_edid(&sc->sc_i2c, sc->sc_edid_data, 128);
+               printf("\n");
+               i++;
+       }
+#ifdef PM2FB_DEBUG
+       printf("i = %d\n", i);
+       for (i = 0; i < 128; i += 16) {
+               printf("%02x:", i);
+               for (j = 0; j < 16; j++)
+                       printf(" %02x", sc->sc_edid_data[i + j]);
+               printf("\n");
+       }
+#endif
+#if 0
+       if (edid_parse(&sc->sc_edid_data[0], &sc->sc_ei) != -1) {
 #ifdef PM2FB_DEBUG



Home | Main Index | Thread Index | Old Index