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