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