Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/omap a simple console driver for the OMAP 3xxx ...
details: https://anonhg.NetBSD.org/src/rev/f0527f268f3b
branches: trunk
changeset: 757475:f0527f268f3b
user: macallan <macallan%NetBSD.org@localhost>
date: Tue Aug 31 19:03:55 2010 +0000
description:
a simple console driver for the OMAP 3xxx on-chip video
no acceleration so far and it will recycle whatever video mode the firmware
set up
diffstat:
sys/arch/arm/omap/omapfb.c | 690 ++++++++++++++++++++++++++++++++++++++++++
sys/arch/arm/omap/omapfbreg.h | 310 ++++++++++++++++++
2 files changed, 1000 insertions(+), 0 deletions(-)
diffs (truncated from 1008 to 300 lines):
diff -r 752e2a3e9f09 -r f0527f268f3b sys/arch/arm/omap/omapfb.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/omap/omapfb.c Tue Aug 31 19:03:55 2010 +0000
@@ -0,0 +1,690 @@
+/* $NetBSD: omapfb.c,v 1.1 2010/08/31 19:03:55 macallan Exp $ */
+
+/*
+ * Copyright (c) 2010 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 OMAP 3530's built-in video controller
+ * tested on beagleboard only so far
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: omapfb.c,v 1.1 2010/08/31 19:03:55 macallan Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/lwp.h>
+#include <sys/kauth.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <dev/videomode/videomode.h>
+
+#include <machine/bus.h>
+#include <arm/omap/omapfbreg.h>
+#include <arm/omap/omap2_obiovar.h>
+#include <arm/omap/omap2_obioreg.h>
+
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/wscons/wsconsio.h>
+#include <dev/wsfont/wsfont.h>
+#include <dev/rasops/rasops.h>
+#include <dev/wscons/wsdisplay_vconsvar.h>
+
+struct omapfb_softc {
+ device_t sc_dev;
+
+ bus_space_tag_t sc_iot;
+ bus_dma_tag_t sc_dmat;
+ bus_space_handle_t sc_regh;
+ bus_dmamap_t sc_dmamap;
+ bus_dma_segment_t sc_dmamem[1];
+ size_t sc_vramsize;
+
+ int sc_width, sc_height, sc_depth, sc_stride;
+ int sc_locked;
+ void *sc_fbaddr, *sc_vramaddr;
+ uint32_t *sc_clut;
+ struct vcons_screen sc_console_screen;
+ struct wsscreen_descr sc_defaultscreen_descr;
+ const struct wsscreen_descr *sc_screens[1];
+ struct wsscreen_list sc_screenlist;
+ struct vcons_data vd;
+ int sc_mode;
+ uint8_t sc_cmap_red[256], sc_cmap_green[256], sc_cmap_blue[256];
+};
+
+static int omapfb_match(device_t, cfdata_t, void *);
+static void omapfb_attach(device_t, device_t, void *);
+
+CFATTACH_DECL_NEW(omapfb, sizeof(struct omapfb_softc),
+ omapfb_match, omapfb_attach, NULL, NULL);
+
+static int omapfb_ioctl(void *, void *, u_long, void *, int,
+ struct lwp *);
+static paddr_t omapfb_mmap(void *, void *, off_t, int);
+static void omapfb_init_screen(void *, struct vcons_screen *, int, long *);
+
+static void omapfb_init(struct omapfb_softc *);
+
+static int omapfb_putcmap(struct omapfb_softc *, struct wsdisplay_cmap *);
+static int omapfb_getcmap(struct omapfb_softc *, struct wsdisplay_cmap *);
+static void omapfb_restore_palette(struct omapfb_softc *);
+static void omapfb_putpalreg(struct omapfb_softc *, int, uint8_t,
+ uint8_t, uint8_t);
+
+#if 0
+static void omapfb_flush_engine(struct omapfb_softc *);
+static void omapfb_rectfill(struct omapfb_softc *, int, int, int, int,
+ uint32_t);
+static void omapfb_bitblt(struct omapfb_softc *, int, int, int, int, int,
+ int, int);
+
+static void omapfb_cursor(void *, int, int, int);
+static void omapfb_putchar(void *, int, int, u_int, long);
+static void omapfb_copycols(void *, int, int, int, int);
+static void omapfb_erasecols(void *, int, int, int, long);
+static void omapfb_copyrows(void *, int, int, int);
+static void omapfb_eraserows(void *, int, int, long);
+#endif
+
+struct wsdisplay_accessops omapfb_accessops = {
+ omapfb_ioctl,
+ omapfb_mmap,
+ NULL, /* alloc_screen */
+ NULL, /* free_screen */
+ NULL, /* show_screen */
+ NULL, /* load_font */
+ NULL, /* pollc */
+ NULL /* scroll */
+};
+
+uint32_t venc_mode_ntsc[] = {
+ 0x00000000, 0x00000001, 0x00008040, 0x00000359,
+ 0x0000020c, 0x00000000, 0x043f2631, 0x00000000,
+ 0x00000102, 0x0000016c, 0x0000012f, 0x00000043,
+ 0x00000038, 0x00000007, 0x00000001, 0x00000038,
+ 0x21f07c1f, 0x00000000, 0x01310011, 0x0000f003,
+ 0x00000000, 0x069300f4, 0x0016020c, 0x00060107,
+ 0x008e0350, 0x000f0359, 0x01a00000, 0x020701a0,
+ 0x01ac0024, 0x020d01ac, 0x00000006, 0x03480078,
+ 0x02060024, 0x0001008a, 0x01ac0106, 0x01060006,
+ 0x00140001, 0x00010001, 0x00f90000, 0x0000000d,
+ 0x00000000};
+
+extern const u_char rasops_cmap[768];
+
+static int
+omapfb_match(device_t parent, cfdata_t match, void *aux)
+{
+ struct obio_attach_args *obio = aux;
+
+ if ((obio->obio_addr == -1) || (obio->obio_size == 0))
+ return 0;
+ return 1;
+}
+
+static void
+omapfb_attach(device_t parent, device_t self, void *aux)
+{
+ struct omapfb_softc *sc = device_private(self);
+ struct obio_attach_args *obio = aux;
+ struct rasops_info *ri;
+ struct wsemuldisplaydev_attach_args aa;
+ prop_dictionary_t dict;
+ unsigned long defattr;
+ bool is_console;
+ uint32_t sz, reg;
+ int segs, i, j, adr;
+
+ sc->sc_iot = obio->obio_iot;
+ sc->sc_dev = self;
+ sc->sc_dmat = obio->obio_dmat;
+
+ printf(": OMAP onboard video\n");
+ if (bus_space_map(obio->obio_iot, obio->obio_addr, obio->obio_size, 0,
+ &sc->sc_regh)) {
+ aprint_error(": couldn't map register space\n");
+ return;
+ }
+
+ sz = bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_SIZE);
+ sc->sc_width = (sz & 0xfff) + 1;
+ sc->sc_height = ((sz & 0x0fff0000 ) >> 16) + 1;
+ sc->sc_depth = 16;
+ sc->sc_stride = sc->sc_width << 1;
+
+ printf("%s: firmware set up %d x %d\n", device_xname(self),
+ sc->sc_width, sc->sc_height);
+#if 0
+ printf("DSS revision: %08x\n",
+ bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DSS_REVISION));
+#endif
+ dict = device_properties(self);
+ prop_dictionary_get_bool(dict, "is_console", &is_console);
+ is_console = 1;
+
+ /* setup video DMA */
+ sc->sc_vramsize = (12 << 20) + 0x1000; /* 12MB + CLUT */
+
+ if (bus_dmamem_alloc(sc->sc_dmat, sc->sc_vramsize, 0, 0,
+ sc->sc_dmamem, 1, &segs, BUS_DMA_NOWAIT) != 0) {
+ panic("boo!\n");
+ aprint_error_dev(sc->sc_dev,
+ "failed to allocate video memory\n");
+ return;
+ }
+
+ if (bus_dmamem_map(sc->sc_dmat, sc->sc_dmamem, 1, sc->sc_vramsize,
+ &sc->sc_vramaddr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT) != 0) {
+ aprint_error_dev(sc->sc_dev, "failed to map video RAM\n");
+ return;
+ }
+ sc->sc_fbaddr = (uint8_t *)sc->sc_vramaddr + 0x1000;
+ sc->sc_clut = sc->sc_vramaddr;
+
+ if (bus_dmamap_create(sc->sc_dmat, sc->sc_vramsize, 1, sc->sc_vramsize,
+ 0, BUS_DMA_NOWAIT, &sc->sc_dmamap) != 0) {
+ aprint_error_dev(sc->sc_dev, "failed to create DMA map\n");
+ return;
+ }
+
+ if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_vramaddr,
+ sc->sc_vramsize, NULL, BUS_DMA_NOWAIT) != 0) {
+ aprint_error_dev(sc->sc_dev, "failed to load DMA map\n");
+ return;
+ }
+
+ if (sc->sc_depth == 8) {
+ j = 0;
+ for (i = 0; i < 256; i++) {
+ sc->sc_cmap_red[i] = rasops_cmap[j];
+ sc->sc_cmap_green[i] = rasops_cmap[j + 1];
+ sc->sc_cmap_blue[i] = rasops_cmap[j + 2];
+ j += 3;
+ }
+ } else {
+ for (i = 0; i < 256; i++) {
+ sc->sc_cmap_red[i] = i;
+ sc->sc_cmap_green[i] = i;
+ sc->sc_cmap_blue[i] = i;
+ }
+ }
+ omapfb_restore_palette(sc);
+
+ /* now that we have video memory, stick it to the video controller */
+
+ reg = bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_SYSCONFIG);
+ reg &= ~(OMAP_DISPC_SYSC_STANDBY_MASK | OMAP_DISPC_SYSC_IDLE_MASK);
+ reg |= OMAP_DISPC_SYSC_SMART_STANDBY | OMAP_DISPC_SYSC_SMART_IDLE |
+ OMAP_DISPC_SYSC_WAKEUP_ENABLE | OMAP_SYSCONF_AUTOIDLE;
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_SYSCONFIG, reg);
+
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DSS_SYSCONFIG,
+ OMAP_SYSCONF_AUTOIDLE);
+ reg = bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONFIG);
+ reg = 0x8;
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONFIG, reg);
+
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_BASE_0,
+ sc->sc_dmamem->ds_addr + 0x1000);
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_TABLE_BASE,
+ sc->sc_dmamem->ds_addr);
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_POSITION,
+ 0);
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_PRELOAD, 0x60);
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_ATTRIBUTES,
+ OMAP_DISPC_ATTR_ENABLE |
+ OMAP_DISPC_ATTR_BURST_16x32 |
+ /*OMAP_DISPC_ATTR_8BIT*/OMAP_DISPC_ATTR_RGB16
+ | OMAP_DISPC_ATTR_REPLICATION);
+#if 0
+ printf("dss_control: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DSS_CONTROL));
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DSS_CONTROL,
+ /*OMAP_DSSCTRL_DISPC_CLK_SWITCH |*/
+ OMAP_DSSCTRL_CLOCK_MODE |
+ OMAP_DSSCTRL_VENC_CLOCK_4X |
+ OMAP_DSSCTRL_DAC_DEMEN);
+#endif
+
+ /* VENC to NTSC mode */
+ adr = OMAPFB_VENC_F_CONTROL;
+#if 0
+ for (i = 0; i < __arraycount(venc_mode_ntsc); i++) {
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, adr,
+ venc_mode_ntsc[i]);
+ adr += 4;
+ }
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_VENC_F_CONTROL,
+ venc_mode_ntsc[0]);
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_VENC_SYNC_CTRL,
+ venc_mode_ntsc[2]);
+
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_DEFAULT_COLOR_1,
+ 0x00ff0000);
+#endif
+ reg = bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL);
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL,
+ reg | OMAP_DISPC_CTRL_GO_LCD);
+
+#ifdef OMAPFB_DEBUG
+ printf("attr: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_ATTRIBUTES));
Home |
Main Index |
Thread Index |
Old Index