summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/fb/machfb.c1490
-rw-r--r--sys/dev/fb/machfbreg.h458
2 files changed, 1948 insertions, 0 deletions
diff --git a/sys/dev/fb/machfb.c b/sys/dev/fb/machfb.c
new file mode 100644
index 0000000..2fc32ef
--- /dev/null
+++ b/sys/dev/fb/machfb.c
@@ -0,0 +1,1490 @@
+/*-
+ * Copyright (c) 2002 Bang Jun-Young
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * from: NetBSD: machfb.c,v 1.23 2005/03/07 21:45:24 martin Exp
+ */
+/*-
+ * Copyright (c) 2005 Marius Strobl <marius@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Driver for ATI Mach64 graphics chips. Some code is derived from the
+ * ATI Rage Pro and Derivatives Programmer's Guide.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/consio.h>
+#include <sys/eventhandler.h>
+#include <sys/fbio.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/resource.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/bus_private.h>
+#include <machine/ofw_machdep.h>
+#include <machine/resource.h>
+#include <machine/sc_machdep.h>
+
+#include <sys/rman.h>
+
+#include <dev/fb/fbreg.h>
+#include <dev/fb/gallant12x22.h>
+#include <dev/fb/machfbreg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+#include <dev/syscons/syscons.h>
+
+/* #define MACHFB_DEBUG */
+
+#define MACHFB_DRIVER_NAME "machfb"
+
+#define MACH64_REG_OFF 0x7ffc00
+#define MACH64_REG_SIZE 1024
+
+struct machfb_softc {
+ video_adapter_t sc_va; /* must be first */
+
+ phandle_t sc_node;
+ uint16_t sc_chip_id;
+ uint8_t sc_chip_rev;
+
+ int sc_memrid;
+ int sc_viorid;
+ int sc_vmemrid;
+ struct resource *sc_memres;
+ struct resource *sc_viores;
+ struct resource *sc_vmemres;
+ bus_space_tag_t sc_memt;
+ bus_space_tag_t sc_regt;
+ bus_space_tag_t sc_viot;
+ bus_space_tag_t sc_vmemt;
+ bus_space_handle_t sc_memh;
+ bus_space_handle_t sc_regh;
+ bus_space_handle_t sc_vioh;
+ bus_space_handle_t sc_vmemh;
+
+ int sc_height;
+ int sc_width;
+ int sc_depth;
+ int sc_xmargin;
+ int sc_ymargin;
+
+ size_t sc_memsize;
+ int sc_memtype;
+ int sc_mem_freq;
+ int sc_ramdac_freq;
+ int sc_ref_freq;
+
+ int sc_ref_div;
+ int sc_mclk_post_div;
+ int sc_mclk_fb_div;
+
+ int sc_dacw;
+ uint8_t sc_cmap_red[256];
+ uint8_t sc_cmap_green[256];
+ uint8_t sc_cmap_blue[256];
+
+ u_char *sc_font;
+ int sc_cbwidth;
+ vm_offset_t sc_curoff;
+
+ int sc_draw_cache;
+#define MACHFB_DRAW_CHAR (1 << 0)
+#define MACHFB_DRAW_FILLRECT (1 << 1)
+
+ int sc_flags;
+#define MACHFB_CONSOLE (1 << 0)
+#define MACHFB_CUREN (1 << 1)
+#define MACHFB_DSP (1 << 2)
+};
+
+static struct {
+ uint16_t chip_id;
+ const char *name;
+ uint32_t ramdac_freq;
+} machfb_info[] = {
+ { ATI_MACH64_CT, "ATI Mach64 CT", 135000 },
+ { ATI_RAGE_PRO_AGP, "ATI 3D Rage Pro (AGP)", 230000 },
+ { ATI_RAGE_PRO_AGP1X, "ATI 3D Rage Pro (AGP 1x)", 230000 },
+ { ATI_RAGE_PRO_PCI_B, "ATI 3D Rage Pro Turbo", 230000 },
+ { ATI_RAGE_XC_PCI66, "ATI Rage XL (PCI66)", 230000 },
+ { ATI_RAGE_XL_AGP, "ATI Rage XL (AGP)", 230000 },
+ { ATI_RAGE_XC_AGP, "ATI Rage XC (AGP)", 230000 },
+ { ATI_RAGE_XL_PCI66, "Rage XL (PCI66)", 230000 },
+ { ATI_RAGE_PRO_PCI_P, "ATI 3D Rage Pro", 230000 },
+ { ATI_RAGE_PRO_PCI_L, "ATI 3D Rage Pro (limited 3D)", 230000 },
+ { ATI_RAGE_XL_PCI, "ATI Rage XL", 230000 },
+ { ATI_RAGE_XC_PCI, "ATI Rage XC", 230000 },
+ { ATI_RAGE_II, "ATI 3D Rage I/II", 135000 },
+ { ATI_RAGE_IIP, "ATI 3D Rage II+", 200000 },
+ { ATI_RAGE_IIC_PCI, "ATI 3D Rage IIC", 230000 },
+ { ATI_RAGE_IIC_AGP_B, "ATI 3D Rage IIC (AGP)", 230000 },
+ { ATI_RAGE_IIC_AGP_P, "ATI 3D Rage IIC (AGP)", 230000 },
+ { ATI_RAGE_LT_PRO_AGP, "ATI 3D Rage LT Pro (AGP 133MHz)", 230000 },
+ { ATI_RAGE_MOB_M3_PCI, "ATI Rage Mobility M3", 230000 },
+ { ATI_RAGE_MOB_M3_AGP, "ATI Rage Mobility M3 (AGP)", 230000 },
+ { ATI_RAGE_LT, "ATI 3D Rage LT", 230000 },
+ { ATI_RAGE_LT_PRO_PCI, "ATI 3D Rage LT Pro", 230000 },
+ { ATI_RAGE_MOBILITY, "ATI Rage Mobility", 230000 },
+ { ATI_RAGE_L_MOBILITY, "ATI Rage L Mobility", 230000 },
+ { ATI_RAGE_LT_PRO, "ATI 3D Rage LT Pro", 230000 },
+ { ATI_RAGE_LT_PRO2, "ATI 3D Rage LT Pro", 230000 },
+ { ATI_RAGE_MOB_M1_PCI, "ATI Rage Mobility M1 (PCI)", 230000 },
+ { ATI_RAGE_L_MOB_M1_PCI, "ATI Rage L Mobility (PCI)", 230000 },
+ { ATI_MACH64_VT, "ATI Mach64 VT", 170000 },
+ { ATI_MACH64_VTB, "ATI Mach64 VTB", 200000 },
+ { ATI_MACH64_VT4, "ATI Mach64 VT4", 230000 }
+};
+
+static struct machfb_cmap {
+ uint8_t red;
+ uint8_t green;
+ uint8_t blue;
+} machfb_default_cmap[16] = {
+ {0x00, 0x00, 0x00}, /* black */
+ {0x00, 0x00, 0xff}, /* blue */
+ {0x00, 0xff, 0x00}, /* green */
+ {0x00, 0xc0, 0xc0}, /* cyan */
+ {0xff, 0x00, 0x00}, /* red */
+ {0xc0, 0x00, 0xc0}, /* magenta */
+ {0xc0, 0xc0, 0x00}, /* brown */
+ {0xc0, 0xc0, 0xc0}, /* light grey */
+ {0x80, 0x80, 0x80}, /* dark grey */
+ {0x80, 0x80, 0xff}, /* light blue */
+ {0x80, 0xff, 0x80}, /* light green */
+ {0x80, 0xff, 0xff}, /* light cyan */
+ {0xff, 0x80, 0x80}, /* light red */
+ {0xff, 0x80, 0xff}, /* light magenta */
+ {0xff, 0xff, 0x80}, /* yellow */
+ {0xff, 0xff, 0xff} /* white */
+};
+
+static u_char machfb_mouse_pointer_bits[64][8] = {
+ { 0x00, 0x00, }, /* ............ */
+ { 0x80, 0x00, }, /* *........... */
+ { 0xc0, 0x00, }, /* **.......... */
+ { 0xe0, 0x00, }, /* ***......... */
+ { 0xf0, 0x00, }, /* ****........ */
+ { 0xf8, 0x00, }, /* *****....... */
+ { 0xfc, 0x00, }, /* ******...... */
+ { 0xfe, 0x00, }, /* *******..... */
+ { 0xff, 0x00, }, /* ********.... */
+ { 0xff, 0x80, }, /* *********... */
+ { 0xfc, 0xc0, }, /* ******..**.. */
+ { 0xdc, 0x00, }, /* **.***...... */
+ { 0x8e, 0x00, }, /* *...***..... */
+ { 0x0e, 0x00, }, /* ....***..... */
+ { 0x07, 0x00, }, /* .....***.... */
+ { 0x04, 0x00, }, /* .....*...... */
+ { 0x00, 0x00, }, /* ............ */
+ { 0x00, 0x00, }, /* ............ */
+ { 0x00, 0x00, }, /* ............ */
+ { 0x00, 0x00, }, /* ............ */
+ { 0x00, 0x00, }, /* ............ */
+ { 0x00, 0x00, }, /* ............ */
+};
+
+/*
+ * Lookup table to perform a bit-swap of the mouse pointer bits,
+ * map set bits to CUR_CLR0 and unset bits to transparent.
+ */
+static u_char machfb_mouse_pointer_lut[] = {
+ 0xaa, 0x2a, 0x8a, 0x0a, 0xa2, 0x22, 0x82, 0x02,
+ 0xa8, 0x28, 0x88, 0x08, 0xa0, 0x20, 0x80, 0x00
+};
+
+static char *machfb_memtype_names[] = {
+ "(N/A)", "DRAM", "EDO DRAM", "EDO DRAM", "SDRAM", "SGRAM", "WRAM",
+ "(unknown type)"
+};
+
+static struct machfb_softc machfb_softc;
+static struct bus_space_tag machfb_bst_store[1];
+
+static device_probe_t machfb_pci_probe;
+static device_attach_t machfb_pci_attach;
+static device_detach_t machfb_pci_detach;
+
+static device_method_t machfb_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, machfb_pci_probe),
+ DEVMETHOD(device_attach, machfb_pci_attach),
+ DEVMETHOD(device_detach, machfb_pci_detach),
+
+ { 0, 0 }
+};
+
+static driver_t machfb_pci_driver = {
+ MACHFB_DRIVER_NAME,
+ machfb_methods,
+ sizeof(struct machfb_softc),
+};
+
+static devclass_t machfb_devclass;
+
+DRIVER_MODULE(machfb, pci, machfb_pci_driver, machfb_devclass, 0, 0);
+MODULE_DEPEND(machfb, pci, 1, 1, 1);
+
+static void machfb_cursor_enable(struct machfb_softc *, int);
+static int machfb_cursor_install(struct machfb_softc *);
+static int machfb_get_memsize(struct machfb_softc *);
+static void machfb_reset_engine(struct machfb_softc *);
+static void machfb_init_engine(struct machfb_softc *);
+#if 0
+static void machfb_adjust_frame(struct machfb_softc *, int, int);
+#endif
+static void machfb_putpalreg(struct machfb_softc *, uint8_t, uint8_t, uint8_t,
+ uint8_t);
+static void machfb_shutdown_final(void *v);
+static void machfb_shutdown_reset(void *v);
+
+static int machfb_configure(int flags);
+
+static vi_probe_t machfb_probe;
+static vi_init_t machfb_init;
+static vi_get_info_t machfb_get_info;
+static vi_query_mode_t machfb_query_mode;
+static vi_set_mode_t machfb_set_mode;
+static vi_save_font_t machfb_save_font;
+static vi_load_font_t machfb_load_font;
+static vi_show_font_t machfb_show_font;
+static vi_save_palette_t machfb_save_palette;
+static vi_load_palette_t machfb_load_palette;
+static vi_set_border_t machfb_set_border;
+static vi_save_state_t machfb_save_state;
+static vi_load_state_t machfb_load_state;
+static vi_set_win_org_t machfb_set_win_org;
+static vi_read_hw_cursor_t machfb_read_hw_cursor;
+static vi_set_hw_cursor_t machfb_set_hw_cursor;
+static vi_set_hw_cursor_shape_t machfb_set_hw_cursor_shape;
+static vi_blank_display_t machfb_blank_display;
+static vi_mmap_t machfb_mmap;
+static vi_ioctl_t machfb_ioctl;
+static vi_clear_t machfb_clear;
+static vi_fill_rect_t machfb_fill_rect;
+static vi_bitblt_t machfb_bitblt;
+static vi_diag_t machfb_diag;
+static vi_save_cursor_palette_t machfb_save_cursor_palette;
+static vi_load_cursor_palette_t machfb_load_cursor_palette;
+static vi_copy_t machfb_copy;
+static vi_putp_t machfb_putp;
+static vi_putc_t machfb_putc;
+static vi_puts_t machfb_puts;
+static vi_putm_t machfb_putm;
+
+static video_switch_t machfbvidsw = {
+ .probe = machfb_probe,
+ .init = machfb_init,
+ .get_info = machfb_get_info,
+ .query_mode = machfb_query_mode,
+ .set_mode = machfb_set_mode,
+ .save_font = machfb_save_font,
+ .load_font = machfb_load_font,
+ .show_font = machfb_show_font,
+ .save_palette = machfb_save_palette,
+ .load_palette = machfb_load_palette,
+ .set_border = machfb_set_border,
+ .save_state = machfb_save_state,
+ .load_state = machfb_load_state,
+ .set_win_org = machfb_set_win_org,
+ .read_hw_cursor = machfb_read_hw_cursor,
+ .set_hw_cursor = machfb_set_hw_cursor,
+ .set_hw_cursor_shape = machfb_set_hw_cursor_shape,
+ .blank_display = machfb_blank_display,
+ .mmap = machfb_mmap,
+ .ioctl = machfb_ioctl,
+ .clear = machfb_clear,
+ .fill_rect = machfb_fill_rect,
+ .bitblt = machfb_bitblt,
+ NULL,
+ NULL,
+ .diag = machfb_diag,
+ .save_cursor_palette = machfb_save_cursor_palette,
+ .load_cursor_palette = machfb_load_cursor_palette,
+ .copy = machfb_copy,
+ .putp = machfb_putp,
+ .putc = machfb_putc,
+ .puts = machfb_puts,
+ .putm = machfb_putm
+};
+
+VIDEO_DRIVER(machfb, machfbvidsw, machfb_configure);
+
+extern sc_rndr_sw_t txtrndrsw;
+RENDERER(machfb, 0, txtrndrsw, gfb_set);
+
+RENDERER_MODULE(machfb, gfb_set);
+
+/*
+ * Inline functions for getting access to register aperture.
+ */
+static inline uint32_t regr(struct machfb_softc *, uint32_t);
+static inline uint8_t regrb(struct machfb_softc *, uint32_t);
+static inline void regw(struct machfb_softc *, uint32_t, uint32_t);
+static inline void regwb(struct machfb_softc *, uint32_t, uint8_t);
+static inline void regwb_pll(struct machfb_softc *, uint32_t, uint8_t);
+
+static inline uint32_t
+regr(struct machfb_softc *sc, uint32_t index)
+{
+
+ return bus_space_read_4(sc->sc_regt, sc->sc_regh, index);
+}
+
+static inline uint8_t
+regrb(struct machfb_softc *sc, uint32_t index)
+{
+
+ return bus_space_read_1(sc->sc_regt, sc->sc_regh, index);
+}
+
+static inline void
+regw(struct machfb_softc *sc, uint32_t index, uint32_t data)
+{
+
+ bus_space_write_4(sc->sc_regt, sc->sc_regh, index, data);
+ bus_space_barrier(sc->sc_regt, sc->sc_regh, index, 4,
+ BUS_SPACE_BARRIER_WRITE);
+}
+
+static inline void
+regwb(struct machfb_softc *sc, uint32_t index, uint8_t data)
+{
+
+ bus_space_write_1(sc->sc_regt, sc->sc_regh, index, data);
+ bus_space_barrier(sc->sc_regt, sc->sc_regh, index, 1,
+ BUS_SPACE_BARRIER_WRITE);
+}
+
+static inline void
+regwb_pll(struct machfb_softc *sc, uint32_t index, uint8_t data)
+{
+
+ regwb(sc, CLOCK_CNTL + 1, (index << 2) | PLL_WR_EN);
+ regwb(sc, CLOCK_CNTL + 2, data);
+ regwb(sc, CLOCK_CNTL + 1, (index << 2) & ~PLL_WR_EN);
+}
+
+static inline void
+wait_for_fifo(struct machfb_softc *sc, uint8_t v)
+{
+
+ while ((regr(sc, FIFO_STAT) & 0xffff) > (0x8000 >> v))
+ ;
+}
+
+static inline void
+wait_for_idle(struct machfb_softc *sc)
+{
+
+ wait_for_fifo(sc, 16);
+ while ((regr(sc, GUI_STAT) & 1) != 0)
+ ;
+}
+
+/*
+ * video driver interface
+ */
+static int
+machfb_configure(int flags)
+{
+ struct machfb_softc *sc;
+ phandle_t chosen, output;
+ ihandle_t stdout;
+ bus_addr_t addr;
+ uint32_t id;
+ int i, space;
+
+ sc = &machfb_softc;
+
+ if ((chosen = OF_finddevice("/chosen")) == -1) /* Quis contra nos? */
+ return (0);
+ if (OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) == -1)
+ return (0);
+ if ((output = OF_instance_to_package(stdout)) == -1)
+ return (0);
+ if ((OF_getprop(output, "vendor-id", &id, sizeof(id)) == -1) ||
+ id != ATI_VENDOR)
+ return (0);
+ if (OF_getprop(output, "device-id", &id, sizeof(id)) == -1)
+ return (0);
+ for (i = 0; i < sizeof(machfb_info) / sizeof(machfb_info[0]); i++) {
+ if (id == machfb_info[i].chip_id) {
+ /*
+ * When being called a second time, i.e. during
+ * sc_probe_unit(), just return at this point.
+ * Note that the polarity of the VIO_PROBE_ONLY
+ * flag is somewhat non-intuitive.
+ */
+ if (!(flags & VIO_PROBE_ONLY))
+ goto found;
+ sc->sc_flags = MACHFB_CONSOLE;
+ sc->sc_node = output;
+ sc->sc_chip_id = id;
+ break;
+ }
+ }
+ if (!(sc->sc_flags & MACHFB_CONSOLE))
+ return (0);
+
+ if (OF_getprop(output, "revision-id", &sc->sc_chip_rev,
+ sizeof(sc->sc_chip_rev)) == -1)
+ return (0);
+ if (OF_decode_addr(output, 0, &space, &addr) != 0)
+ return (0);
+ sc->sc_memt = &machfb_bst_store[0];
+ sc->sc_memh = sparc64_fake_bustag(space, addr, sc->sc_memt);
+ sc->sc_regt = sc->sc_memt;
+ bus_space_subregion(sc->sc_regt, sc->sc_memh, MACH64_REG_OFF,
+ MACH64_REG_SIZE, &sc->sc_regh);
+
+ if (machfb_init(0, &sc->sc_va, 0) < 0)
+ return (0);
+
+ found:
+ /* Return number of found adapters. */
+ return (1);
+}
+
+static int
+machfb_probe(int unit, video_adapter_t **adpp, void *arg, int flags)
+{
+
+ return (0);
+}
+
+static int
+machfb_init(int unit, video_adapter_t *adp, int flags)
+{
+ struct machfb_softc *sc;
+ phandle_t options;
+ video_info_t *vi;
+ char buf[32];
+ int i, j;
+
+ sc = (struct machfb_softc *)adp;
+ vi = &adp->va_info;
+
+ if ((regr(sc, CONFIG_CHIP_ID) & 0xffff) != sc->sc_chip_id)
+ return (ENXIO);
+
+ sc->sc_ramdac_freq = 0;
+ for (i = 0; i < sizeof(machfb_info) / sizeof(machfb_info[0]); i++) {
+ if (sc->sc_chip_id == machfb_info[i].chip_id) {
+ sc->sc_ramdac_freq = machfb_info[i].ramdac_freq;
+ break;
+ }
+ }
+ if (sc->sc_ramdac_freq == 0)
+ return (ENXIO);
+ if (sc->sc_chip_id == ATI_RAGE_II && sc->sc_chip_rev & 0x07)
+ sc->sc_ramdac_freq = 170000;
+
+ vid_init_struct(adp, MACHFB_DRIVER_NAME, -1, unit);
+
+ if (OF_getprop(sc->sc_node, "height", &sc->sc_height,
+ sizeof(sc->sc_height)) == -1)
+ return (ENXIO);
+ if (OF_getprop(sc->sc_node, "width", &sc->sc_width,
+ sizeof(sc->sc_width)) == -1)
+ return (ENXIO);
+ if (OF_getprop(sc->sc_node, "depth", &sc->sc_depth,
+ sizeof(sc->sc_depth)) == -1)
+ return (ENXIO);
+ if ((options = OF_finddevice("/options")) == -1)
+ return (ENXIO);
+ if (OF_getprop(options, "screen-#rows", buf, sizeof(buf)) == -1)
+ return (ENXIO);
+ vi->vi_height = strtol(buf, NULL, 10);
+ if (OF_getprop(options, "screen-#columns", buf, sizeof(buf)) == -1)
+ return (ENXIO);
+ vi->vi_width = strtol(buf, NULL, 10);
+ vi->vi_cwidth = 12;
+ vi->vi_cheight = 22;
+ vi->vi_flags = V_INFO_COLOR;
+ vi->vi_mem_model = V_INFO_MM_OTHER;
+
+ sc->sc_draw_cache = -1;
+ sc->sc_font = gallant12x22_data;
+ sc->sc_cbwidth = howmany(vi->vi_cwidth, 8); /* width in bytes */
+ sc->sc_xmargin = (sc->sc_width - (vi->vi_width * vi->vi_cwidth)) / 2;
+ sc->sc_ymargin = (sc->sc_height - (vi->vi_height * vi->vi_cheight)) / 2;
+
+ if (sc->sc_chip_id != ATI_MACH64_CT &&
+ !((sc->sc_chip_id == ATI_MACH64_VT ||
+ sc->sc_chip_id == ATI_RAGE_II) &&
+ (sc->sc_chip_rev & 0x07) == 0))
+ sc->sc_flags |= MACHFB_DSP;
+
+ sc->sc_memsize = machfb_get_memsize(sc);
+ if (sc->sc_memsize == 8192)
+ /* The last page is used as register aperture. */
+ sc->sc_memsize -= 4;
+ sc->sc_memtype = regr(sc, CONFIG_STAT0) & 0x07;
+
+ if ((sc->sc_chip_id >= ATI_RAGE_XC_PCI66 &&
+ sc->sc_chip_id <= ATI_RAGE_XL_PCI66) ||
+ (sc->sc_chip_id >= ATI_RAGE_XL_PCI &&
+ sc->sc_chip_id <= ATI_RAGE_XC_PCI))
+ sc->sc_ref_freq = 29498;
+ else
+ sc->sc_ref_freq = 14318;
+
+ regwb(sc, CLOCK_CNTL + 1, PLL_REF_DIV << 2);
+ sc->sc_ref_div = regrb(sc, CLOCK_CNTL + 2);
+ regwb(sc, CLOCK_CNTL + 1, MCLK_FB_DIV << 2);
+ sc->sc_mclk_fb_div = regrb(sc, CLOCK_CNTL + 2);
+ sc->sc_mem_freq = (2 * sc->sc_ref_freq * sc->sc_mclk_fb_div) /
+ (sc->sc_ref_div * 2);
+ sc->sc_mclk_post_div = (sc->sc_mclk_fb_div * 2 * sc->sc_ref_freq) /
+ (sc->sc_mem_freq * sc->sc_ref_div);
+
+ machfb_init_engine(sc);
+#if 0
+ mach64_adjust_frame(0, 0);
+#endif
+
+ sc->sc_dacw = -1;
+ for (i = 0; i < 16; i++)
+ for (j = 0; j < 16; j++)
+ machfb_putpalreg(sc, (i * 16) + j,
+ machfb_default_cmap[j].red,
+ machfb_default_cmap[j].green,
+ machfb_default_cmap[j].blue);
+
+ machfb_blank_display(adp, V_DISPLAY_BLANK);
+
+ adp->va_flags |= V_ADP_COLOR | V_ADP_BORDER | V_ADP_INITIALIZED;
+ if (vid_register(adp) < 0)
+ return (ENXIO);
+ adp->va_flags |= V_ADP_REGISTERED;
+
+ return (0);
+}
+
+static int
+machfb_get_info(video_adapter_t *adp, int mode, video_info_t *info)
+{
+
+ bcopy(&adp->va_info, info, sizeof(*info));
+
+ return (0);
+}
+
+static int
+machfb_query_mode(video_adapter_t *adp, video_info_t *info)
+{
+
+ return (ENODEV);
+}
+
+static int
+machfb_set_mode(video_adapter_t *adp, int mode)
+{
+
+ return (ENODEV);
+}
+
+static int
+machfb_save_font(video_adapter_t *adp, int page, int size, u_char *data,
+ int c, int count)
+{
+
+ return (ENODEV);
+}
+
+static int
+machfb_load_font(video_adapter_t *adp, int page, int size, u_char *data,
+ int c, int count)
+{
+
+ return (ENODEV);
+}
+
+static int
+machfb_show_font(video_adapter_t *adp, int page)
+{
+
+ return (ENODEV);
+}
+
+static int
+machfb_save_palette(video_adapter_t *adp, u_char *palette)
+{
+
+ return (ENODEV);
+}
+
+static int
+machfb_load_palette(video_adapter_t *adp, u_char *palette)
+{
+
+ return (ENODEV);
+}
+
+static int
+machfb_set_border(video_adapter_t *adp, int border)
+{
+ struct machfb_softc *sc;
+
+ sc = (struct machfb_softc *)adp;
+
+ machfb_fill_rect(adp, border, 0, 0, sc->sc_width, sc->sc_ymargin);
+ machfb_fill_rect(adp, border, 0, sc->sc_height - sc->sc_ymargin,
+ sc->sc_width, sc->sc_ymargin);
+ machfb_fill_rect(adp, border, 0, 0, sc->sc_xmargin, sc->sc_height);
+ machfb_fill_rect(adp, border, sc->sc_width - sc->sc_xmargin, 0,
+ sc->sc_xmargin, sc->sc_height);
+
+ return (0);
+}
+
+static int
+machfb_save_state(video_adapter_t *adp, void *p, size_t size)
+{
+
+ return (ENODEV);
+}
+
+static int
+machfb_load_state(video_adapter_t *adp, void *p)
+{
+
+ return (ENODEV);
+}
+
+static int
+machfb_set_win_org(video_adapter_t *adp, off_t offset)
+{
+
+ return (ENODEV);
+}
+
+static int
+machfb_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
+{
+
+ *col = 0;
+ *row = 0;
+
+ return (0);
+}
+
+static int
+machfb_set_hw_cursor(video_adapter_t *adp, int col, int row)
+{
+
+ return (ENODEV);
+}
+
+static int
+machfb_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
+ int celsize, int blink)
+{
+
+ return (ENODEV);
+}
+
+static int
+machfb_blank_display(video_adapter_t *adp, int mode)
+{
+ struct machfb_softc *sc;
+
+ sc = (struct machfb_softc *)adp;
+
+ if (mode == V_DISPLAY_ON || mode == V_DISPLAY_BLANK)
+ regw(sc, CRTC_GEN_CNTL, (regr(sc, CRTC_GEN_CNTL) | CRTC_EN |
+ CRTC_EXT_DISP_EN) & ~CRTC_DISPLAY_DIS);
+ else
+ regw(sc, CRTC_GEN_CNTL, regr(sc, CRTC_GEN_CNTL) & ~CRTC_EN);
+ if (mode == V_DISPLAY_BLANK)
+ machfb_fill_rect(adp, (SC_NORM_ATTR >> 4) & 0xf, 0, 0,
+ sc->sc_width, sc->sc_height);
+
+ return (0);
+}
+
+static int
+machfb_mmap(video_adapter_t *adp, vm_offset_t offset, vm_paddr_t *paddr,
+ int prot)
+{
+ struct machfb_softc *sc;
+
+ sc = (struct machfb_softc *)adp;
+
+ if (adp->va_io_base != 0 && offset >= adp->va_io_base &&
+ offset < adp->va_io_base + adp->va_io_size) {
+ *paddr = sc->sc_vioh + offset - adp->va_io_size;
+ return (0);
+ }
+
+ if (adp->va_mem_base != 0 && offset >= adp->va_mem_base &&
+ offset < adp->va_mem_base + adp->va_mem_size) {
+ *paddr = sc->sc_vmemh + offset - adp->va_mem_base;
+ return (0);
+ }
+
+ if (offset >= adp->va_registers &&
+ offset < adp->va_registers + adp->va_registers_size) {
+ *paddr = sc->sc_memh + offset - adp->va_registers;
+ return (0);
+ }
+
+ /* 'regular' framebuffer mmap()ing */
+ if (offset < adp->va_window_size) {
+ *paddr = adp->va_window + offset;
+ return (0);
+ }
+
+ return (EINVAL);
+}
+
+static int
+machfb_ioctl(video_adapter_t *adp, u_long cmd, caddr_t data)
+{
+ struct machfb_softc *sc;
+ struct fbcursor *fbc;
+ struct fbtype *fb;
+
+ sc = (struct machfb_softc *)adp;
+
+ switch (cmd) {
+ case FBIOGTYPE:
+ fb = (struct fbtype *)data;
+ fb->fb_type = FBTYPE_PCIMISC;
+ fb->fb_height = sc->sc_height;
+ fb->fb_width = sc->sc_width;
+ fb->fb_depth = sc->sc_depth;
+ if (sc->sc_depth <= 1 || sc->sc_depth > 8)
+ fb->fb_cmsize = 0;
+ else
+ fb->fb_cmsize = 1 << sc->sc_depth;
+ fb->fb_size = adp->va_buffer_size;
+ break;
+ case FBIOSCURSOR:
+ fbc = (struct fbcursor *)data;
+ if (fbc->set & FB_CUR_SETCUR) {
+ if (fbc->enable == 0) {
+ machfb_cursor_enable(sc, 0);
+ sc->sc_flags &= ~MACHFB_CUREN;
+ } else
+ return (ENODEV);
+ }
+ break;
+ default:
+ return (fb_commonioctl(adp, cmd, data));
+ }
+
+ return (0);
+}
+
+static int
+machfb_clear(video_adapter_t *adp)
+{
+
+ return (ENODEV);
+}
+
+static int
+machfb_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
+{
+ struct machfb_softc *sc;
+
+ sc = (struct machfb_softc *)adp;
+
+ if (sc->sc_draw_cache != MACHFB_DRAW_FILLRECT) {
+ wait_for_fifo(sc, 7);
+ regw(sc, DP_WRITE_MASK, 0xff);
+ regw(sc, DP_PIX_WIDTH, DST_8BPP | SRC_8BPP | HOST_8BPP);
+ regw(sc, DP_SRC, FRGD_SRC_FRGD_CLR);
+ regw(sc, DP_MIX, MIX_SRC << 16);
+ regw(sc, CLR_CMP_CNTL, 0); /* no transparency */
+ regw(sc, SRC_CNTL, SRC_LINE_X_LEFT_TO_RIGHT);
+ regw(sc, DST_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
+ sc->sc_draw_cache = MACHFB_DRAW_FILLRECT;
+ }
+ wait_for_fifo(sc, 5);
+ regw(sc, DP_FRGD_CLR, val);
+ regw(sc, SRC_Y_X, (x << 16) | y);
+ regw(sc, SRC_WIDTH1, cx);
+ regw(sc, DST_Y_X, (x << 16) | y);
+ regw(sc, DST_HEIGHT_WIDTH, (cx << 16) | cy);
+
+ return (0);
+}
+
+static int
+machfb_bitblt(video_adapter_t *adp, ...)
+{
+
+ return (ENODEV);
+}
+
+static int
+machfb_diag(video_adapter_t *adp, int level)
+{
+ video_info_t info;
+
+ fb_dump_adp_info(adp->va_name, adp, level);
+ machfb_get_info(adp, 0, &info);
+ fb_dump_mode_info(adp->va_name, adp, &info, level);
+
+ return (0);
+}
+
+static int
+machfb_save_cursor_palette(video_adapter_t *adp, u_char *palette)
+{
+
+ return (ENODEV);
+}
+
+static int
+machfb_load_cursor_palette(video_adapter_t *adp, u_char *palette)
+{
+
+ return (ENODEV);
+}
+
+static int
+machfb_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst, int n)
+{
+
+ return (ENODEV);
+}
+
+static int
+machfb_putp(video_adapter_t *adp, vm_offset_t off, uint32_t p, uint32_t a,
+ int size, int bpp, int bit_ltor, int byte_ltor)
+{
+
+ return (ENODEV);
+}
+
+static int
+machfb_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a)
+{
+ struct machfb_softc *sc;
+ uint8_t *p;
+ int i;
+
+ sc = (struct machfb_softc *)adp;
+
+ if (sc->sc_draw_cache != MACHFB_DRAW_CHAR) {
+ wait_for_fifo(sc, 8);
+ regw(sc, DP_WRITE_MASK, 0xff); /* XXX only good for 8 bit */
+ regw(sc, DP_PIX_WIDTH, DST_8BPP | SRC_1BPP | HOST_1BPP);
+ regw(sc, DP_SRC, MONO_SRC_HOST | BKGD_SRC_BKGD_CLR |
+ FRGD_SRC_FRGD_CLR);
+ regw(sc, DP_MIX ,((MIX_SRC & 0xffff) << 16) | MIX_SRC);
+ regw(sc, CLR_CMP_CNTL, 0); /* no transparency */
+ regw(sc, SRC_CNTL, SRC_LINE_X_LEFT_TO_RIGHT);
+ regw(sc, DST_CNTL, DST_Y_TOP_TO_BOTTOM | DST_X_LEFT_TO_RIGHT);
+ regw(sc, HOST_CNTL, HOST_BYTE_ALIGN);
+ sc->sc_draw_cache = MACHFB_DRAW_CHAR;
+ }
+ p = sc->sc_font + (c * adp->va_info.vi_cheight * sc->sc_cbwidth);
+ wait_for_fifo(sc, 6 + (adp->va_info.vi_cheight / sc->sc_cbwidth));
+ regw(sc, DP_BKGD_CLR, (a >> 4) & 0xf);
+ regw(sc, DP_FRGD_CLR, a & 0xf);
+ regw(sc, SRC_Y_X, 0);
+ regw(sc, SRC_WIDTH1, adp->va_info.vi_cwidth);
+ regw(sc, DST_Y_X, ((((off % adp->va_info.vi_width) *
+ adp->va_info.vi_cwidth) + sc->sc_xmargin) << 16) |
+ (((off / adp->va_info.vi_width) * adp->va_info.vi_cheight) +
+ sc->sc_ymargin));
+ regw(sc, DST_HEIGHT_WIDTH, (adp->va_info.vi_cwidth << 16) |
+ adp->va_info.vi_cheight);
+ for (i = 0; i < adp->va_info.vi_cheight * sc->sc_cbwidth; i += 4)
+ regw(sc, HOST_DATA0 + i, (p[i + 3] << 24 | p[i + 2] << 16 |
+ p[i + 1] << 8 | p[i]));
+
+ return (0);
+}
+
+static int
+machfb_puts(video_adapter_t *adp, vm_offset_t off, uint16_t *s, int len)
+{
+ struct machfb_softc *sc;
+ int blanks, i, x1, x2, y1, y2;
+ uint8_t a, c, color1, color2;
+
+ sc = (struct machfb_softc *)adp;
+
+#define MACHFB_BLANK machfb_fill_rect(adp, color1, x1, y1, \
+ blanks * adp->va_info.vi_cwidth, \
+ adp->va_info.vi_cheight)
+
+ blanks = color1 = x1 = y1 = 0;
+ for (i = 0; i < len; i++) {
+ /*
+ * Accelerate continuous blanks by drawing a respective
+ * rectangle instead. Drawing a rectangle of any size
+ * takes about the same number of operations as drawing
+ * a single character.
+ */
+ c = s[i] & 0xff;
+ a = (s[i] & 0xff00) >> 8;
+ if (c == 0x00 || c == 0x20 || c == 0xdb || c == 0xff) {
+ color2 = (a >> (c == 0xdb ? 0 : 4) & 0xf);
+ x2 = (((off + i) % adp->va_info.vi_width) *
+ adp->va_info.vi_cwidth) + sc->sc_xmargin;
+ y2 = (((off + i) / adp->va_info.vi_width) *
+ adp->va_info.vi_cheight) + sc->sc_ymargin;
+ if (blanks == 0) {
+ color1 = color2;
+ x1 = x2;
+ y1 = y2;
+ blanks++;
+ } else if (color1 != color2 || y1 != y2) {
+ MACHFB_BLANK;
+ color1 = color2;
+ x1 = x2;
+ y1 = y2;
+ blanks = 1;
+ } else
+ blanks++;
+ } else {
+ if (blanks != 0) {
+ MACHFB_BLANK;
+ blanks = 0;
+ }
+ (*vidsw[adp->va_index]->putc)(adp, off + i, c, a);
+ }
+ }
+ if (blanks != 0)
+ MACHFB_BLANK;
+
+#undef MACHFB_BLANK
+
+ return (0);
+}
+
+static int
+machfb_putm(video_adapter_t *adp, int x, int y, uint8_t *pixel_image,
+ uint32_t pixel_mask, int size)
+{
+ struct machfb_softc *sc;
+ int error;
+
+ sc = (struct machfb_softc *)adp;
+
+ if ((!(sc->sc_flags & MACHFB_CUREN)) &&
+ (error = machfb_cursor_install(sc)) < 0)
+ return (error);
+ else {
+ /*
+ * The hardware cursor always must be disabled when
+ * fiddling with its bits otherwise some artifacts
+ * may appear on the screen.
+ */
+ machfb_cursor_enable(sc, 0);
+ }
+
+ regw(sc, CUR_HORZ_VERT_OFF, 0);
+ if ((regr(sc, GEN_TEST_CNTL) & CRTC_DBL_SCAN_EN) != 0)
+ y <<= 1;
+ regw(sc, CUR_HORZ_VERT_POSN, ((y + sc->sc_ymargin) << 16) |
+ (x + sc->sc_xmargin));
+ machfb_cursor_enable(sc, 1);
+ sc->sc_flags |= MACHFB_CUREN;
+
+ return (0);
+}
+
+/*
+ * PCI bus interface
+ */
+static int
+machfb_pci_probe(device_t dev)
+{
+ int i;
+
+ if (pci_get_class(dev) != PCIC_DISPLAY ||
+ pci_get_subclass(dev) != PCIS_DISPLAY_VGA)
+ return (ENXIO);
+
+ for (i = 0; i < sizeof(machfb_info) / sizeof(machfb_info[0]); i++) {
+ if (pci_get_device(dev) == machfb_info[i].chip_id) {
+ device_set_desc(dev, machfb_info[i].name);
+ return (BUS_PROBE_DEFAULT);
+ }
+ }
+
+ return (ENXIO);
+}
+
+static int
+machfb_pci_attach(device_t dev)
+{
+ struct machfb_softc *sc;
+ video_adapter_t *adp;
+ video_switch_t *sw;
+ phandle_t node;
+ uint32_t *p32, saved_value;
+ uint8_t *p;
+ int error, i;
+
+ node = ofw_bus_get_node(dev);
+ if ((sc = (struct machfb_softc *)vid_get_adapter(vid_find_adapter(
+ MACHFB_DRIVER_NAME, 0))) != NULL && sc->sc_node == node) {
+ device_printf(dev, "console\n");
+ device_set_softc(dev, sc);
+ } else {
+ sc = device_get_softc(dev);
+ bzero(sc, sizeof(struct machfb_softc));
+
+ sc->sc_node = node;
+ sc->sc_chip_id = pci_get_device(dev);
+ sc->sc_chip_rev = pci_get_revid(dev);
+ }
+ adp = &sc->sc_va;
+
+ /*
+ * Regardless whether we are the console and already allocated
+ * resources in machfb_configure() or not we have to allocate
+ * them here (again) in order for rman_get_virtual() to work.
+ */
+
+ /* Enable memory and IO access. */
+ pci_write_config(dev, PCIR_COMMAND,
+ pci_read_config(dev, PCIR_COMMAND, 2) | PCIM_CMD_PORTEN |
+ PCIM_CMD_MEMEN, 2);
+
+ sc->sc_memrid = PCIR_BAR(0);
+ if ((sc->sc_memres = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+ &sc->sc_memrid, RF_ACTIVE)) == NULL) {
+ device_printf(dev, "cannot allocate memory resources\n");
+ return (ENXIO);
+ }
+ sc->sc_memt = rman_get_bustag(sc->sc_memres);
+ sc->sc_memh = rman_get_bushandle(sc->sc_memres);
+ adp->va_registers = rman_get_start(sc->sc_memres);
+ adp->va_registers_size = rman_get_size(sc->sc_memres);
+ sc->sc_regt = sc->sc_memt;
+ bus_space_subregion(sc->sc_regt, sc->sc_memh, MACH64_REG_OFF,
+ MACH64_REG_SIZE, &sc->sc_regh);
+ adp->va_buffer = (vm_offset_t)rman_get_virtual(sc->sc_memres);
+ adp->va_buffer_size = rman_get_size(sc->sc_memres);
+
+ /*
+ * Depending on the firmware version the VGA I/O and/or memory
+ * resources of the Mach64 chips come up disabled. We generally
+ * enable them above (pci(4) actually already did this unless
+ * pci_enable_io_modes is not set) but this doesn't necessarily
+ * mean that we get valid ones. Invalid resources seem to have
+ * in common that they start at address 0. We don't allocate
+ * them in this case in order to avoid warnings in apb(4) and
+ * crashes when using these invalid resources. Xorg is aware
+ * of this and doesn't use the VGA resources in this case (but
+ * demands them if they are valid).
+ */
+ sc->sc_viorid = PCIR_BAR(1);
+ if (bus_get_resource_start(dev, SYS_RES_IOPORT, sc->sc_viorid) != 0) {
+ if ((sc->sc_viores = bus_alloc_resource_any(dev,
+ SYS_RES_IOPORT, &sc->sc_viorid, RF_ACTIVE)) == NULL) {
+ device_printf(dev,
+ "cannot allocate VGA I/O resources\n");
+ error = ENXIO;
+ goto fail_memres;
+ }
+ sc->sc_viot = rman_get_bustag(sc->sc_viores);
+ sc->sc_vioh = rman_get_bushandle(sc->sc_viores);
+ adp->va_io_base = rman_get_start(sc->sc_viores);
+ adp->va_io_size = rman_get_size(sc->sc_viores);
+ }
+
+ sc->sc_vmemrid = PCIR_BAR(2);
+ if (bus_get_resource_start(dev, SYS_RES_MEMORY, sc->sc_vmemrid) != 0) {
+ if ((sc->sc_vmemres = bus_alloc_resource_any(dev,
+ SYS_RES_MEMORY, &sc->sc_vmemrid, RF_ACTIVE)) == NULL) {
+ device_printf(dev,
+ "cannot allocate VGA memory resources\n");
+ error = ENXIO;
+ goto fail_viores;
+ }
+ sc->sc_vmemt = rman_get_bustag(sc->sc_vmemres);
+ sc->sc_vmemh = rman_get_bushandle(sc->sc_vmemres);
+ adp->va_mem_base = rman_get_start(sc->sc_vmemres);
+ adp->va_mem_size = rman_get_size(sc->sc_vmemres);
+ }
+
+ device_printf(dev,
+ "%d MB aperture at 0x%08x, %d KB registers at 0x%08x\n",
+ (u_int)(adp->va_buffer_size / (1024 * 1024)),
+ (u_int)adp->va_buffer, MACH64_REG_SIZE / 1024,
+ (u_int)sc->sc_regh);
+
+ if (!(sc->sc_flags & MACHFB_CONSOLE)) {
+ if ((sw = vid_get_switch(MACHFB_DRIVER_NAME)) == NULL) {
+ device_printf(dev, "cannot get video switch\n");
+ error = ENODEV;
+ goto fail_vmemres;
+ }
+ /*
+ * During device configuration we don't necessarily probe
+ * the adapter which is the console first so we can't use
+ * the device unit number for the video adapter unit. The
+ * worst case would be that we use the video adapter unit
+ * 0 twice. As it doesn't really matter which unit number
+ * the corresponding video adapter has just use the next
+ * unused one.
+ */
+ for (i = 0; i < devclass_get_maxunit(machfb_devclass); i++)
+ if (vid_find_adapter(MACHFB_DRIVER_NAME, i) < 0)
+ break;
+ if ((error = sw->init(i, adp, 0)) != 0) {
+ device_printf(dev, "cannot initialize adapter\n");
+ goto fail_vmemres;
+ }
+ }
+
+ device_printf(dev,
+ "%ld KB %s %d.%d MHz, maximum RAMDAC clock %d MHz, %sDSP\n",
+ (u_long)sc->sc_memsize, machfb_memtype_names[sc->sc_memtype],
+ sc->sc_mem_freq / 1000, sc->sc_mem_freq % 1000,
+ sc->sc_ramdac_freq / 1000,
+ (sc->sc_flags & MACHFB_DSP) ? "" : "no ");
+ device_printf(dev, "resolution %dx%d at %d bpp\n",
+ sc->sc_width, sc->sc_height, sc->sc_depth);
+
+ /*
+ * Test whether the aperture is byte swapped or not, set
+ * va_window and va_window_size as appropriate.
+ */
+ p32 = (uint32_t *)adp->va_buffer;
+ saved_value = *p32;
+ p = (uint8_t *)adp->va_buffer;
+ *p32 = 0x12345678;
+ if (!(p[0] == 0x12 && p[1] == 0x34 && p[2] == 0x56 && p[3] == 0x78)) {
+ adp->va_window = adp->va_buffer + 0x800000;
+ adp->va_window_size = adp->va_buffer_size - 0x800000;
+ } else {
+ adp->va_window = adp->va_buffer;
+ adp->va_window_size = adp->va_buffer_size;
+ }
+ *p32 = saved_value;
+ adp->va_window_gran = adp->va_window_size;
+
+ /*
+ * Allocate one page for the mouse pointer image at the end of
+ * the little endian aperture, right before the memory mapped
+ * registers that might also reside there. Must be done after
+ * sc_memsize was set and possibly adjusted to account for the
+ * memory mapped registers.
+ */
+ sc->sc_curoff = (sc->sc_memsize * 1024) - PAGE_SIZE;
+ sc->sc_memsize -= PAGE_SIZE / 1024;
+ machfb_cursor_enable(sc, 0);
+ /* Initialize with an all transparent image. */
+ memset((void *)(adp->va_buffer + sc->sc_curoff), 0xaa, PAGE_SIZE);
+
+ /*
+ * For cosmetics register a handler that turns off the mouse
+ * pointer on halt. Register a second handler that turns off
+ * the CRTC when resetting, otherwise the OFW boot command
+ * issued by cpu_reset() just doesn't work.
+ */
+ EVENTHANDLER_REGISTER(shutdown_final, machfb_shutdown_final, sc,
+ SHUTDOWN_PRI_DEFAULT);
+ EVENTHANDLER_REGISTER(shutdown_reset, machfb_shutdown_reset, sc,
+ SHUTDOWN_PRI_DEFAULT);
+
+ return (0);
+
+ fail_vmemres:
+ if (sc->sc_vmemres != NULL)
+ bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_vmemrid,
+ sc->sc_vmemres);
+ fail_viores:
+ if (sc->sc_viores != NULL)
+ bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_viorid,
+ sc->sc_viores);
+ fail_memres:
+ bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_memrid, sc->sc_memres);
+
+ return (error);
+}
+
+static int
+machfb_pci_detach(device_t dev)
+{
+
+ return (EINVAL);
+}
+
+/*
+ * internal functions
+ */
+static void
+machfb_cursor_enable(struct machfb_softc *sc, int onoff)
+{
+
+ if (onoff)
+ regw(sc, GEN_TEST_CNTL,
+ regr(sc, GEN_TEST_CNTL) | HWCURSOR_ENABLE);
+ else
+ regw(sc, GEN_TEST_CNTL,
+ regr(sc, GEN_TEST_CNTL) &~ HWCURSOR_ENABLE);
+}
+
+static int
+machfb_cursor_install(struct machfb_softc *sc)
+{
+ uint16_t *p;
+ uint8_t fg;
+ int i, j;
+
+ if (sc->sc_curoff == 0)
+ return (ENODEV);
+
+ machfb_cursor_enable(sc, 0);
+ regw(sc, CUR_OFFSET, sc->sc_curoff >> 3);
+ fg = SC_NORM_ATTR & 0xf;
+ regw(sc, CUR_CLR0, sc->sc_cmap_red[fg] << 24 |
+ sc->sc_cmap_green[fg] << 16 | sc->sc_cmap_blue[fg] << 8 | fg);
+ p = (uint16_t *)(sc->sc_va.va_buffer + sc->sc_curoff);
+ for (i = 0; i < 64; i++)
+ for (j = 0; j < 8; j++)
+ *(p++) = machfb_mouse_pointer_lut[
+ machfb_mouse_pointer_bits[i][j] >> 4] |
+ machfb_mouse_pointer_lut[
+ machfb_mouse_pointer_bits[i][j] & 0x0f] << 8;
+
+ return (0);
+}
+
+static int
+machfb_get_memsize(struct machfb_softc *sc)
+{
+ int tmp, memsize;
+ int mem_tab[] = {
+ 512, 1024, 2048, 4096, 6144, 8192, 12288, 16384
+ };
+
+ tmp = regr(sc, MEM_CNTL);
+#ifdef MACHFB_DEBUG
+ printf("memcntl=0x%08x\n", tmp);
+#endif
+ if (sc->sc_flags & MACHFB_DSP) {
+ tmp &= 0x0000000f;
+ if (tmp < 8)
+ memsize = (tmp + 1) * 512;
+ else if (tmp < 12)
+ memsize = (tmp - 3) * 1024;
+ else
+ memsize = (tmp - 7) * 2048;
+ } else
+ memsize = mem_tab[tmp & 0x07];
+
+ return (memsize);
+}
+
+static void
+machfb_reset_engine(struct machfb_softc *sc)
+{
+
+ /* Reset engine.*/
+ regw(sc, GEN_TEST_CNTL, regr(sc, GEN_TEST_CNTL) & ~GUI_ENGINE_ENABLE);
+
+ /* Enable engine. */
+ regw(sc, GEN_TEST_CNTL, regr(sc, GEN_TEST_CNTL) | GUI_ENGINE_ENABLE);
+
+ /*
+ * Ensure engine is not locked up by clearing any FIFO or
+ * host errors.
+ */
+ regw(sc, BUS_CNTL, regr(sc, BUS_CNTL) | BUS_HOST_ERR_ACK |
+ BUS_FIFO_ERR_ACK);
+}
+
+static void
+machfb_init_engine(struct machfb_softc *sc)
+{
+ uint32_t pitch_value;
+
+ pitch_value = sc->sc_width;
+
+ if (sc->sc_depth == 24)
+ pitch_value *= 3;
+
+ machfb_reset_engine(sc);
+
+ wait_for_fifo(sc, 14);
+
+ regw(sc, CONTEXT_MASK, 0xffffffff);
+
+ regw(sc, DST_OFF_PITCH, (pitch_value / 8) << 22);
+
+ regw(sc, DST_Y_X, 0);
+ regw(sc, DST_HEIGHT, 0);
+ regw(sc, DST_BRES_ERR, 0);
+ regw(sc, DST_BRES_INC, 0);
+ regw(sc, DST_BRES_DEC, 0);
+
+ regw(sc, DST_CNTL, DST_LAST_PEL | DST_X_LEFT_TO_RIGHT |
+ DST_Y_TOP_TO_BOTTOM);
+
+ regw(sc, SRC_OFF_PITCH, (pitch_value / 8) << 22);
+
+ regw(sc, SRC_Y_X, 0);
+ regw(sc, SRC_HEIGHT1_WIDTH1, 1);
+ regw(sc, SRC_Y_X_START, 0);
+ regw(sc, SRC_HEIGHT2_WIDTH2, 1);
+
+ regw(sc, SRC_CNTL, SRC_LINE_X_LEFT_TO_RIGHT);
+
+ wait_for_fifo(sc, 13);
+ regw(sc, HOST_CNTL, 0);
+
+ regw(sc, PAT_REG0, 0);
+ regw(sc, PAT_REG1, 0);
+ regw(sc, PAT_CNTL, 0);
+
+ regw(sc, SC_LEFT, 0);
+ regw(sc, SC_TOP, 0);
+ regw(sc, SC_BOTTOM, sc->sc_height - 1);
+ regw(sc, SC_RIGHT, pitch_value - 1);
+
+ regw(sc, DP_BKGD_CLR, 0);
+ regw(sc, DP_FRGD_CLR, 0xffffffff);
+ regw(sc, DP_WRITE_MASK, 0xffffffff);
+ regw(sc, DP_MIX, (MIX_SRC << 16) | MIX_DST);
+
+ regw(sc, DP_SRC, FRGD_SRC_FRGD_CLR);
+
+ wait_for_fifo(sc, 3);
+ regw(sc, CLR_CMP_CLR, 0);
+ regw(sc, CLR_CMP_MASK, 0xffffffff);
+ regw(sc, CLR_CMP_CNTL, 0);
+
+ wait_for_fifo(sc, 2);
+ switch (sc->sc_depth) {
+ case 8:
+ regw(sc, DP_PIX_WIDTH, HOST_8BPP | SRC_8BPP | DST_8BPP);
+ regw(sc, DP_CHAIN_MASK, DP_CHAIN_8BPP);
+ regw(sc, DAC_CNTL, regr(sc, DAC_CNTL) | DAC_8BIT_EN);
+ break;
+#if 0
+ case 32:
+ regw(sc, DP_PIX_WIDTH, HOST_32BPP | SRC_32BPP | DST_32BPP);
+ regw(sc, DP_CHAIN_MASK, DP_CHAIN_32BPP);
+ regw(sc, DAC_CNTL, regr(sc, DAC_CNTL) | DAC_8BIT_EN);
+ break;
+#endif
+ }
+
+ wait_for_fifo(sc, 5);
+ regw(sc, CRTC_INT_CNTL, regr(sc, CRTC_INT_CNTL) & ~0x20);
+ regw(sc, GUI_TRAJ_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
+
+ wait_for_idle(sc);
+}
+
+#if 0
+static void
+machfb_adjust_frame(struct machfb_softc *sc, int x, int y)
+{
+ int offset;
+
+ offset = ((x + y * sc->sc_width) * (sc->sc_depth >> 3)) >> 3;
+
+ regw(sc, CRTC_OFF_PITCH, (regr(sc, CRTC_OFF_PITCH) & 0xfff00000) |
+ offset);
+}
+#endif
+
+static void
+machfb_putpalreg(struct machfb_softc *sc, uint8_t index, uint8_t r, uint8_t g,
+ uint8_t b)
+{
+
+ sc->sc_cmap_red[index] = r;
+ sc->sc_cmap_green[index] = g;
+ sc->sc_cmap_blue[index] = b;
+ /*
+ * Writing the DAC index takes a while, in theory we can poll some
+ * register to see when it's ready - but we better avoid writing it
+ * unnecessarily.
+ */
+ if (index != sc->sc_dacw) {
+ regwb(sc, DAC_MASK, 0xff);
+ regwb(sc, DAC_WINDEX, index);
+ }
+ sc->sc_dacw = index + 1;
+ regwb(sc, DAC_DATA, r);
+ regwb(sc, DAC_DATA, g);
+ regwb(sc, DAC_DATA, b);
+}
+
+static void
+machfb_shutdown_final(void *v)
+{
+ struct machfb_softc *sc = v;
+
+ machfb_cursor_enable(sc, 0);
+}
+
+static void
+machfb_shutdown_reset(void *v)
+{
+ struct machfb_softc *sc = v;
+
+ machfb_blank_display(&sc->sc_va, V_DISPLAY_STAND_BY);
+}
diff --git a/sys/dev/fb/machfbreg.h b/sys/dev/fb/machfbreg.h
new file mode 100644
index 0000000..8990a4e
--- /dev/null
+++ b/sys/dev/fb/machfbreg.h
@@ -0,0 +1,458 @@
+/*-
+ * Copyright 1992,1993,1994,1995,1996,1997 by Kevin E. Martin, Chapel Hill, North Carolina.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Kevin E. Martin not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. Kevin E. Martin
+ * makes no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * KEVIN E. MARTIN, RICKARD E. FAITH, AND TIAGO GONS DISCLAIM ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE
+ * AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Modified for the Mach-8 by Rickard E. Faith (faith@cs.unc.edu)
+ * Modified for the Mach32 by Kevin E. Martin (martin@cs.unc.edu)
+ * Modified for the Mach64 by Kevin E. Martin (martin@cs.unc.edu)
+ *
+ * from: NetBSD: machfbreg.h,v 1.1 2002/10/24 18:15:57 junyoung Exp
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _DEV_FB_MACHFB_H_
+#define _DEV_FB_MACHFB_H_
+
+/* NON-GUI MEMORY MAPPED Registers - expressed in BYTE offsets */
+
+#define CRTC_H_TOTAL_DISP 0x0000 /* Dword offset 00 */
+#define CRTC_H_SYNC_STRT_WID 0x0004 /* Dword offset 01 */
+#define CRTC_V_TOTAL_DISP 0x0008 /* Dword offset 02 */
+#define CRTC_V_SYNC_STRT_WID 0x000C /* Dword offset 03 */
+#define CRTC_VLINE_CRNT_VLINE 0x0010 /* Dword offset 04 */
+#define CRTC_OFF_PITCH 0x0014 /* Dword offset 05 */
+#define CRTC_INT_CNTL 0x0018 /* Dword offset 06 */
+#define CRTC_GEN_CNTL 0x001C /* Dword offset 07 */
+
+#define DSP_CONFIG 0x0020 /* Dword offset 08 */
+#define DSP_ON_OFF 0x0024 /* Dword offset 09 */
+
+#define SHARED_CNTL 0x0038 /* Dword offset 0E */
+
+#define OVR_CLR 0x0040 /* Dword offset 10 */
+#define OVR_WID_LEFT_RIGHT 0x0044 /* Dword offset 11 */
+#define OVR_WID_TOP_BOTTOM 0x0048 /* Dword offset 12 */
+
+#define CUR_CLR0 0x0060 /* Dword offset 18 */
+#define CUR_CLR1 0x0064 /* Dword offset 19 */
+#define CUR_OFFSET 0x0068 /* Dword offset 1A */
+#define CUR_HORZ_VERT_POSN 0x006C /* Dword offset 1B */
+#define CUR_HORZ_VERT_OFF 0x0070 /* Dword offset 1C */
+
+#define HW_DEBUG 0x007C /* Dword offset 1F */
+
+#define SCRATCH_REG0 0x0080 /* Dword offset 20 */
+#define SCRATCH_REG1 0x0084 /* Dword offset 21 */
+
+#define CLOCK_CNTL 0x0090 /* Dword offset 24 */
+
+#define BUS_CNTL 0x00A0 /* Dword offset 28 */
+
+#define LCD_INDEX 0x00A4 /* Dword offset 29 (LTPro) */
+#define LCD_DATA 0x00A8 /* Dword offset 2A (LTPro) */
+
+#define MEM_CNTL 0x00B0 /* Dword offset 2C */
+
+#define MEM_VGA_WP_SEL 0x00B4 /* Dword offset 2D */
+#define MEM_VGA_RP_SEL 0x00B8 /* Dword offset 2E */
+
+#define DAC_REGS 0x00C0 /* Dword offset 30 */
+#define DAC_WINDEX 0x00C0 /* Dword offset 30 */
+#define DAC_DATA 0x00C1 /* Dword offset 30 */
+#define DAC_MASK 0x00C2 /* Dword offset 30 */
+#define DAC_RINDEX 0x00C3 /* Dword offset 30 */
+#define DAC_CNTL 0x00C4 /* Dword offset 31 */
+
+#define HORZ_STRETCHING 0x00C8 /* Dword offset 32 (LT) */
+#define VERT_STRETCHING 0x00CC /* Dword offset 33 (LT) */
+
+#define GEN_TEST_CNTL 0x00D0 /* Dword offset 34 */
+
+#define LCD_GEN_CNTL 0x00D4 /* Dword offset 35 (LT) */
+#define POWER_MANAGEMENT 0x00D8 /* Dword offset 36 (LT) */
+
+#define CONFIG_CNTL 0x00DC /* Dword offset 37 (CT, ET, VT) */
+#define CONFIG_CHIP_ID 0x00E0 /* Dword offset 38 */
+#define CONFIG_STAT0 0x00E4 /* Dword offset 39 */
+#define CONFIG_STAT1 0x00E8 /* Dword offset 3A */
+
+
+/* GUI MEMORY MAPPED Registers */
+
+#define DST_OFF_PITCH 0x0100 /* Dword offset 40 */
+#define DST_X 0x0104 /* Dword offset 41 */
+#define DST_Y 0x0108 /* Dword offset 42 */
+#define DST_Y_X 0x010C /* Dword offset 43 */
+#define DST_WIDTH 0x0110 /* Dword offset 44 */
+#define DST_HEIGHT 0x0114 /* Dword offset 45 */
+#define DST_HEIGHT_WIDTH 0x0118 /* Dword offset 46 */
+#define DST_X_WIDTH 0x011C /* Dword offset 47 */
+#define DST_BRES_LNTH 0x0120 /* Dword offset 48 */
+#define DST_BRES_ERR 0x0124 /* Dword offset 49 */
+#define DST_BRES_INC 0x0128 /* Dword offset 4A */
+#define DST_BRES_DEC 0x012C /* Dword offset 4B */
+#define DST_CNTL 0x0130 /* Dword offset 4C */
+
+#define SRC_OFF_PITCH 0x0180 /* Dword offset 60 */
+#define SRC_X 0x0184 /* Dword offset 61 */
+#define SRC_Y 0x0188 /* Dword offset 62 */
+#define SRC_Y_X 0x018C /* Dword offset 63 */
+#define SRC_WIDTH1 0x0190 /* Dword offset 64 */
+#define SRC_HEIGHT1 0x0194 /* Dword offset 65 */
+#define SRC_HEIGHT1_WIDTH1 0x0198 /* Dword offset 66 */
+#define SRC_X_START 0x019C /* Dword offset 67 */
+#define SRC_Y_START 0x01A0 /* Dword offset 68 */
+#define SRC_Y_X_START 0x01A4 /* Dword offset 69 */
+#define SRC_WIDTH2 0x01A8 /* Dword offset 6A */
+#define SRC_HEIGHT2 0x01AC /* Dword offset 6B */
+#define SRC_HEIGHT2_WIDTH2 0x01B0 /* Dword offset 6C */
+#define SRC_CNTL 0x01B4 /* Dword offset 6D */
+
+#define HOST_DATA0 0x0200 /* Dword offset 80 */
+#define HOST_DATA1 0x0204 /* Dword offset 81 */
+#define HOST_DATA2 0x0208 /* Dword offset 82 */
+#define HOST_DATA3 0x020C /* Dword offset 83 */
+#define HOST_DATA4 0x0210 /* Dword offset 84 */
+#define HOST_DATA5 0x0214 /* Dword offset 85 */
+#define HOST_DATA6 0x0218 /* Dword offset 86 */
+#define HOST_DATA7 0x021C /* Dword offset 87 */
+#define HOST_DATA8 0x0220 /* Dword offset 88 */
+#define HOST_DATA9 0x0224 /* Dword offset 89 */
+#define HOST_DATAA 0x0228 /* Dword offset 8A */
+#define HOST_DATAB 0x022C /* Dword offset 8B */
+#define HOST_DATAC 0x0230 /* Dword offset 8C */
+#define HOST_DATAD 0x0234 /* Dword offset 8D */
+#define HOST_DATAE 0x0238 /* Dword offset 8E */
+#define HOST_DATAF 0x023C /* Dword offset 8F */
+#define HOST_CNTL 0x0240 /* Dword offset 90 */
+
+#define PAT_REG0 0x0280 /* Dword offset A0 */
+#define PAT_REG1 0x0284 /* Dword offset A1 */
+#define PAT_CNTL 0x0288 /* Dword offset A2 */
+
+#define SC_LEFT 0x02A0 /* Dword offset A8 */
+#define SC_RIGHT 0x02A4 /* Dword offset A9 */
+#define SC_LEFT_RIGHT 0x02A8 /* Dword offset AA */
+#define SC_TOP 0x02AC /* Dword offset AB */
+#define SC_BOTTOM 0x02B0 /* Dword offset AC */
+#define SC_TOP_BOTTOM 0x02B4 /* Dword offset AD */
+
+#define DP_BKGD_CLR 0x02C0 /* Dword offset B0 */
+#define DP_FRGD_CLR 0x02C4 /* Dword offset B1 */
+#define DP_WRITE_MASK 0x02C8 /* Dword offset B2 */
+#define DP_CHAIN_MASK 0x02CC /* Dword offset B3 */
+#define DP_PIX_WIDTH 0x02D0 /* Dword offset B4 */
+#define DP_MIX 0x02D4 /* Dword offset B5 */
+#define DP_SRC 0x02D8 /* Dword offset B6 */
+
+#define CLR_CMP_CLR 0x0300 /* Dword offset C0 */
+#define CLR_CMP_MASK 0x0304 /* Dword offset C1 */
+#define CLR_CMP_CNTL 0x0308 /* Dword offset C2 */
+
+#define FIFO_STAT 0x0310 /* Dword offset C4 */
+
+#define CONTEXT_MASK 0x0320 /* Dword offset C8 */
+#define CONTEXT_LOAD_CNTL 0x032C /* Dword offset CB */
+
+#define GUI_TRAJ_CNTL 0x0330 /* Dword offset CC */
+#define GUI_STAT 0x0338 /* Dword offset CE */
+
+
+/* CRTC control values */
+
+#define CRTC_HSYNC_NEG 0x00200000
+#define CRTC_VSYNC_NEG 0x00200000
+
+#define CRTC_DBL_SCAN_EN 0x00000001
+#define CRTC_INTERLACE_EN 0x00000002
+#define CRTC_HSYNC_DIS 0x00000004
+#define CRTC_VSYNC_DIS 0x00000008
+#define CRTC_CSYNC_EN 0x00000010
+#define CRTC_PIX_BY_2_EN 0x00000020
+#define CRTC_DISPLAY_DIS 0x00000040
+#define CRTC_VGA_XOVERSCAN 0x00000080
+
+#define CRTC_PIX_WIDTH 0x00000700
+#define CRTC_PIX_WIDTH_4BPP 0x00000100
+#define CRTC_PIX_WIDTH_8BPP 0x00000200
+#define CRTC_PIX_WIDTH_15BPP 0x00000300
+#define CRTC_PIX_WIDTH_16BPP 0x00000400
+#define CRTC_PIX_WIDTH_24BPP 0x00000500
+#define CRTC_PIX_WIDTH_32BPP 0x00000600
+
+#define CRTC_BYTE_PIX_ORDER 0x00000800
+#define CRTC_PIX_ORDER_MSN_LSN 0x00000000
+#define CRTC_PIX_ORDER_LSN_MSN 0x00000800
+
+#define CRTC_FIFO_LWM 0x000f0000
+#define CRTC_LOCK_REGS 0x00400000
+#define CRTC_EXT_DISP_EN 0x01000000
+#define CRTC_EN 0x02000000
+#define CRTC_DISP_REQ_EN 0x04000000
+#define CRTC_VGA_LINEAR 0x08000000
+#define CRTC_VSYNC_FALL_EDGE 0x10000000
+#define CRTC_VGA_TEXT_132 0x20000000
+#define CRTC_CNT_EN 0x40000000
+#define CRTC_CUR_B_TEST 0x80000000
+
+#define CRTC_CRNT_VLINE 0x07f00000
+#define CRTC_VBLANK 0x00000001
+
+/* DAC control values */
+
+#define DAC_EXT_SEL_RS2 0x01
+#define DAC_EXT_SEL_RS3 0x02
+#define DAC_8BIT_EN 0x00000100
+#define DAC_PIX_DLY_MASK 0x00000600
+#define DAC_PIX_DLY_0NS 0x00000000
+#define DAC_PIX_DLY_2NS 0x00000200
+#define DAC_PIX_DLY_4NS 0x00000400
+#define DAC_BLANK_ADJ_MASK 0x00001800
+#define DAC_BLANK_ADJ_0 0x00000000
+#define DAC_BLANK_ADJ_1 0x00000800
+#define DAC_BLANK_ADJ_2 0x00001000
+
+
+/* Mix control values */
+
+#define MIX_NOT_DST 0x0000
+#define MIX_0 0x0001
+#define MIX_1 0x0002
+#define MIX_DST 0x0003
+#define MIX_NOT_SRC 0x0004
+#define MIX_XOR 0x0005
+#define MIX_XNOR 0x0006
+#define MIX_SRC 0x0007
+#define MIX_NAND 0x0008
+#define MIX_NOT_SRC_OR_DST 0x0009
+#define MIX_SRC_OR_NOT_DST 0x000a
+#define MIX_OR 0x000b
+#define MIX_AND 0x000c
+#define MIX_SRC_AND_NOT_DST 0x000d
+#define MIX_NOT_SRC_AND_DST 0x000e
+#define MIX_NOR 0x000f
+
+/* Maximum engine dimensions */
+#define ENGINE_MIN_X 0
+#define ENGINE_MIN_Y 0
+#define ENGINE_MAX_X 4095
+#define ENGINE_MAX_Y 16383
+
+/* Mach64 engine bit constants - these are typically ORed together */
+
+/* HW_DEBUG register constants */
+/* For RagePro only... */
+#define AUTO_FF_DIS 0x000001000
+#define AUTO_BLKWRT_DIS 0x000002000
+
+/* BUS_CNTL register constants */
+#define BUS_FIFO_ERR_ACK 0x00200000
+#define BUS_HOST_ERR_ACK 0x00800000
+#define BUS_APER_REG_DIS 0x00000010
+
+/* GEN_TEST_CNTL register constants */
+#define GEN_OVR_OUTPUT_EN 0x20
+#define HWCURSOR_ENABLE 0x80
+#define GUI_ENGINE_ENABLE 0x100
+#define BLOCK_WRITE_ENABLE 0x200
+
+/* DSP_CONFIG register constants */
+#define DSP_XCLKS_PER_QW 0x00003fff
+#define DSP_LOOP_LATENCY 0x000f0000
+#define DSP_PRECISION 0x00700000
+
+/* DSP_ON_OFF register constants */
+#define DSP_OFF 0x000007ff
+#define DSP_ON 0x07ff0000
+
+/* SHARED_CNTL register constants */
+#define CTD_FIFO5 0x01000000
+
+/* CLOCK_CNTL register constants */
+#define CLOCK_SEL 0x0f
+#define CLOCK_DIV 0x30
+#define CLOCK_DIV1 0x00
+#define CLOCK_DIV2 0x10
+#define CLOCK_DIV4 0x20
+#define CLOCK_STROBE 0x40
+#define PLL_WR_EN 0x02
+
+/* PLL registers */
+#define PLL_MACRO_CNTL 0x01
+#define PLL_REF_DIV 0x02
+#define PLL_GEN_CNTL 0x03
+#define MCLK_FB_DIV 0x04
+#define PLL_VCLK_CNTL 0x05
+#define VCLK_POST_DIV 0x06
+#define VCLK0_FB_DIV 0x07
+#define VCLK1_FB_DIV 0x08
+#define VCLK2_FB_DIV 0x09
+#define VCLK3_FB_DIV 0x0A
+#define PLL_XCLK_CNTL 0x0B
+#define PLL_TEST_CTRL 0x0E
+#define PLL_TEST_COUNT 0x0F
+
+/* Memory types for CT, ET, VT, GT */
+#define DRAM 1
+#define EDO_DRAM 2
+#define PSEUDO_EDO 3
+#define SDRAM 4
+#define SGRAM 5
+#define SGRAM32 6
+
+#define DAC_INTERNAL 0x00
+#define DAC_IBMRGB514 0x01
+#define DAC_ATI68875 0x02
+#define DAC_TVP3026_A 0x72
+#define DAC_BT476 0x03
+#define DAC_BT481 0x04
+#define DAC_ATT20C491 0x14
+#define DAC_SC15026 0x24
+#define DAC_MU9C1880 0x34
+#define DAC_IMSG174 0x44
+#define DAC_ATI68860_B 0x05
+#define DAC_ATI68860_C 0x15
+#define DAC_TVP3026_B 0x75
+#define DAC_STG1700 0x06
+#define DAC_ATT498 0x16
+#define DAC_STG1702 0x07
+#define DAC_SC15021 0x17
+#define DAC_ATT21C498 0x27
+#define DAC_STG1703 0x37
+#define DAC_CH8398 0x47
+#define DAC_ATT20C408 0x57
+
+#define CLK_ATI18818_0 0
+#define CLK_ATI18818_1 1
+#define CLK_STG1703 2
+#define CLK_CH8398 3
+#define CLK_INTERNAL 4
+#define CLK_ATT20C408 5
+#define CLK_IBMRGB514 6
+
+/* DST_CNTL register constants */
+#define DST_X_RIGHT_TO_LEFT 0
+#define DST_X_LEFT_TO_RIGHT 1
+#define DST_Y_BOTTOM_TO_TOP 0
+#define DST_Y_TOP_TO_BOTTOM 2
+#define DST_X_MAJOR 0
+#define DST_Y_MAJOR 4
+#define DST_X_TILE 8
+#define DST_Y_TILE 0x10
+#define DST_LAST_PEL 0x20
+#define DST_POLYGON_ENABLE 0x40
+#define DST_24_ROTATION_ENABLE 0x80
+
+/* SRC_CNTL register constants */
+#define SRC_PATTERN_ENABLE 1
+#define SRC_ROTATION_ENABLE 2
+#define SRC_LINEAR_ENABLE 4
+#define SRC_BYTE_ALIGN 8
+#define SRC_LINE_X_RIGHT_TO_LEFT 0
+#define SRC_LINE_X_LEFT_TO_RIGHT 0x10
+
+/* HOST_CNTL register constants */
+#define HOST_BYTE_ALIGN 1
+
+/* DP_CHAIN_MASK register constants */
+#define DP_CHAIN_4BPP 0x8888
+#define DP_CHAIN_7BPP 0xD2D2
+#define DP_CHAIN_8BPP 0x8080
+#define DP_CHAIN_8BPP_RGB 0x9292
+#define DP_CHAIN_15BPP 0x4210
+#define DP_CHAIN_16BPP 0x8410
+#define DP_CHAIN_24BPP 0x8080
+#define DP_CHAIN_32BPP 0x8080
+
+/* DP_PIX_WIDTH register constants */
+#define DST_1BPP 0
+#define DST_4BPP 1
+#define DST_8BPP 2
+#define DST_15BPP 3
+#define DST_16BPP 4
+#define DST_32BPP 6
+#define SRC_1BPP 0
+#define SRC_4BPP 0x100
+#define SRC_8BPP 0x200
+#define SRC_15BPP 0x300
+#define SRC_16BPP 0x400
+#define SRC_32BPP 0x600
+#define HOST_1BPP 0
+#define HOST_4BPP 0x10000
+#define HOST_8BPP 0x20000
+#define HOST_15BPP 0x30000
+#define HOST_16BPP 0x40000
+#define HOST_32BPP 0x60000
+#define BYTE_ORDER_MSB_TO_LSB 0
+#define BYTE_ORDER_LSB_TO_MSB 0x1000000
+
+/* DP_SRC register constants */
+#define BKGD_SRC_BKGD_CLR 0
+#define BKGD_SRC_FRGD_CLR 1
+#define BKGD_SRC_HOST 2
+#define BKGD_SRC_BLIT 3
+#define BKGD_SRC_PATTERN 4
+#define FRGD_SRC_BKGD_CLR 0
+#define FRGD_SRC_FRGD_CLR 0x100
+#define FRGD_SRC_HOST 0x200
+#define FRGD_SRC_BLIT 0x300
+#define FRGD_SRC_PATTERN 0x400
+#define MONO_SRC_ONE 0
+#define MONO_SRC_PATTERN 0x10000
+#define MONO_SRC_HOST 0x20000
+#define MONO_SRC_BLIT 0x30000
+
+/* PCI IDs */
+#define ATI_VENDOR 0x1002
+#define ATI_MACH64_CT 0x4354 /* Mach64 CT */
+#define ATI_RAGE_PRO_AGP 0x4742 /* 3D Rage Pro (AGP) */
+#define ATI_RAGE_PRO_AGP1X 0x4744 /* 3D Rage Pro (AGP 1x) */
+#define ATI_RAGE_PRO_PCI_B 0x4749 /* 3D Rage Pro Turbo */
+#define ATI_RAGE_XC_PCI66 0x474c /* Rage XC (PCI66) */
+#define ATI_RAGE_XL_AGP 0x474d /* Rage XL (AGP) */
+#define ATI_RAGE_XC_AGP 0x474e /* Rage XC (AGP) */
+#define ATI_RAGE_XL_PCI66 0x474f /* Rage XL (PCI66) */
+#define ATI_RAGE_PRO_PCI_P 0x4750 /* 3D Rage Pro */
+#define ATI_RAGE_PRO_PCI_L 0x4751 /* 3D Rage Pro (limited 3D) */
+#define ATI_RAGE_XL_PCI 0x4752 /* Rage XL */
+#define ATI_RAGE_XC_PCI 0x4753 /* Rage XC */
+#define ATI_RAGE_II 0x4754 /* 3D Rage I/II */
+#define ATI_RAGE_IIP 0x4755 /* 3D Rage II+ */
+#define ATI_RAGE_IIC_PCI 0x4756 /* 3D Rage IIC */
+#define ATI_RAGE_IIC_AGP_B 0x4757 /* 3D Rage IIC (AGP) */
+#define ATI_RAGE_IIC_AGP_P 0x475a /* 3D Rage IIC (AGP) */
+#define ATI_RAGE_LT_PRO_AGP 0x4c42 /* 3D Rage LT Pro (AGP 133MHz) */
+#define ATI_RAGE_MOB_M3_PCI 0x4c45 /* Rage Mobility M3 */
+#define ATI_RAGE_MOB_M3_AGP 0x4c46 /* Rage Mobility M3 (AGP) */
+#define ATI_RAGE_LT 0x4c47 /* 3D Rage LT */
+#define ATI_RAGE_LT_PRO_PCI 0x4c49 /* 3D Rage LT Pro */
+#define ATI_RAGE_MOBILITY 0x4c4d /* Rage Mobility */
+#define ATI_RAGE_L_MOBILITY 0x4c4e /* Rage L Mobility */
+#define ATI_RAGE_LT_PRO 0x4c50 /* 3D Rage LT Pro */
+#define ATI_RAGE_LT_PRO2 0x4c51 /* 3D Rage LT Pro */
+#define ATI_RAGE_MOB_M1_PCI 0x4c52 /* Rage Mobility M1 (PCI) */
+#define ATI_RAGE_L_MOB_M1_PCI 0x4c53 /* Rage L Mobility (PCI) */
+#define ATI_MACH64_VT 0x5654 /* Mach64 VT */
+#define ATI_MACH64_VTB 0x5655 /* Mach64 VTB */
+#define ATI_MACH64_VT4 0x5656 /* Mach64 VT4 */
+
+#endif /* !_DEV_FB_MACHFB_H_ */
OpenPOWER on IntegriCloud