Module Name: src Committed By: macallan Date: Wed May 4 23:36:21 UTC 2011
Modified Files: src/sys/dev/pci: machfb.c Log Message: add support for (ancient) Mach64 CX and GX, while there make sure the visible vram area starts at the same offset as the area we're going to draw into - zero that is. from David Riley To generate a diff of this commit: cvs rdiff -u -r1.63 -r1.64 src/sys/dev/pci/machfb.c 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/pci/machfb.c diff -u src/sys/dev/pci/machfb.c:1.63 src/sys/dev/pci/machfb.c:1.64 --- src/sys/dev/pci/machfb.c:1.63 Sat Jan 22 15:14:28 2011 +++ src/sys/dev/pci/machfb.c Wed May 4 23:36:21 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: machfb.c,v 1.63 2011/01/22 15:14:28 cegger Exp $ */ +/* $NetBSD: machfb.c,v 1.64 2011/05/04 23:36:21 macallan Exp $ */ /* * Copyright (c) 2002 Bang Jun-Young @@ -34,7 +34,7 @@ #include <sys/cdefs.h> __KERNEL_RCSID(0, - "$NetBSD: machfb.c,v 1.63 2011/01/22 15:14:28 cegger Exp $"); + "$NetBSD: machfb.c,v 1.64 2011/05/04 23:36:21 macallan Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -169,6 +169,8 @@ uint16_t chip_id; uint32_t ramdac_freq; } const mach64_info[] = { + { PCI_PRODUCT_ATI_MACH64_GX, 135000 }, + { PCI_PRODUCT_ATI_MACH64_CX, 135000 }, { PCI_PRODUCT_ATI_MACH64_CT, 135000 }, { PCI_PRODUCT_ATI_RAGE_PRO_AGP, 230000 }, { PCI_PRODUCT_ATI_RAGE_PRO_AGP1X, 230000 }, @@ -184,12 +186,11 @@ { PCI_PRODUCT_ATI_RAGE_IIC_AGP_B, 230000 }, { PCI_PRODUCT_ATI_RAGE_IIC_AGP_P, 230000 }, #if 0 - { PCI_PRODUCT_ATI_RAGE_LT_PRO_AGP, 230000 }, { PCI_PRODUCT_ATI_RAGE_MOB_M3_PCI, 230000 }, { PCI_PRODUCT_ATI_RAGE_MOB_M3_AGP, 230000 }, { PCI_PRODUCT_ATI_RAGE_MOBILITY, 230000 }, - { PCI_PRODUCT_ATI_RAGE_LT_PRO, 230000 }, #endif + { PCI_PRODUCT_ATI_RAGE_LT_PRO_AGP, 230000 }, { PCI_PRODUCT_ATI_RAGE_LT_PRO, 230000 }, { PCI_PRODUCT_ATI_RAGE_LT, 230000 }, { PCI_PRODUCT_ATI_RAGE_LT_PRO_PCI, 230000 }, @@ -201,6 +202,11 @@ static int mach64_chip_id, mach64_chip_rev; static struct videomode default_mode = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; +static const char *mach64_gx_memtype_names[] = { + "DRAM", "VRAM", "VRAM", "DRAM", + "DRAM", "VRAM", "VRAM", "(unknown type)" +}; + static const char *mach64_memtype_names[] = { "(N/A)", "DRAM", "EDO DRAM", "EDO DRAM", "SDRAM", "SGRAM", "WRAM", "(unknown type)" @@ -507,7 +513,9 @@ prop_data_t edid_data; const struct videomode *mode = NULL; char devinfo[256]; - int bar, id; + int bar, id, expected_id; + int is_gx; + const char **memtype_names; struct wsemuldisplaydev_attach_args aa; long defattr; int setmode, width, height; @@ -566,6 +574,13 @@ } sc->sc_aperture = (void *)bus_space_vaddr(sc->sc_memt, sc->sc_memh); + /* If the BAR was never mapped, fix it up in MMIO. */ + if(sc->sc_regsize == 0) { + sc->sc_regsize = MACH64_REG_SIZE; + sc->sc_regbase = sc->sc_aperbase + MACH64_REG_OFF; + sc->sc_regphys = sc->sc_aperphys + MACH64_REG_OFF; + } + sc->sc_regt = sc->sc_memt; bus_space_subregion(sc->sc_regt, sc->sc_memh, MACH64_REG_OFF, sc->sc_regsize, &sc->sc_regh); @@ -608,19 +623,36 @@ printf("mode: %s\n", mode->name); } } - if (mach64_chip_id == PCI_PRODUCT_ATI_MACH64_CT || - ((mach64_chip_id == PCI_PRODUCT_ATI_MACH64_VT || - mach64_chip_id == PCI_PRODUCT_ATI_RAGE_II) && - (mach64_chip_rev & 0x07) == 0)) - sc->has_dsp = 0; - else - sc->has_dsp = 1; + + is_gx = 0; + switch(mach64_chip_id) { + case PCI_PRODUCT_ATI_MACH64_GX: + case PCI_PRODUCT_ATI_MACH64_CX: + is_gx = 1; + case PCI_PRODUCT_ATI_MACH64_CT: + sc->has_dsp = 0; + break; + case PCI_PRODUCT_ATI_MACH64_VT: + case PCI_PRODUCT_ATI_RAGE_II: + if((mach64_chip_rev & 0x07) == 0) { + sc->has_dsp = 0; + break; + } + /* Otherwise fall through. */ + default: + sc->has_dsp = 1; + } + + memtype_names = is_gx ? mach64_gx_memtype_names : mach64_memtype_names; sc->memsize = mach64_get_memsize(sc); if (sc->memsize == 8192) /* The last page is used as register aperture. */ sc->memsize -= 4; - sc->memtype = regr(sc, CONFIG_STAT0) & 0x07; + if(is_gx) + sc->memtype = (regr(sc, CONFIG_STAT0) >> 3) & 0x07; + else + sc->memtype = regr(sc, CONFIG_STAT0) & 0x07; /* XXX is there any way to calculate reference frequency from known values? */ @@ -649,14 +681,26 @@ aprint_normal_dev(sc->sc_dev, "%ld KB %s %d.%d MHz, maximum RAMDAC clock %d MHz\n", (u_long)sc->memsize, - mach64_memtype_names[sc->memtype], + memtype_names[sc->memtype], sc->mem_freq / 1000, sc->mem_freq % 1000, sc->ramdac_freq / 1000); id = regr(sc, CONFIG_CHIP_ID) & 0xffff; - if (id != mach64_chip_id) { + switch(mach64_chip_id) { + case PCI_PRODUCT_ATI_MACH64_GX: + expected_id = 0x00d7; + break; + case PCI_PRODUCT_ATI_MACH64_CX: + expected_id = 0x0057; + break; + default: + /* Most chip IDs match their PCI product ID. */ + expected_id = mach64_chip_id; + } + + if (id != expected_id) { aprint_error_dev(sc->sc_dev, - "chip ID mismatch, 0x%x != 0x%x\n", id, mach64_chip_id); + "chip ID mismatch, 0x%x != 0x%x\n", id, expected_id); return; } @@ -706,11 +750,6 @@ if (setmode) mach64_modeswitch(sc, sc->sc_my_mode); -#if 0 - mach64_adjust_frame(0, 0); - if (sc->bits_per_pixel == 8) - mach64_init_lut(sc); -#endif aprint_normal_dev(sc->sc_dev, "initial resolution %dx%d at %d bpp\n", @@ -732,6 +771,7 @@ machfb_blank(sc, 0); /* unblank the screen */ if (sc->sc_console) { + vcons_init_screen(&sc->vd, &mach64_console_screen, 1, &defattr); mach64_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; @@ -741,6 +781,7 @@ mach64_defaultscreen.capabilities = ri->ri_caps; mach64_defaultscreen.nrows = ri->ri_rows; mach64_defaultscreen.ncols = ri->ri_cols; + wsdisplay_cnattach(&mach64_defaultscreen, ri, 0, 0, defattr); vcons_replay_msgbuf(&mach64_console_screen); } else { @@ -1045,6 +1086,9 @@ regw(sc, DST_OFF_PITCH, (pitch_value / 8) << 22); + /* make sure the visible area starts where we're going to draw */ + regw(sc, CRTC_OFF_PITCH, (sc->virt_x >> 3) << 22); + regw(sc, DST_Y_X, 0); regw(sc, DST_HEIGHT, 0); regw(sc, DST_BRES_ERR, 0); @@ -1090,13 +1134,13 @@ wait_for_fifo(sc, 2); switch (sc->bits_per_pixel) { case 8: - regw(sc, DP_PIX_WIDTH, HOST_8BPP | SRC_8BPP | DST_8BPP); + regw(sc, DP_PIX_WIDTH, HOST_1BPP | SRC_8BPP | DST_8BPP); regw(sc, DP_CHAIN_MASK, DP_CHAIN_8BPP); /* We want 8 bit per channel */ regw(sc, DAC_CNTL, regr(sc, DAC_CNTL) | DAC_8BIT_EN); break; case 32: - regw(sc, DP_PIX_WIDTH, HOST_32BPP | SRC_32BPP | DST_32BPP); + regw(sc, DP_PIX_WIDTH, HOST_1BPP | SRC_32BPP | DST_32BPP); regw(sc, DP_CHAIN_MASK, DP_CHAIN_32BPP); regw(sc, DAC_CNTL, regr(sc, DAC_CNTL) | DAC_8BIT_EN); break; @@ -1610,7 +1654,7 @@ int shift = 0; int reg = 0; - for (i=0;i<count;i++) { + for (i = 0; i < count; i++) { bork = data[i]; latch |= (bork << shift); if (shift == 24) {