Index: arch/shark/conf/files.shark =================================================================== RCS file: /cvsroot/src/sys/arch/shark/conf/files.shark,v retrieving revision 1.17 diff -u -r1.17 files.shark --- arch/shark/conf/files.shark 20 Feb 2008 21:43:35 -0000 1.17 +++ arch/shark/conf/files.shark 18 May 2008 16:46:55 -0000 @@ -122,6 +122,10 @@ attach vga at ofbus with vga_ofbus file arch/shark/ofw/vga_ofbus.c vga_ofbus needs-flag +# ofbus Chips & Technologies +attach chipsfb at ofbus with chipsfb_ofbus +file arch/shark/ofw/chipsfb_ofbus.c chipsfb_ofbus needs-flag + # ofbus CyberPro attach igsfb at ofbus with igsfb_ofbus file arch/shark/ofw/igsfb_ofbus.c igsfb_ofbus needs-flag Index: conf/files =================================================================== RCS file: /cvsroot/src/sys/conf/files,v retrieving revision 1.905 diff -u -r1.905 files --- conf/files 5 May 2008 13:42:15 -0000 1.905 +++ conf/files 18 May 2008 16:46:55 -0000 @@ -1037,6 +1037,13 @@ file dev/ic/vga_raster.c vga_rasterconsole needs-flag file dev/ic/vga_subr.c vga | vga_rasterconsole file dev/ic/vga_common.c vga | vga_rasterconsole + +# Chips & Technologies 655x0 framebuffers (linear non-VGA mode) +# +device chipsfb: wsemuldisplaydev, wsrasteremulops, rasops8, vcons, videomode +file dev/ic/chipsfb.c chipsfb needs-flag +defflag opt_chipsfb.h CHIPSFB_DEBUG CHIPSFB_WAIT + # Integraphics Systems IGA168x and CyberPro framebuffers (linear non-VGA mode) # device igsfb: wsemuldisplaydev, wsrasteremulops, rasops8, vcons Index: dev/pci/files.pci =================================================================== RCS file: /cvsroot/src/sys/dev/pci/files.pci,v retrieving revision 1.303 diff -u -r1.303 files.pci --- dev/pci/files.pci 29 Mar 2008 00:16:26 -0000 1.303 +++ dev/pci/files.pci 18 May 2008 16:49:02 -0000 @@ -805,11 +805,8 @@ file dev/pci/cxgb_osdep.c cxgbc | cxgb # Chips & Technologies 65550 framebuffer console driver -device chipsfb: wsemuldisplaydev, rasops8, vcons, videomode -attach chipsfb at pci -file dev/pci/chipsfb.c chipsfb -defflag opt_chipsfb.h CHIPSFB_DEBUG -defflag opt_chipsfb.h CHIPSFB_WAIT +attach chipsfb at pci with chipsfb_pci +file dev/pci/chipsfb_pci.c chipsfb_pci # 3Com 3c990 device txp: ether, ifnet, arp --- /dev/null 2008-05-18 21:24:23.000000000 +0900 +++ arch/shark/ofw/chipsfb_ofbus.c 2007-09-20 01:15:21.000000000 +0900 @@ -0,0 +1,122 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 2006 Michael Lorenz + * 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. + */ + +/* + * ofbus attachment for Chips & Technologies 65550 graphics controllers + * found on some DNARD compatibles + */ + +#include +__KERNEL_RCSID(0, "$NetBSD$"); + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#define CHIPSFB_BASE 0x06800000 +#define CHIPSFB_SIZE (2 * 1024 * 1024) + +static int chipsfb_ofbus_match(struct device *, struct cfdata *, void *); +static void chipsfb_ofbus_attach(struct device *, struct device *, void *); + +CFATTACH_DECL(chipsfb_ofbus, sizeof(struct chipsfb_softc), + chipsfb_ofbus_match, chipsfb_ofbus_attach, NULL, NULL); + +static const char const *compat_strings[] = { "CHPS,ct65550", NULL }; + +vaddr_t chipsfb_mem_vaddr = 0; +vaddr_t chipsfb_mem_paddr; +struct bus_space chipsfb_memt; + +static int +chipsfb_ofbus_match(struct device *parent, struct cfdata *match, void *aux) +{ + struct ofbus_attach_args *oba = (void *)aux; + + if (of_compatible(oba->oba_phandle, compat_strings) < 0) + return 0; + + return 10; /* beat vga etc. */ +} + +static void +chipsfb_ofbus_attach(struct device *parent, struct device *self, void *aux) +{ + struct chipsfb_softc *sc = (void *)self; + struct ofbus_attach_args *oba = aux; + int chipsfb_node; + uint32_t regs[6]; + + chipsfb_node = oba->oba_phandle; + + if (OF_getprop(chipsfb_node, "reg", regs, sizeof(regs)) <= 0) { + printf(": can't get properties\n"); + return; + } + + sc->sc_memt = &isa_mem_bs_tag; /* XXX */ + sc->sc_iot = &isa_io_bs_tag; /* XXX */ + + /* the framebuffer */ + chipsfb_mem_paddr = CHIPSFB_BASE; + chipsfb_mem_vaddr = ofw_map(chipsfb_mem_paddr, CHIPSFB_SIZE, 0); + memcpy(&chipsfb_memt, sc->sc_memt, sizeof (struct bus_space)); + chipsfb_memt.bs_cookie = (void *)chipsfb_mem_vaddr; + + sc->sc_fbt = &chipsfb_memt; + sc->sc_fb = 0; + sc->sc_fbsize = CHIPSFB_SIZE; + + /* IO-mapped registers */ + if (bus_space_map(sc->sc_iot, CT_VGAREG_OFF, CT_VGAREG_SIZE, + 0, &sc->sc_ioregh) != 0) { + aprint_error("%s: failed to map IO registers.\n", + sc->sc_dev.dv_xname); + } + + chipsfb_attach(sc); +} --- /dev/null 2008-05-18 21:24:23.000000000 +0900 +++ dev/ic/chipsfb.c 2007-09-20 00:40:06.000000000 +0900 @@ -0,0 +1,910 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 2006 Michael Lorenz + * 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. + */ + +/* + * MI part of Chips & Technologies 65550 graphics controller driver + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: chipsfb.c,v 1.12 2007/08/19 15:57:24 he Exp $"); + +#include "opt_wsemul.h" +#include "opt_chipsfb.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +static struct vcons_screen chipsfb_console_screen; + +extern const u_char rasops_cmap[768]; + +static void chipsfb_init(struct chipsfb_softc *); + +static void chipsfb_cursor(void *, int, int, int); +static void chipsfb_copycols(void *, int, int, int, int); +static void chipsfb_erasecols(void *, int, int, int, long); +static void chipsfb_copyrows(void *, int, int, int); +static void chipsfb_eraserows(void *, int, int, long); + +#if 0 +static int chipsfb_allocattr(void *, int, int, int, long *); +static void chipsfb_scroll(void *, void *, int); +static int chipsfb_load_font(void *, void *, struct wsdisplay_font *); +#endif + +static int chipsfb_putcmap(struct chipsfb_softc *, + struct wsdisplay_cmap *); +static int chipsfb_getcmap(struct chipsfb_softc *, + struct wsdisplay_cmap *); +static int chipsfb_putpalreg(struct chipsfb_softc *, uint8_t, uint8_t, + uint8_t, uint8_t); + +static void chipsfb_bitblt(struct chipsfb_softc *, int, int, int, int, + int, int, uint8_t); +static void chipsfb_rectfill(struct chipsfb_softc *, int, int, int, int, + int); +static void chipsfb_putchar(void *, int, int, u_int, long); +static void chipsfb_setup_mono(struct chipsfb_softc *, int, int, int, + int, uint32_t, uint32_t); +static void chipsfb_feed(struct chipsfb_softc *, int, uint8_t *); + +#if 0 +static void chipsfb_showpal(struct chipsfb_softc *); +#endif +static void chipsfb_restore_palette(struct chipsfb_softc *); + +static void chipsfb_wait_idle(struct chipsfb_softc *); + +static uint32_t chipsfb_probe_vram(struct chipsfb_softc *); + +static int chipsfb_ioctl(void *, void *, u_long, void *, int, + struct lwp *); +static paddr_t chipsfb_mmap(void *, void *, off_t, int); +static void chipsfb_clearscreen(struct chipsfb_softc *); +static void chipsfb_init_screen(void *, struct vcons_screen *, int, long *); + +struct wsscreen_descr chipsfb_defaultscreen = { + "default", + 0, 0, + NULL, + 8, 16, + WSSCREEN_WSCOLORS | WSSCREEN_HILIT, +}; + +const struct wsscreen_descr *_chipsfb_scrlist[] = { + &chipsfb_defaultscreen, + /* XXX other formats, graphics screen? */ +}; + +struct wsscreen_list chipsfb_screenlist = { + sizeof(_chipsfb_scrlist) / sizeof(struct wsscreen_descr *), + _chipsfb_scrlist +}; + + +struct wsdisplay_accessops chipsfb_accessops = { + chipsfb_ioctl, + chipsfb_mmap, + NULL, /* load_font */ + NULL, /* polls */ + NULL, /* scroll */ +}; + +/* + * Inline functions for getting access to register aperture. + */ +static inline void +chipsfb_write32(struct chipsfb_softc *sc, uint32_t reg, uint32_t val) +{ + + bus_space_write_4(sc->sc_fbt, sc->sc_fbh, reg, val); +} + +static inline uint32_t +chipsfb_read32(struct chipsfb_softc *sc, uint32_t reg) +{ + + return bus_space_read_4(sc->sc_fbt, sc->sc_fbh, reg); +} + +static inline void +chipsfb_write_vga(struct chipsfb_softc *sc, uint32_t reg, uint8_t val) +{ + + bus_space_write_1(sc->sc_iot, sc->sc_ioregh, reg, val); +} + +static inline uint8_t +chipsfb_read_vga(struct chipsfb_softc *sc, uint32_t reg) +{ + + return bus_space_read_1(sc->sc_iot, sc->sc_ioregh, reg); +} + +static inline uint8_t +chipsfb_read_indexed(struct chipsfb_softc *sc, uint32_t reg, uint8_t index) +{ + + chipsfb_write_vga(sc, reg & 0xfffe, index); + return chipsfb_read_vga(sc, reg | 0x0001); +} + +static inline void +chipsfb_write_indexed(struct chipsfb_softc *sc, uint32_t reg, uint8_t index, + uint8_t val) +{ + + chipsfb_write_vga(sc, reg & 0xfffe, index); + chipsfb_write_vga(sc, reg | 0x0001, val); +} + +static void +chipsfb_wait_idle(struct chipsfb_softc *sc) +{ + +#ifdef CHIPSFB_DEBUG + chipsfb_write32(sc, CT_OFF_FB + (800 * 598) - 4, 0); +#endif + + /* spin until the blitter is idle */ + while ((chipsfb_read32(sc, CT_BLT_CONTROL) & BLT_IS_BUSY) != 0) { + } + +#ifdef CHIPSFB_DEBUG + chipsfb_write32(sc, CT_OFF_FB + (800 * 598) - 4, 0xffffffff); +#endif +} + +void +chipsfb_attach(struct chipsfb_softc *sc) +{ + struct wsemuldisplaydev_attach_args aa; + struct rasops_info *ri; + prop_dictionary_t dict; + ulong defattr; + bool console = false; + int width, height, i, j; + uint32_t bg, fg, ul; + + dict = device_properties(&sc->sc_dev); + sc->sc_mode = WSDISPLAYIO_MODE_EMUL; + sc->sc_dacw = -1; + +#ifdef CHIPSFB_DEBUG + printf(prop_dictionary_externalize(dict)); +#endif + + sc->memsize = chipsfb_probe_vram(sc); + chipsfb_init(sc); + + /* we should read these from the chip instead of depending on OF */ + width = height = -1; + + /* detect panel size */ + width = chipsfb_read_indexed(sc, CT_FP_INDEX, FP_HSIZE_LSB); + width |= (chipsfb_read_indexed(sc, CT_FP_INDEX, FP_HORZ_OVERFLOW_1) + & 0x0f) << 8; + width = (width + 1) * 8; + height = chipsfb_read_indexed(sc, CT_FP_INDEX, FP_VSIZE_LSB); + height |= (chipsfb_read_indexed(sc, CT_FP_INDEX, FP_VERT_OVERFLOW_1) + & 0x0f) << 8; + height++; + aprint_verbose("Panel size: %d x %d\n", width, height); + + if (!prop_dictionary_get_uint32(dict, "width", &sc->width)) + sc->width = width; + if (!prop_dictionary_get_uint32(dict, "height", &sc->height)) + sc->height = height; + if (!prop_dictionary_get_uint32(dict, "depth", &sc->bits_per_pixel)) + sc->bits_per_pixel = 8; + if (!prop_dictionary_get_uint32(dict, "linebytes", &sc->linebytes)) + sc->linebytes = (sc->width * sc->bits_per_pixel) >> 3; + + prop_dictionary_get_bool(dict, "is_console", &console); + +#ifdef notyet + /* XXX this should at least be configurable via kernel config */ + chipsfb_set_videomode(sc, &videomode_list[16]); +#endif + + vcons_init(&sc->vd, sc, &chipsfb_defaultscreen, &chipsfb_accessops); + sc->vd.init_screen = chipsfb_init_screen; + + ri = &chipsfb_console_screen.scr_ri; + if (console) { + vcons_init_screen(&sc->vd, &chipsfb_console_screen, 1, + &defattr); + chipsfb_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; + + chipsfb_defaultscreen.textops = &ri->ri_ops; + chipsfb_defaultscreen.capabilities = ri->ri_caps; + chipsfb_defaultscreen.nrows = ri->ri_rows; + chipsfb_defaultscreen.ncols = ri->ri_cols; + wsdisplay_cnattach(&chipsfb_defaultscreen, ri, 0, 0, defattr); + } else { + /* + * since we're not the console we can postpone the rest + * until someone actually allocates a screen for us + */ +#ifdef notyet + chipsfb_set_videomode(sc, &videomode_list[0]); +#endif + } + + rasops_unpack_attr(defattr, &fg, &bg, &ul); + sc->sc_bg = ri->ri_devcmap[bg]; + chipsfb_clearscreen(sc); + + aprint_normal("%s: %d MB aperture, %d MB VRAM at 0x%08x\n", + sc->sc_dev.dv_xname, (u_int)(sc->sc_fbsize >> 20), + (u_int)sc->memsize >> 20, (u_int)sc->sc_fb); +#ifdef CHIPSFB_DEBUG + aprint_debug("fb: %08lx\n", (ulong)ri->ri_bits); +#endif + + j = 0; + for (i = 0; i < 256; i++) { + chipsfb_putpalreg(sc, i, rasops_cmap[j], rasops_cmap[j + 1], + rasops_cmap[j + 2]); + j += 3; + } + + aa.console = console; + aa.scrdata = &chipsfb_screenlist; + aa.accessops = &chipsfb_accessops; + aa.accesscookie = &sc->vd; + + config_found(&sc->sc_dev, &aa, wsemuldisplaydevprint); +} + +static int +chipsfb_putpalreg(struct chipsfb_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; + + chipsfb_write_vga(sc, CT_DACMASK, 0xff); + chipsfb_write_vga(sc, CT_WRITEINDEX, index); + chipsfb_write_vga(sc, CT_DACDATA, r); + chipsfb_write_vga(sc, CT_DACDATA, g); + chipsfb_write_vga(sc, CT_DACDATA, b); + + return 0; +} + +static int +chipsfb_putcmap(struct chipsfb_softc *sc, struct wsdisplay_cmap *cm) +{ + u_char *r, *g, *b; + u_int index = cm->index; + u_int count = cm->count; + int i, error; + u_char rbuf[256], gbuf[256], bbuf[256]; + +#ifdef CHIPSFB_DEBUG + aprint_debug("putcmap: %d %d\n",index, count); +#endif + if (cm->index >= 256 || cm->count > 256 || + (cm->index + cm->count) > 256) + return EINVAL; + error = copyin(cm->red, &rbuf[index], count); + if (error) + return error; + error = copyin(cm->green, &gbuf[index], count); + if (error) + return error; + error = copyin(cm->blue, &bbuf[index], count); + if (error) + return error; + + memcpy(&sc->sc_cmap_red[index], &rbuf[index], count); + memcpy(&sc->sc_cmap_green[index], &gbuf[index], count); + memcpy(&sc->sc_cmap_blue[index], &bbuf[index], count); + + r = &sc->sc_cmap_red[index]; + g = &sc->sc_cmap_green[index]; + b = &sc->sc_cmap_blue[index]; + + for (i = 0; i < count; i++) { + chipsfb_putpalreg(sc, index, *r, *g, *b); + index++; + r++, g++, b++; + } + return 0; +} + +static int +chipsfb_getcmap(struct chipsfb_softc *sc, struct wsdisplay_cmap *cm) +{ + u_int index = cm->index; + u_int count = cm->count; + int error; + + if (index >= 255 || count > 256 || index + count > 256) + return EINVAL; + + error = copyout(&sc->sc_cmap_red[index], cm->red, count); + if (error) + return error; + error = copyout(&sc->sc_cmap_green[index], cm->green, count); + if (error) + return error; + error = copyout(&sc->sc_cmap_blue[index], cm->blue, count); + if (error) + return error; + + return 0; +} + +static void +chipsfb_clearscreen(struct chipsfb_softc *sc) +{ + chipsfb_rectfill(sc, 0, 0, sc->width, sc->height, sc->sc_bg); +} + +/* + * wsdisplay_emulops + */ + +static void +chipsfb_cursor(void *cookie, int on, int row, int col) +{ + struct rasops_info *ri = cookie; + struct vcons_screen *scr = ri->ri_hw; + struct chipsfb_softc *sc = scr->scr_cookie; + int x, y, wi, he; + + wi = ri->ri_font->fontwidth; + he = ri->ri_font->fontheight; + + if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { + x = ri->ri_ccol * wi + ri->ri_xorigin; + y = ri->ri_crow * he + ri->ri_yorigin; + if (ri->ri_flg & RI_CURSOR) { + chipsfb_bitblt(sc, x, y, x, y, wi, he, ROP_NOT_DST); + ri->ri_flg &= ~RI_CURSOR; + } + ri->ri_crow = row; + ri->ri_ccol = col; + if (on) { + x = ri->ri_ccol * wi + ri->ri_xorigin; + y = ri->ri_crow * he + ri->ri_yorigin; + chipsfb_bitblt(sc, x, y, x, y, wi, he, ROP_NOT_DST); + ri->ri_flg |= RI_CURSOR; + } + } else { + ri->ri_flg &= ~RI_CURSOR; + ri->ri_crow = row; + ri->ri_ccol = col; + } +} + +#if 0 +int +chipsfb_mapchar(void *cookie, int uni, u_int *index) +{ + return 0; +} +#endif + +static void +chipsfb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols) +{ + struct rasops_info *ri = cookie; + struct vcons_screen *scr = ri->ri_hw; + struct chipsfb_softc *sc = scr->scr_cookie; + int32_t xs, xd, y, width, height; + + if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { + xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol; + xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol; + y = ri->ri_yorigin + ri->ri_font->fontheight * row; + width = ri->ri_font->fontwidth * ncols; + height = ri->ri_font->fontheight; + chipsfb_bitblt(sc, xs, y, xd, y, width, height, ROP_COPY); + } +} + +static void +chipsfb_erasecols(void *cookie, int row, int startcol, int ncols, + long fillattr) +{ + struct rasops_info *ri = cookie; + struct vcons_screen *scr = ri->ri_hw; + struct chipsfb_softc *sc = scr->scr_cookie; + int32_t x, y, width, height, fg, bg, ul; + + if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { + x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol; + y = ri->ri_yorigin + ri->ri_font->fontheight * row; + width = ri->ri_font->fontwidth * ncols; + height = ri->ri_font->fontheight; + rasops_unpack_attr(fillattr, &fg, &bg, &ul); + + chipsfb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]); + } +} + +static void +chipsfb_copyrows(void *cookie, int srcrow, int dstrow, int nrows) +{ + struct rasops_info *ri = cookie; + struct vcons_screen *scr = ri->ri_hw; + struct chipsfb_softc *sc = scr->scr_cookie; + int32_t x, ys, yd, width, height; + + if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { + x = ri->ri_xorigin; + ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow; + yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow; + width = ri->ri_emuwidth; + height = ri->ri_font->fontheight * nrows; + chipsfb_bitblt(sc, x, ys, x, yd, width, height, ROP_COPY); + } +} + +static void +chipsfb_eraserows(void *cookie, int row, int nrows, long fillattr) +{ + struct rasops_info *ri = cookie; + struct vcons_screen *scr = ri->ri_hw; + struct chipsfb_softc *sc = scr->scr_cookie; + int32_t x, y, width, height, fg, bg, ul; + + if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { + rasops_unpack_attr(fillattr, &fg, &bg, &ul); + if ((row == 0) && (nrows == ri->ri_rows)) { + /* clear the whole screen */ + chipsfb_rectfill(sc, 0, 0, ri->ri_width, + ri->ri_height, ri->ri_devcmap[bg]); + } else { + x = ri->ri_xorigin; + y = ri->ri_yorigin + ri->ri_font->fontheight * row; + width = ri->ri_emuwidth; + height = ri->ri_font->fontheight * nrows; + chipsfb_rectfill(sc, x, y, width, height, + ri->ri_devcmap[bg]); + } + } +} + +static void +chipsfb_bitblt(struct chipsfb_softc *sc, int xs, int ys, int xd, int yd, + int width, int height, uint8_t rop) +{ + uint32_t src, dst, cmd = rop, stride, size; + + cmd |= BLT_PAT_IS_SOLID; + + /* we assume 8 bit for now */ + src = xs + ys * sc->linebytes; + dst = xd + yd * sc->linebytes; + + if (xs < xd) { + /* right-to-left operation */ + cmd |= BLT_START_RIGHT; + src += width - 1; + dst += width - 1; + } + + if (ys < yd) { + /* bottom-to-top operation */ + cmd |= BLT_START_BOTTOM; + src += (height - 1) * sc->linebytes; + dst += (height - 1) * sc->linebytes; + } + + stride = (sc->linebytes << 16) | sc->linebytes; + size = (height << 16) | width; + + chipsfb_wait_idle(sc); + chipsfb_write32(sc, CT_BLT_STRIDE, stride); + chipsfb_write32(sc, CT_BLT_SRCADDR, src); + chipsfb_write32(sc, CT_BLT_DSTADDR, dst); + chipsfb_write32(sc, CT_BLT_CONTROL, cmd); + chipsfb_write32(sc, CT_BLT_SIZE, size); +#ifdef CHIPSFB_WAIT + chipsfb_wait_idle(sc); +#endif +} + +static void +chipsfb_rectfill(struct chipsfb_softc *sc, int x, int y, int width, + int height, int colour) +{ + uint32_t dst, cmd, stride, size; + + cmd = BLT_PAT_IS_SOLID | BLT_PAT_IS_MONO | ROP_PAT; + + /* we assume 8 bit for now */ + dst = x + y * sc->linebytes; + + stride = (sc->linebytes << 16) | sc->linebytes; + size = (height << 16) | width; + + chipsfb_wait_idle(sc); + chipsfb_write32(sc, CT_BLT_STRIDE, stride); + chipsfb_write32(sc, CT_BLT_SRCADDR, dst); + chipsfb_write32(sc, CT_BLT_DSTADDR, dst); + chipsfb_write32(sc, CT_BLT_CONTROL, cmd); + chipsfb_write32(sc, CT_BLT_BG, colour); + chipsfb_write32(sc, CT_BLT_FG, colour); + chipsfb_write32(sc, CT_BLT_SIZE, size); +#ifdef CHIPSFB_WAIT + chipsfb_wait_idle(sc); +#endif +} + +static void +chipsfb_putchar(void *cookie, int row, int col, u_int c, long attr) +{ + struct rasops_info *ri = cookie; + struct vcons_screen *scr = ri->ri_hw; + struct chipsfb_softc *sc = scr->scr_cookie; + + if (__predict_false((unsigned int)row > ri->ri_rows || + (unsigned int)col > ri->ri_cols)) + return; + + if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { + uint8_t *data; + int fg, bg, uc; + int x, y, wi, he; + + wi = ri->ri_font->fontwidth; + he = ri->ri_font->fontheight; + + if (!CHAR_IN_FONT(c, ri->ri_font)) + return; + bg = (u_char)ri->ri_devcmap[(attr >> 16) & 0xf]; + fg = (u_char)ri->ri_devcmap[(attr >> 24) & 0xf]; + x = ri->ri_xorigin + col * wi; + y = ri->ri_yorigin + row * he; + if (c == 0x20) { + chipsfb_rectfill(sc, x, y, wi, he, bg); + } else { + uc = c-ri->ri_font->firstchar; + data = (uint8_t *)ri->ri_font->data + uc * + ri->ri_fontscale; + chipsfb_setup_mono(sc, x, y, wi, he, fg, bg); + chipsfb_feed(sc, ri->ri_font->stride * he, data); + } + } +} + +static void +chipsfb_setup_mono(struct chipsfb_softc *sc, int xd, int yd, int width, + int height, uint32_t fg, uint32_t bg) +{ + uint32_t dst, cmd, stride, size; + + cmd = BLT_PAT_IS_SOLID | BLT_SRC_IS_CPU | BLT_SRC_IS_MONO | ROP_COPY; + + /* we assume 8 bit for now */ + dst = xd + yd * sc->linebytes; + + stride = (sc->linebytes << 16); + size = (height << 16) | width; + + chipsfb_wait_idle(sc); + chipsfb_write32(sc, CT_BLT_STRIDE, stride); + chipsfb_write32(sc, CT_BLT_EXPCTL, MONO_SRC_ALIGN_BYTE); + chipsfb_write32(sc, CT_BLT_DSTADDR, dst); + chipsfb_write32(sc, CT_BLT_SRCADDR, 0); + chipsfb_write32(sc, CT_BLT_CONTROL, cmd); + chipsfb_write32(sc, CT_BLT_BG, bg); + chipsfb_write32(sc, CT_BLT_FG, fg); + chipsfb_write32(sc, CT_BLT_SIZE, size); +} + +static void +chipsfb_feed(struct chipsfb_softc *sc, int count, uint8_t *data) +{ + int i; + uint32_t latch = 0, bork; + int shift = 0; + + for (i = 0; i < count; i++) { + bork = data[i]; + latch |= (bork << shift); + if (shift == 24) { + chipsfb_write32(sc, CT_OFF_DATA, latch); + latch = 0; + shift = 0; + } else + shift += 8; + } + + if (shift != 0) { + chipsfb_write32(sc, CT_OFF_DATA, latch); + } + + /* apparently the chip wants 64bit-aligned data or it won't go idle */ + if ((count + 3) & 0x04) { + chipsfb_write32(sc, CT_OFF_DATA, 0); + } +#ifdef CHIPSFB_WAIT + chipsfb_wait_idle(sc); +#endif +} + +#if 0 +static void +chipsfb_showpal(struct chipsfb_softc *sc) +{ + int i, x = 0; + + for (i = 0; i < 16; i++) { + chipsfb_rectfill(sc, x, 0, 64, 64, i); + x += 64; + } +} +#endif + +#if 0 +static int +chipsfb_allocattr(void *cookie, int fg, int bg, int flags, long *attrp) +{ + + return 0; +} +#endif + +static void +chipsfb_restore_palette(struct chipsfb_softc *sc) +{ + int i; + + for (i = 0; i < 256; i++) { + chipsfb_putpalreg(sc, + i, + sc->sc_cmap_red[i], + sc->sc_cmap_green[i], + sc->sc_cmap_blue[i]); + } +} + +/* + * wsdisplay_accessops + */ + +static int +chipsfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, + struct lwp *l) +{ + struct vcons_data *vd = v; + struct chipsfb_softc *sc = vd->cookie; + struct wsdisplay_fbinfo *wdf; + struct vcons_screen *ms = vd->active; + + switch (cmd) { + case WSDISPLAYIO_GTYPE: + *(u_int *)data = WSDISPLAY_TYPE_PCIMISC; + return 0; + + case WSDISPLAYIO_GINFO: + wdf = (void *)data; + wdf->height = ms->scr_ri.ri_height; + wdf->width = ms->scr_ri.ri_width; + wdf->depth = ms->scr_ri.ri_depth; + wdf->cmsize = 256; + return 0; + + case WSDISPLAYIO_GETCMAP: + return chipsfb_getcmap(sc, + (struct wsdisplay_cmap *)data); + + case WSDISPLAYIO_PUTCMAP: + return chipsfb_putcmap(sc, + (struct wsdisplay_cmap *)data); + +#if 0 + /* PCI config read/write passthrough. */ + case PCI_IOC_CFGREAD: + case PCI_IOC_CFGWRITE: + return (pci_devioctl(sc->sc_pc, sc->sc_pcitag, + cmd, data, flag, l)); +#endif + + case WSDISPLAYIO_SMODE: + { + int new_mode = *(int*)data; + if (new_mode != sc->sc_mode) { + sc->sc_mode = new_mode; + if(new_mode == WSDISPLAYIO_MODE_EMUL) { + chipsfb_restore_palette(sc); + vcons_redraw_screen(ms); + } + } + } + return 0; + } + return EPASSTHROUGH; +} + +static paddr_t +chipsfb_mmap(void *v, void *vs, off_t offset, int prot) +{ + struct vcons_data *vd = v; + struct chipsfb_softc *sc = vd->cookie; + struct lwp *me; + paddr_t pa; + + /* 'regular' framebuffer mmap()ing */ + if (offset < sc->memsize) { + pa = bus_space_mmap(sc->sc_fbt, offset, 0, prot, + BUS_SPACE_MAP_LINEAR); + return pa; + } + + /* + * restrict all other mappings to processes with superuser privileges + * or the kernel itself + */ + me = curlwp; + if (me != NULL) { + if (kauth_authorize_generic(me->l_cred, KAUTH_GENERIC_ISSUSER, + NULL) != 0) { + aprint_normal("%s: mmap() rejected.\n", sc->sc_dev.dv_xname); + return -1; + } + } + + if ((offset >= sc->sc_fb) && (offset < (sc->sc_fb + sc->sc_fbsize))) { + pa = bus_space_mmap(sc->sc_memt, offset, 0, prot, + BUS_SPACE_MAP_LINEAR); + return pa; + } + +#ifdef macppc + /* allow mapping of IO space */ + if ((offset >= 0xf2000000) && (offset < 0xf2800000)) { + pa = bus_space_mmap(sc->sc_iot, offset - 0xf2000000, 0, prot, + BUS_SPACE_MAP_LINEAR); + return pa; + } +#endif + +#ifdef OFB_ALLOW_OTHERS + if (offset >= 0x80000000) { + pa = bus_space_mmap(sc->sc_memt, offset, 0, prot, + BUS_SPACE_MAP_LINEAR); + return pa; + } +#endif + return -1; +} + +static void +chipsfb_init_screen(void *cookie, struct vcons_screen *scr, + int existing, long *defattr) +{ + struct chipsfb_softc *sc = cookie; + struct rasops_info *ri = &scr->scr_ri; + + ri->ri_depth = sc->bits_per_pixel; + ri->ri_width = sc->width; + ri->ri_height = sc->height; + ri->ri_stride = sc->width; + ri->ri_flg = RI_CENTER | RI_FULLCLEAR; + + ri->ri_bits = bus_space_vaddr(sc->sc_fbt, sc->sc_fbh); + +#ifdef CHIPSFB_DEBUG + aprint_debug("addr: %08lx\n", (ulong)ri->ri_bits); +#endif + if (existing) { + ri->ri_flg |= RI_CLEAR; + } + + rasops_init(ri, sc->height/8, sc->width/8); + ri->ri_caps = WSSCREEN_WSCOLORS; + + rasops_reconfig(ri, sc->height / ri->ri_font->fontheight, + sc->width / ri->ri_font->fontwidth); + + ri->ri_hw = scr; + ri->ri_ops.copyrows = chipsfb_copyrows; + ri->ri_ops.copycols = chipsfb_copycols; + ri->ri_ops.eraserows = chipsfb_eraserows; + ri->ri_ops.erasecols = chipsfb_erasecols; + ri->ri_ops.cursor = chipsfb_cursor; + ri->ri_ops.putchar = chipsfb_putchar; +} + +#if 0 +int +chipsfb_load_font(void *v, void *cookie, struct wsdisplay_font *data) +{ + + return 0; +} +#endif + +static void +chipsfb_init(struct chipsfb_softc *sc) +{ + + chipsfb_wait_idle(sc); + + chipsfb_write_indexed(sc, CT_CONF_INDEX, XR_IO_CONTROL, + ENABLE_CRTC_EXT | ENABLE_ATTR_EXT); + chipsfb_write_indexed(sc, CT_CONF_INDEX, XR_ADDR_MAPPING, + ENABLE_LINEAR); + + /* setup the blitter */ +} + +static uint32_t +chipsfb_probe_vram(struct chipsfb_softc *sc) +{ + uint32_t ofs = 0x00080000; /* 512kB */ + + /* + * advance in 0.5MB steps, see if we can read back what we wrote and + * if what we wrote to 0 is left untouched. Max. fb size is 4MB so + * we voluntarily stop there. + */ + chipsfb_write32(sc, 0, 0xf0f0f0f0); + chipsfb_write32(sc, ofs, 0x0f0f0f0f); + while ((chipsfb_read32(sc, 0) == 0xf0f0f0f0) && + (chipsfb_read32(sc, ofs) == 0x0f0f0f0f) && + (ofs < 0x00400000)) { + + ofs += 0x00080000; + chipsfb_write32(sc, ofs, 0x0f0f0f0f); + } + + return ofs; +} --- /dev/null 2008-05-18 21:24:23.000000000 +0900 +++ dev/ic/chipsfbreg.h 2007-09-20 00:25:07.000000000 +0900 @@ -0,0 +1,436 @@ +/* $NetBSD: chipsfbreg.h,v 1.2 2006/09/27 05:19:23 macallan Exp $ */ + +/* + * Copyright 2006 by Michael Lorenz. + * + * 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. + * +*/ + +#ifndef CHIPSFB_H +#define CHIPSFB_H + +#define CT_VGAREG_OFF 0x3c0 +#define CT_VGAREG_SIZE 0x20 + +/* VGA */ +#define CRTC_INDEX 0x14 +#define CRTC_DATA 0x15 +#define SEQ_INDEX 0x04 +#define SEQ_DATA 0x05 +#define MISC_W 0x02 +#define GRA_INDEX 0x0e +#define GRA_DATA 0x0f +#define ATT_IW 0x00 + +/* palette */ +#define CT_DACMASK 0x06 +#define CT_DACSTATE 0x07 /* read only */ +#define CT_READINDEX 0x07 /* write only */ +#define CT_WRITEINDEX 0x08 +#define CT_DACDATA 0x09 + +/* extended VGA */ +#define CT_FP_INDEX 0x10 +#define CT_FP_DATA 0x11 +#define CT_MM_INDEX 0x12 +#define CT_MM_DATA 0x13 +#define CT_CONF_INDEX 0x16 +#define CT_CONF_DATA 0x17 + +/* offsets in aperture */ +#define CT_OFF_FB 0x00000000 +#define CT_OFF_BITBLT 0x00400000 +#define CT_OFF_DRAW 0x00400040 +#define CT_OFF_DATA 0x00410000 + +#define CT_OFF_BE 0x00800000 + +/* blitter registers */ +#define CT_BLT_STRIDE CT_OFF_BITBLT + /* + * upper 16 bit are destination stride in bytes + * lower 16 bit are source stride in bytes + */ + +#define CT_BLT_BG CT_OFF_BITBLT + 0x04 +#define CT_BLT_FG CT_OFF_BITBLT + 0x08 +#define CT_BLT_EXPCTL CT_OFF_BITBLT + 0x0c /* expansion control */ + #define LEFT_CLIPPING_MSK 0x0000003f + #define MONO_RIGHT_CLIPPING_MSK 0x00003f00 + #define MONO_INITIAL_DISCARD 0x003f0000 + #define MONO_SRC_ALIGN_MASK 0x07000000 + #define MONO_SRC_ALIGN_BIT 0x01000000 + #define MONO_SRC_ALIGN_BYTE 0x02000000 + #define MONO_SRC_ALIGN_WORD 0x03000000 + #define MONO_SRC_ALIGN_LONG 0x04000000 + #define MONO_SRC_ALIGN_LONGLONG 0x05000000 + #define MONO_SELECT_ALT_FG_BG 0x08000000 /* use CT_SRC_EXP_* */ + +#define CT_BLT_CONTROL CT_OFF_BITBLT + 0x10 + #define BLT_ROP_MASK 0x000000ff + #define BLT_START_RIGHT 0x00000100 /* 0 for start left */ + #define BLT_START_BOTTOM 0x00000200 /* 0 for start top */ + #define BLT_SRC_IS_CPU 0x00000400 /* 0 for vram source */ + #define BLT_SRC_IS_MONO 0x00001000 + #define BLT_MONO_TRANSPARENCY 0x00002000 + #define BLT_COLOR_COMPARE_MASK 0x0001c000 /* 0 for no color keying */ + #define BLT_PAT_TRANSPARENCY 0x00020000 /* pattern is transparent */ + #define BLT_PAT_IS_MONO 0x00040000 + #define BLT_PAT_IS_SOLID 0x00080000 /* ignore pattern */ + #define BLT_PAT_VERT_ALIGN_MASK 0x00700000 + #define BLT_IS_BUSY 0x80000000 + +#define ROP_COPY 0xcc +#define ROP_NOT_SRC 0x33 +#define ROP_NOT_DST 0x55 +#define ROP_PAT 0xf0 + +#define CT_BLT_PATTERN CT_OFF_BITBLT + 0x14 /* address in vram */ +#define CT_BLT_SRCADDR CT_OFF_BITBLT + 0x18 +#define CT_BLT_DSTADDR CT_OFF_BITBLT + 0x1c + +#define CT_BLT_SIZE CT_OFF_BITBLT + 0x20 /* width and height */ +/* + * upper 16 bit are destination height + * lower 16 bit are destination width in bytes + */ + +#define CT_SRC_EXP_BG CT_OFF_BITBLT + 0x24 +#define CT_SRC_EXP_FG CT_OFF_BITBLT + 0x28 + +/* extension registers ( via CT_CONF */ +#define XR_VENDOR_LO 0x00 +#define XR_VENDOR_HI 0x01 +#define XR_DEVICE_LO 0x02 +#define XR_DEVICE_HI 0x03 +#define XR_REVISION 0x04 +#define XR_LINEAR_BASE_LO 0x05 +#define XR_LINEAR_BASE_HI 0x06 + +#define XR_CONFIGURATION 0x08 + #define BUS_PCI 0x01 + #define BUS_VL 0x00 + #define ENABLE_PCI 0x02 + +#define XR_IO_CONTROL 0x09 + #define ENABLE_CRTC_EXT 0x01 + #define ENABLE_ATTR_EXT 0x02 + +#define XR_ADDR_MAPPING 0x0a + #define ENABLE_MAPPING 0x01 /* in VGA window */ + #define ENABLE_LINEAR 0x02 + #define ENABLE_PACKED 0x04 + #define FB_SWAP_NONE 0x00 + #define FB_SWAP_16 0x10 + #define FB_SWAP_32 0x20 + +#define XR_BURST_WRITE_MODE 0x0b + +#define XR_PAGE_SELECT 0x0e + +#define XR_BITBLT_CONTROL0 0x20 + #define BLITTER_BUSY 0x01 + #define BLITTER_RESET 0x02 + #define BLITTER_8BIT 0x00 + #define BLITTER_16BIT 0x10 + #define BLITTER_24BIT 0x20 + #define BLITTER_32BIT 0x30 /* reserved */ + +#define XR_DRAM_ACCESS_CONTROL 0x40 + #define ENABLE_64BIT 0x01 + #define DISABLE_WRAP 0x02 /* otherwise only 256kB */ + #define EXTENDED_TEXT 0x10 + +#define XR_DRAM_TYPE 0x41 + #define DRAM_FASTPAGE 0x00 + #define DRAM_EDO 0x01 + +#define XR_DRAM_CONFIG 0x42 + #define DRAM_8BIT_COL 0x00 + #define DRAM_9BIT_COL 0x01 + +#define XR_DRAM_INTERFACE 0x43 +#define XR_DRAM_TIMING 0x44 + +#define XR_VIDEO_PIN_CONTROL 0x60 +#define XR_DDC_SYNC_SELECT 0x61 + #define DDC_HSYNC_DATA 0x01 + #define DDC_HSYNC_OUT 0x02 /* hsync is controlled by above */ + #define DDC_VSYNC_DATA 0x04 + #define DDC_VSYNC_OUT 0x08 /* vsync is controlled by above */ + #define DDC_HV_POWERDOWN 0x10 + #define DDC_ENABLE_HSYNC 0x20 + #define DDC_ENABLE_VSYNC 0x40 + +/* + * upper 6 bit define if corresponding bits in DATA are input or output + * 1 selects output + */ +#define XR_GPIO_CONTROL 0x62 +#define XR_GPIO_DATA 0x63 + +#define XR_PIN_TRISTATE_CONTROL 0x67 + +#define XR_CONFIG_PINS_0 0x70 +#define XR_CONFIG_PINS_1 0x71 + +#define XR_PIXEL_PIPELINE_CTL_0 0x80 + #define ENABLE_EXTENDED_PALETTE 0x01 + #define ENABLE_CRT_OVERSCAN 0x02 + #define ENABLE_PANEL_OVERSCAN 0x04 + #define ENABLE_EXTENDED_STATUS 0x08 + #define ENABLE_CURSOR_1 0x10 + #define ENABLE_PIXEL_AVERAGING 0x20 + #define SELECT_PIXEL_STREAM 0x40 /* 1 for P1 */ + #define ENABLE_8BIT_DAC 0x80 /* 6 bit otherwise */ + +#define XR_PIXEL_PIPELINE_CTL_1 0x81 + #define COLOR_VGA 0x00 + #define COLOR_8BIT_EXTENDED 0x02 + #define COLOR_15BIT 0x04 + #define COLOR_16BIT 0x05 + #define COLOR_24BIT 0x06 + #define COLOR_32BIT 0x07 + +#define XR_PIXEL_PIPELINE_CTL_2 0x82 + #define ENABLE_BLANK_PEDESTAL 0x01 + #define ENABLE_SYNY_ON_GREEN 0x02 + #define ENABLE_VIDEO_GAMMA 0x04 + #define ENABLE_GRAPHICS_GAMMA 0x08 + +#define XR_CURSOR_1_CTL 0xa0 +#define XR_CURSOR_1_VERT_EXT 0xa1 +#define XR_CURSOR_1_BASEADDR_LO 0xa2 +#define XR_CURSOR_1_BASEADDR_HI 0xa3 +#define XR_CURSOR_1_X_LO 0xa4 +#define XR_CURSOR_1_X_HI 0xa5 +#define XR_CURSOR_1_Y_LO 0xa6 +#define XR_CURSOR_1_Y_HI 0xa7 + +#define XR_CURSOR_2_CTL 0xa8 +#define XR_CURSOR_2_VERT_EXT 0xa9 +#define XR_CURSOR_2_BASEADDR_LO 0xaa +#define XR_CURSOR_2_BASEADDR_HI 0xab +#define XR_CURSOR_2_X_LO 0xac +#define XR_CURSOR_2_X_HI 0xad +#define XR_CURSOR_2_Y_LO 0xae +#define XR_CURSOR_2_Y_HI 0xaf + +#define XR_VCLOCK_0_M 0xc0 +#define XR_VCLOCK_0_N 0xc1 +#define XR_VCLOCK_0_MN_MSBS 0xc2 +#define XR_VCLOCK_0_DIV_SELECT 0xc3 + +#define XR_VCLOCK_1_M 0xc4 +#define XR_VCLOCK_1_N 0xc5 +#define XR_VCLOCK_1_MN_MSBS 0xc6 +#define XR_VCLOCK_1_DIV_SELECT 0xc7 + +#define XR_VCLOCK_2_M 0xc8 +#define XR_VCLOCK_2_N 0xc9 +#define XR_VCLOCK_2_MN_MSBS 0xca +#define XR_VCLOCK_2_DIV_SELECT 0xcb + +#define XR_MEMCLOCK_M 0xcc +#define XR_MEMCLOCK_N 0xcd +#define XR_MEMCLOCK_DIV_SELECT 0xce +#define XR_CLOCK_CONFIG 0xcf + +#define XR_MODULE_POWER_DOWN 0xd0 +#define XR_DOWN_COUNTER 0xd2 + +#define XR_SOFTWARE_FLAG_0 0xe0 +#define XR_SOFTWARE_FLAG_1 0xe1 +#define XR_SOFTWARE_FLAG_2 0xe2 +#define XR_SOFTWARE_FLAG_3 0xe3 +#define XR_SOFTWARE_FLAG_4 0xe4 +#define XR_SOFTWARE_FLAG_5 0xe5 +#define XR_SOFTWARE_FLAG_6 0xe6 +#define XR_SOFTWARE_FLAG_7 0xe7 + +#define XR_TEST_BLOCK_SELECT 0xf8 +#define XR_TEST_CONTROL_PORT 0xf9 +#define XR_TEST_DATA_PORT 0xfa +#define XR_SCAN_TEST_CONTROL_0 0xfb +#define XR_SCAN_TEST_CONTROL_1 0xfc + +/* flat panel control registers, via CT_FP_* */ +#define FP_FEATURE 0x00 + #define PANEL_EXISTS 0x01 + #define POPUP_EXISTS 0x04 + +#define FP_CRT_FP_CONTROL 0x01 + #define ENABLE_CRT 0x01 + #define ENABLE_PANEL 0x02 + +#define FP_MODE_CONTROL 0x02 +#define FP_DOT_CLOCK_SOURCE 0x03 + #define FP_CLOCK_0 0x00 + #define FP_CLOCK_1 0x04 + #define FP_CLOCK_2 0x08 + #define USE_VIDEO_CLOCK 0x00 + #define USE_MEM_CLOCK 0x10 + +#define FP_POWER_SEQ_DELAY 0x04 +/* + * upper 4 bits select power up delay in 3.4ms increments + * lower 4 bits select power down delay in 29ms increments + */ + +#define FP_POWER_DOWN_CTL_1 0x05 +/* the lower 3 bits select how many refresh cycles per scanline are preformed */ + #define PANEL_POWER_OFF 0x08 + #define HOST_STANDBY 0x10 + #define PANEL_TRISTATE 0x20 + #define NO_SEFL_REFRESH 0x40 + #define PANEL_INACTIVE 0x80 + +/* these bits are effective when the panel is powered down */ +#define FP_POWER_DOWN_CTL_0 0x06 + #define FP_VGA_PALETTE_POWERDOWN 0x01 + #define FP_VGA_PALETTE_ENABLE 0x02 + #define FP_ENABLE_SYNC 0x04 + +#define FP_PIN_POLARITY 0x08 + #define FP_DISPLAY_NEGATIVE 0x02 + #define FP_HSYNC_NEGATIVE 0x04 + #define FP_VSYNC_NEGATIVE 0x08 + #define FP_TEXT_VIDEO_INVERT 0x10 + #define FP_GRAPHICS_INVERT 0x20 + #define CRT_HSYNC_NEGATIVE 0x40 + #define CRT_VSYNC_NEGATIVE 0x80 + +#define FP_OUTPUT_DRIVE 0x0a + #define VL_THRESHOLD_5V 0x02 /* 3.3v otherwise */ + #define FP_DRIVE_HIGH 0x04 /* req. with 3.3v */ + #define BUS_INTERFACE_LOW 0x08 /* req. with 3.3v */ + #define MEM_DRIVE_HIGHER 0x10 + #define MEM_C_DRIVE_HIGHER 0x20 + #define SYNC_DRIVE_HIGHER 0x40 + +#define FP_PIN_CONTROL_1 0x0b + #define DISPLAY_ENABLE_ON_69 0x01 /* M signal otherwise */ + #define DISPLAY_ENABLE_ON_68 0x02 /* FP Hsync otherwise */ + #define COMPOSITE_SYNC_ON_65 0x04 /* separate otherwise */ + #define BACKLIGHT_ON_61 0x08 /* on 54 otherwise */ + #define GPIO_ON_154 0x10 + #define SIMPLE_COMPOSITE_SYNC 0x20 + #define MEM_C_TRISTATE 0x80 + +#define FP_PIN_CONTROL_2 0x0c + #define ACTI_ON_53 0x00 + #define COMPOSITE_SYNC_ON_53 0x08 + #define GPIO_IN_ON_53 0x10 + #define GPIO_OUT_ON_53 0x18 + #define ENABKL_ON_54 0x00 + #define COMPOSITE_SYNC_ON_54 0x40 + #define GPIO_IN_ON_54 0x80 + #define GPIO_OUT_ON_54 0xc0 + +#define FP_ACTIVITY_CONTROL 0x0f +/* the lower 5 bits select a timeout in 28.1s increments */ + #define PANEL_OFF_ON_TIMEOUT 0x40 /* backlight off otherwise */ + #define ENABLE_ACTIVITY_TIMER 0x80 + +#define FP_PANEL_FORMAT_0 0x10 + #define SINGLE_PANEL_SINGLE_DRIVE 0x00 + #define DUAL_PANEL_DUAL_DRIVE 0x03 + #define MONO_NTSC 0x00 + #define MONO_EQUIV_WEIGHT 0x04 + #define MONO_GREEN_ONLY 0x08 + #define COLOUR_PANEL 0x0c + #define SHIFT_CLOCK_DIVIDER_MASK 0x70 + +#define FP_PANEL_FORMAT_1 0x11 + +#define FP_PANEL_FORMAT_2 0x12 +#define FP_PANEL_FORMAT_3 0x13 + +#define FP_FRC_OPTION_SELECT 0x16 +#define FP_POLYNOMIAL_FRC_CTL 0x17 + +#define FP_TEXTMODE_CONTROL 0x18 +#define FP_BLINK_RATE_CONTROL 0x19 +#define FP_FB_CONTROL 0x1a + +#define FP_ACDCLK_CONTROL 0x1e +#define FP_DIAGNOSTIC 0x1f + +#define FP_HSIZE_LSB 0x20 /* panel size - 1 */ +#define FP_HSYNC_START 0x21 /* value - 1 */ +#define FP_HSYNC_END 0x22 +#define FP_HTOTAL_LSB 0x23 /* value - 5 */ +#define FP_HSYNC_DELAY_LSB 0x24 +#define FP_HORZ_OVERFLOW_1 0x25 +/* + * upper 4 bits are upper 4 bits of FP_HSYNC_START + * lower 4 bits are upper 4 bits of FP_HSIZE_LSB + */ + +#define FP_HORZ_OVERFLOW_2 0x26 +/* + * upper 4 bits are upper 4 bits of FP_HSYNC_DELAY_LSB + * lower 4 bits are upper 4 bits of FP_HTOTAL_LSB + */ + +#define FP_HSYNC_WIDTH_DISABLE 0x27 +/* lower 7 bits are HSYNC width - 1 */ + #define DELAY_DISABLE 0x80 + +#define FP_VSIZE_LSB 0x30 /* panel size - 1 */ +#define FP_VSYNC_START 0x31 /* value - 1 */ +#define FP_VSYNC_END 0x32 /* value - 1 */ +#define FP_VTOTAL_LSB 0x33 /* value - 2 */ +#define FP_VSYNC_DELAY_LSB 0x34 /* value - 1 */ +#define FP_VERT_OVERFLOW_1 0x35 +/* + * upper 4 bits are upper 4 bits of FP_VSYNC_START + * lower 4 bits are upper 4 bits of FP_VSIZE_LSB + */ + +#define FP_VERT_OVERFLOW_2 0x36 +/* + * upper 4 bits are upper 4 bits of FP_VSYNC_DELAY_LSB + * lower 4 bits are upper 4 bits of FP_VTOTAL_LSB + */ + +#define FP_VSYNC_DISABLE 0x37 + #define FP_VSYNC_WIDTH_MASK 0x38 /* value - 1 */ + #define FP_VSYNC_IS_CRT_VSYNC 0x40 + #define FP_VSYNC_DELAY_DISABLE 0x80 + +#define FP_HORZ_COMPENSATION 0x40 +#define FP_VERT_COMPENSATION 0x41 +#define FP_VERT_COMPENSATION2 0x48 + +#define FP_TEXT_VSTRETCH_0_MSB 0x49 +#define FP_TEXT_VSTRETCH_0_LSB 0x4a +#define FP_TEXT_VSTRETCH_1_MSB 0x4b +#define FP_TEXT_VSTRETCH_1_LSB 0x4c +#define FP_TEXT_LINE_REPL 0x4d +#define FP_SEL_VSTRETCH_DISABLE 0x4e + + + +#endif --- /dev/null 2008-05-18 21:24:23.000000000 +0900 +++ dev/ic/chipsfbvar.h 2007-09-19 23:45:26.000000000 +0900 @@ -0,0 +1,72 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 2006 Michael Lorenz + * 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. + */ + +#include + +struct chipsfb_softc { + struct device sc_dev; + + bus_space_tag_t sc_memt; + bus_space_tag_t sc_iot; + bus_space_handle_t sc_memh; + + bus_space_tag_t sc_fbt; + bus_space_tag_t sc_ioregt; + bus_space_handle_t sc_fbh; + bus_space_handle_t sc_ioregh; + bus_addr_t sc_fb, sc_ioreg; + bus_size_t sc_fbsize, sc_ioregsize; + + void *sc_ih; + + size_t memsize; + + int bits_per_pixel; + int width, height, linebytes; + + int sc_mode; + uint32_t sc_bg; + + u_char sc_cmap_red[256]; + u_char sc_cmap_green[256]; + u_char sc_cmap_blue[256]; + int sc_dacw; + + /* + * I2C stuff + * DDC2 clock is on GPIO1, data on GPIO0 + */ + struct i2c_controller sc_i2c; + uint8_t sc_edid[1024]; + int sc_edidbytes; /* number of bytes read from the monitor */ + + struct vcons_data vd; +}; + +void chipsfb_attach(struct chipsfb_softc *); --- /dev/null 2008-05-18 21:24:23.000000000 +0900 +++ dev/pci/chipsfb_pci.c 2007-09-20 00:25:16.000000000 +0900 @@ -0,0 +1,133 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 2006 Michael Lorenz + * 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. + */ + +/* + * PCI attachment for Chips & Technologies 65550 graphics controllers + * found on macppc + */ + +#include +__KERNEL_RCSID(0, "$NetBSD$"); + +#include "opt_wsemul.h" +#include "opt_chipsfb.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include + +struct chipsfb_pci_softc { + struct chipsfb_softc sc_chipsfb; + + pci_chipset_tag_t sc_pc; + pcitag_t sc_pcitag; +}; + +static int chipsfb_pci_match(struct device *, struct cfdata *, void *); +static void chipsfb_pci_attach(struct device *, struct device *, void *); + +CFATTACH_DECL(chipsfb_pci, sizeof(struct chipsfb_pci_softc), chipsfb_pci_match, + chipsfb_pci_attach, NULL, NULL); + +static int +chipsfb_pci_match(struct device *parent, struct cfdata *match, void *aux) +{ + struct pci_attach_args *pa = (struct pci_attach_args *)aux; + + if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY || + PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_DISPLAY_VGA) + return 0; + if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_CHIPS) && + (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CHIPS_65550)) + return 100; + if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_CHIPS) && + (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CHIPS_65554)) + return 100; + return 0; +} + +static void +chipsfb_pci_attach(struct device *parent, struct device *self, void *aux) +{ + struct chipsfb_pci_softc *psc = (void *)self; + struct chipsfb_softc *sc = &psc->sc_chipsfb; + struct pci_attach_args *pa = aux; + char devinfo[256]; + pcireg_t screg; + + psc->sc_pc = pa->pa_pc; + psc->sc_pcitag = pa->pa_tag; + + screg = pci_conf_read(psc->sc_pc, psc->sc_pcitag, + PCI_COMMAND_STATUS_REG); + screg |= PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED; + pci_conf_write(psc->sc_pc, psc->sc_pcitag, + PCI_COMMAND_STATUS_REG, screg); + + pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); + aprint_normal(": %s (rev. 0x%02x)\n", devinfo, + PCI_REVISION(pa->pa_class)); + + sc->sc_memt = pa->pa_memt; + sc->sc_iot = pa->pa_iot; + + /* the framebuffer */ + if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_MEM, + BUS_SPACE_MAP_LINEAR, + &sc->sc_fbt, &sc->sc_fbh, &sc->sc_fb, &sc->sc_fbsize)) { + aprint_error("%s: failed to map the frame buffer.\n", + sc->sc_dev.dv_xname); + } + + /* IO-mapped registers */ + if (bus_space_map(sc->sc_iot, CT_VGAREG_OFF, CT_VGAREG_SIZE, + 0, &sc->sc_ioregh) != 0) { + aprint_error("%s: failed to map IO registers.\n", + sc->sc_dev.dv_xname); + } + + chipsfb_attach(sc); +}