Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/ic split out the bus-independent portions of chipsfb



details:   https://anonhg.NetBSD.org/src/rev/5b1a15041ecd
branches:  trunk
changeset: 761865:5b1a15041ecd
user:      macallan <macallan%NetBSD.org@localhost>
date:      Wed Feb 09 21:18:04 2011 +0000

description:
split out the bus-independent portions of chipsfb

diffstat:

 sys/dev/ic/ct65550.c    |  880 ++++++++++++++++++++++++++++++++++++++++++++++++
 sys/dev/ic/ct65550reg.h |  431 +++++++++++++++++++++++
 sys/dev/ic/ct65550var.h |   84 ++++
 3 files changed, 1395 insertions(+), 0 deletions(-)

diffs (truncated from 1407 to 300 lines):

diff -r bc027e006c1d -r 5b1a15041ecd sys/dev/ic/ct65550.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/ic/ct65550.c      Wed Feb 09 21:18:04 2011 +0000
@@ -0,0 +1,880 @@
+/*     $NetBSD: ct65550.c,v 1.1 2011/02/09 21:18:04 macallan Exp $     */
+
+/*
+ * 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.
+ *
+ * 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.
+ */
+
+/*
+ * A console driver for Chips & Technologies 65550 graphics controllers
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: ct65550.c,v 1.1 2011/02/09 21:18:04 macallan Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/kauth.h>
+#include <sys/bus.h>
+#include <dev/videomode/videomode.h>
+
+#include <dev/ic/ct65550reg.h>
+#include <dev/ic/ct65550var.h>
+
+#include "opt_wsemul.h"
+#include "opt_chipsfb.h"
+
+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 *);
+
+struct wsscreen_descr chipsfb_defaultscreen = {
+       "default",      /* name */
+       0, 0,           /* ncols, nrows */
+       NULL,           /* textops */
+       8, 16,          /* fontwidth, fontheight */
+       WSSCREEN_WSCOLORS | WSSCREEN_HILIT, /* capabilities */
+       NULL,           /* modecookie */
+};
+
+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
+};
+
+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 wsdisplay_accessops chipsfb_accessops = {
+       chipsfb_ioctl,
+       chipsfb_mmap,
+       NULL,   /* vcons_alloc_screen */
+       NULL,   /* vcons_free_screen */
+       NULL,   /* vcons_show_screen */
+       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_do_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
+
+       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);
+
+       if (console)
+               vcons_replay_msgbuf(&chipsfb_console_screen);
+
+       aprint_normal_dev(sc->sc_dev, "%d MB aperture, %d MB VRAM at 0x%08x\n",
+           (u_int)(sc->sc_fbsize >> 20),
+           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)
+{
+



Home | Main Index | Thread Index | Old Index