Author: adrian
Date: Sun Apr  3 14:39:55 2011
New Revision: 220297
URL: http://svn.freebsd.org/changeset/base/220297

Log:
  Import the initial CPU support for the MIPS RALink RT305x SoC.
  This is a MIPS4KC CPU with various embedded peripherals, including
  wireless and ethernet support.
  
  This commit includes the platform, UART, ethernet MAC and GPIO support.
  The interrupt-driven GPIO code is disabled for now pending GPIO changes
  from the submitter.
  
  Submitted by: Aleksandr Rybalko <[email protected]>

Added:
  head/sys/mips/conf/RT305X   (contents, props changed)
  head/sys/mips/conf/RT305X.hints   (contents, props changed)
  head/sys/mips/rt305x/
  head/sys/mips/rt305x/files.rt305x   (contents, props changed)
  head/sys/mips/rt305x/obio.c   (contents, props changed)
  head/sys/mips/rt305x/obiovar.h   (contents, props changed)
  head/sys/mips/rt305x/rt305x_dotg.c   (contents, props changed)
  head/sys/mips/rt305x/rt305x_gpio.c   (contents, props changed)
  head/sys/mips/rt305x/rt305x_gpio.h   (contents, props changed)
  head/sys/mips/rt305x/rt305x_gpiovar.h   (contents, props changed)
  head/sys/mips/rt305x/rt305x_ic.c   (contents, props changed)
  head/sys/mips/rt305x/rt305x_icvar.h   (contents, props changed)
  head/sys/mips/rt305x/rt305x_machdep.c   (contents, props changed)
  head/sys/mips/rt305x/rt305x_sysctl.c   (contents, props changed)
  head/sys/mips/rt305x/rt305x_sysctlvar.h   (contents, props changed)
  head/sys/mips/rt305x/rt305xreg.h   (contents, props changed)
  head/sys/mips/rt305x/rt_swreg.h   (contents, props changed)
  head/sys/mips/rt305x/std.rt305x   (contents, props changed)
  head/sys/mips/rt305x/uart_bus_rt305x.c   (contents, props changed)
  head/sys/mips/rt305x/uart_cpu_rt305x.c   (contents, props changed)
  head/sys/mips/rt305x/uart_dev_rt305x.c   (contents, props changed)
  head/sys/mips/rt305x/uart_dev_rt305x.h   (contents, props changed)

Added: head/sys/mips/conf/RT305X
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/mips/conf/RT305X   Sun Apr  3 14:39:55 2011        (r220297)
@@ -0,0 +1,134 @@
+# RT305X -- Kernel configuration file for FreeBSD/mips for Ralink RT305xF 
systems
+#
+# For more information on this file, please read the handbook section on
+# Kernel Configuration Files:
+#
+#    
http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
+#
+# The handbook is also available locally in /usr/share/doc/handbook
+# if you've installed the doc distribution, otherwise always see the
+# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
+# latest information.
+#
+# An exhaustive list of options and more detailed explanations of the
+# device lines is also present in the ../../conf/NOTES and NOTES files. 
+# If you are in doubt as to the purpose or necessity of a line, check first 
+# in NOTES.
+#
+# $FreeBSD$
+
+ident          RT305X
+
+machine                mips mipsel
+makeoptions    MIPS_LITTLE_ENDIAN=defined
+makeoptions    KERNLOADADDR=0x80001000
+
+# Don't build any modules yet.
+makeoptions    MODULES_OVERRIDE="wlan_xauth wlan_wep wlan_tkip wlan_acl 
wlan_amrr wlan_ccmp wlan_rssadapt random if_bridge bridgestp msdosfs md ipfw 
dummynet libalias geom/geom_label ufs usb/uplcom usb/u3g usb/umodem usb/umass 
usb/ucom cam zlib"
+makeoptions    RT3052F
+
+include                "../rt305x/std.rt305x"
+
+hints          "RT305X.hints"          #Default places to look for devices.
+
+#makeoptions   DEBUG=-g                #Build kernel with gdb(1) debug symbols
+
+# Debugging for use in -current
+#options       DEADLKRES               #Enable the deadlock resolver
+#options               INVARIANTS              #Enable calls of extra sanity 
checking
+#options               INVARIANT_SUPPORT       #Extra sanity checks of 
internal structures, required by INVARIANTS
+#options               WITNESS                 #Enable checks to detect 
deadlocks and cycles
+#options               WITNESS_SKIPSPIN        #Don't run witness on spinlocks 
for speed
+#options         DIAGNOSTIC
+#options     DEBUG_LOCKS
+#options     DEBUG_VFS_LOCKS
+#options       GDB
+options        DDB
+options        KDB
+
+options        SCHED_ULE
+#options       SCHED_4BSD              #4BSD scheduler
+#options               COMPAT_43
+options        INET                    #InterNETworking
+options        NFSCLIENT               #Network Filesystem Client
+options        NFS_ROOT                #NFS usable as /, requires NFSCLIENT
+options        PSEUDOFS                #Pseudo-filesystem framework
+#options       _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions
+
+options        BOOTP
+#options       BOOTP_NFSROOT
+options        BOOTP_NFSV3
+options        BOOTP_WIRED_TO=rt0
+options        BOOTP_COMPAT
+options        CD9660                  # ISO 9660 Filesystem
+options                ROOTDEVNAME=\"cd9660:/dev/map/rootfs.uncompress\"
+options        TMPFS                   # TMP Memory Filesystem
+
+#options       FFS                     #Berkeley Fast Filesystem
+#options       SOFTUPDATES             #Enable FFS soft updates support
+#options       UFS_ACL                 #Support for access control lists
+#options       UFS_DIRHASH             #Improve performance on big directories
+#options       ROOTDEVNAME=\"nfs:10.0.0.1:/mnt/bsd\"
+
+# Options for making kernel less hangry
+makeoptions    INLINE_LIMIT=1024
+options                MAXUSERS=3
+options                MAXFILES=512
+options                NSFBUFS=256
+options                SHMALL=128
+options                MSGBUF_SIZE=65536
+
+# Options for making kernel smallest 
+options                NO_SYSCTL_DESCR         # No description string of 
sysctl
+#options               NO_FFS_SNAPSHOT         # Disable Snapshot supporting
+options                SCSI_NO_SENSE_STRINGS
+options                SCSI_NO_OP_STRINGS
+options                RWLOCK_NOINLINE
+options                SX_NOINLINE
+options                NO_SWAPPING
+options        ZERO_COPY_SOCKETS
+options         MROUTING                # Multicast routing
+options                IPFIREWALL_DEFAULT_TO_ACCEPT
+
+device         random
+device         loop
+# RT3050F, RT3052F have only pseudo PHYs
+#device                mii
+#device                miibus
+device                 pty                     # Pseudo-ttys (telnet etc)
+device         ether
+device                 bpf                     # Berkeley packet filter
+device         vlan
+#device                lagg
+#device          if_bridge
+device         uart
+nodevice       uart_ns8250
+device                 tun                     # Packet tunnel.
+
+device         wlan
+
+
+device         gpio
+device         gpioled
+
+device         cfi                     # Detect Flash memmory
+device         cfid
+
+device         nvram2env
+
+device         usb
+#device                dotg                    # DWC like USB OTG Controller 
driver
+#device                u3g
+#device                umodem
+#device                uplcom
+#device                umass
+#device                da
+#device                pass
+#device                scbus
+options        SCSI_DELAY=1000         # Delay (in ms) before probing SCSI
+
+#options               USB_EHCI_BIG_ENDIAN_DESC        # handle big-endian 
byte order
+#options               USB_DEBUG
+#options               USB_REQ_DEBUG
+
+

Added: head/sys/mips/conf/RT305X.hints
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/mips/conf/RT305X.hints     Sun Apr  3 14:39:55 2011        
(r220297)
@@ -0,0 +1,136 @@
+# $FreeBSD$
+# device.hints
+hint.obio.0.at="nexus0"
+hint.obio.0.maddr=0x10000000
+hint.obio.0.msize=0x10000000
+
+hint.nvram.0.sig=0xe5e60a74
+hint.nvram.0.base=0x1f030000
+hint.nvram.0.maxsize=0x2000
+hint.nvram.0.flags=3 # 1 = No check, 2 = Format Generic
+hint.nvram.1.sig=0x5a045e94
+hint.nvram.1.base=0x1f032000
+hint.nvram.1.maxsize=0x4000
+hint.nvram.1.flags=3 # 1 = No check, 2 = Format Generic
+
+# on-board Ralink Frame Engine
+#hint.rt.0.at="nexus0"
+#hint.rt.0.maddr=0x12000000
+#hint.rt.0.msize=0x200000
+#hint.rt.0.irq=9
+hint.rt.0.macaddr="00:18:e7:d5:83:90"
+
+# on-board Ralink 2872 802.11n core
+hint.rt2860.0.at="nexus0"
+hint.rt2860.0.maddr=0x10180000
+hint.rt2860.0.msize=0x40000
+hint.rt2860.0.irq=4
+
+# uart0
+#hint.uart.0.at="obio0"
+#hint.uart.0.maddr=0x10000C00
+#hint.uart.0.msize=0x100
+#hint.uart.0.irq=12
+#hint.uart.0.flags="0x30"
+
+# uart1
+#hint.uart.1.at="obio0"
+#hint.uart.1.maddr=0x10000500
+#hint.uart.1.msize=0x100
+#hint.uart.1.irq=5
+#hint.uart.1.flags="0x30"
+
+
+# gpio
+# GPIO0  - WPS BTN     IN II IO
+hint.gpiobutton.0.at="gpiobus0"
+hint.gpiobutton.0.pins="0x01"
+hint.gpiobutton.0.name="wps"
+hint.gpiobutton.0.flags="0x0581"
+
+# GPIO7  - MODE SW AP  IN II IO
+hint.gpiobutton.1.at="gpiobus0"
+hint.gpiobutton.1.pins="0x80"
+hint.gpiobutton.1.name="mode_ap"
+hint.gpiobutton.1.flags="0x0581"
+
+# GPIO8  - ST LEDRED   OUT     /* 2pin BiDir RED/BLUE LED */
+# GPIO9  - ST LEDBLUE  OUT
+hint.gpioled.0.at="gpiobus0"
+hint.gpioled.0.pins="0x100"
+hint.gpioled.0.name="status_red"
+hint.gpioled.0.flags="0x0002"
+hint.gpioled.1.at="gpiobus0"
+hint.gpioled.1.pins="0x200"
+#hint.gpioled.1.name="status_blue"
+hint.gpioled.1.name="status"
+hint.gpioled.1.flags="0x0002"
+
+# GPIO10 - RST BTN     IN II IO
+hint.gpiobutton.2.at="gpiobus0"
+hint.gpiobutton.2.pins="0x400"
+hint.gpiobutton.2.name="reset"
+hint.gpiobutton.2.flags="0x0581"
+
+# GPIO11 - MODE SW CL  IN II IO
+hint.gpiobutton.3.at="gpiobus0"
+hint.gpiobutton.3.pins="0x800"
+hint.gpiobutton.3.name="mode_wlan_client"
+hint.gpiobutton.3.flags="0x0581"
+
+# GPIO14 - WPS LED     OUT II IO
+hint.gpioled.2.at="gpiobus0"
+hint.gpioled.2.pins="0x4000"
+hint.gpioled.2.name="wps"
+hint.gpioled.2.flags="0x0182"
+
+
+
+#0x00000000-0x00030000 : "Bootloader"
+#0x00030000-0x00040000 : "Factory"
+#0x00040000-0x00070000 : "Config"
+#0x00070000-0x000b0000 : "Language"
+#0x000b0000-0x001a0000 : "Kernel"
+#0x001a0000-0x01000000 : "RootFS"
+
+hint.map.0.at="cfid0"
+hint.map.0.start=0x00000000
+hint.map.0.end=0x00030000
+hint.map.0.name="bootloader"
+hint.map.0.readonly=1
+
+hint.map.1.at="cfid0"
+hint.map.1.start=0x00030000
+hint.map.1.end=0x00040000
+hint.map.1.name="factory"
+
+hint.map.2.at="cfid0"
+hint.map.2.start=0x00040000
+hint.map.2.end=0x00800000
+hint.map.2.name="upgrade"
+
+hint.map.3.at="cfid0"
+hint.map.3.start=0x00040000
+hint.map.3.end=0x00050000
+hint.map.3.name="config"
+
+hint.map.4.at="cfid0"
+hint.map.4.start=0x00000000
+hint.map.4.end=0x00000000
+hint.map.4.name="language"
+
+hint.map.5.at="cfid0"
+hint.map.5.start=0x00050000
+hint.map.5.end=0x00150000
+hint.map.5.name="kernel"
+
+hint.map.6.at="cfid0"
+hint.map.6.start=0x00150000
+hint.map.6.end=0x00800000
+hint.map.6.name="rootfs"
+
+
+hint.rt.0.phymask=0x1f
+hint.rt.0.media=100
+hint.rt.0.fduplex=1
+

Added: head/sys/mips/rt305x/files.rt305x
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/mips/rt305x/files.rt305x   Sun Apr  3 14:39:55 2011        
(r220297)
@@ -0,0 +1,13 @@
+# $FreeBSD$
+
+# RT305X on-board devices
+mips/rt305x/rt305x_machdep.c   standard
+mips/rt305x/obio.c             standard
+mips/rt305x/rt305x_sysctl.c    standard
+mips/rt305x/rt305x_ic.c                standard
+mips/rt305x/rt305x_gpio.c      optional gpio
+mips/rt305x/uart_bus_rt305x.c  optional uart
+mips/rt305x/uart_cpu_rt305x.c  optional uart
+mips/rt305x/uart_dev_rt305x.c  optional uart
+mips/mips/intr_machdep.c        standard
+mips/mips/tick.c               standard

Added: head/sys/mips/rt305x/obio.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/mips/rt305x/obio.c Sun Apr  3 14:39:55 2011        (r220297)
@@ -0,0 +1,627 @@
+/*     $NetBSD: obio.c,v 1.11 2003/07/15 00:25:05 lukem Exp $  */
+
+/*-
+ * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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 WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/interrupt.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/malloc.h>
+
+#include <machine/bus.h>
+
+#include <mips/rt305x/rt305xreg.h>
+#include <mips/rt305x/obiovar.h>
+#include <mips/rt305x/rt305x_icvar.h>
+
+/* MIPS HW interrupts of IRQ/FIQ respectively */
+#define RT305X_INTR            0
+#define RT305X_FAST_INTR       1
+
+/* Interrupt levels */
+#define INTR_IRQ 0
+#define INTR_FIQ 1
+
+
+int irq_priorities[NIRQS] = {
+       INTR_IRQ,       /* SYSCTL */
+       INTR_FIQ,       /* TIMER0 */
+       INTR_FIQ,       /* WDTIMER */
+       INTR_IRQ,       /* Illegal Access */
+       INTR_IRQ,       /* PCM */
+       INTR_IRQ,       /* UART */
+       INTR_IRQ,       /* GPIO */
+       INTR_FIQ,       /* GDMA */
+       INTR_IRQ,       /* NAND */
+       INTR_IRQ,       /* Perfomance Counter */
+       INTR_IRQ,       /* I2S */
+       INTR_IRQ,       /* unknown */
+       INTR_IRQ,       /* UARTLITE */
+       INTR_IRQ,       /* unknown */
+       INTR_IRQ,       /* unknown */
+       INTR_IRQ,       /* unknown */
+       INTR_IRQ,       /* unknown */
+       INTR_IRQ,       /* EtherNet Switch */
+       INTR_FIQ,       /* OTG */
+       INTR_IRQ,       /* unknown */
+       INTR_IRQ,       /* unknown */
+       INTR_IRQ,       /* unknown */
+       INTR_IRQ,       /* unknown */
+       INTR_IRQ,       /* unknown */
+       INTR_IRQ,       /* unknown */
+       INTR_IRQ,       /* unknown */
+       INTR_IRQ,       /* unknown */
+       INTR_IRQ,       /* unknown */
+       INTR_IRQ,       /* unknown */
+       INTR_IRQ,       /* unknown */
+       INTR_IRQ,       /* unknown */
+       INTR_IRQ,       /* unknown */
+};
+
+
+#define REG_READ(o) *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1(INTCTL_BASE + 
(o)))
+#define REG_WRITE(o,v) (REG_READ(o)) = (v)
+
+static int     obio_activate_resource(device_t, device_t, int, int,
+                   struct resource *);
+static device_t        obio_add_child(device_t, u_int, const char *, int);
+static struct resource *
+               obio_alloc_resource(device_t, device_t, int, int *, u_long,
+                   u_long, u_long, u_int);
+static int     obio_attach(device_t);
+static int     obio_deactivate_resource(device_t, device_t, int, int,
+                   struct resource *);
+static struct resource_list *
+               obio_get_resource_list(device_t, device_t);
+static void    obio_add_res_child(device_t, const char *, int, long, int, int);
+static void    obio_hinted_child(device_t, const char *, int);
+static int     obio_intr(void *);
+static int     obio_probe(device_t);
+static int     obio_release_resource(device_t, device_t, int, int,
+                   struct resource *);
+static int     obio_setup_intr(device_t, device_t, struct resource *, int,
+                   driver_filter_t *, driver_intr_t *, void *, void **);
+static int     obio_teardown_intr(device_t, device_t, struct resource *,
+                   void *);
+
+static void 
+obio_mask_irq(void *source)
+{
+       int irq;
+       uint32_t irqmask;
+
+       irq = (int)source;
+       irqmask = 1 << irq;
+
+       /* disable IRQ */
+       rt305x_ic_set(IC_INT_DIS, irqmask);
+}
+
+static void 
+obio_unmask_irq(void *source)
+{
+       int irq;
+       uint32_t irqmask;
+
+       irq = (int)source;
+       irqmask = 1 << irq;
+
+       /* enable IRQ */
+       rt305x_ic_set(IC_INT_ENA, irqmask);
+
+}
+
+
+static int
+obio_probe(device_t dev)
+{
+
+       return (0);
+}
+
+static int
+obio_attach(device_t dev)
+{
+       struct obio_softc *sc = device_get_softc(dev);
+       int rid;
+
+       sc->oba_mem_rman.rm_type = RMAN_ARRAY;
+       sc->oba_mem_rman.rm_descr = "OBIO memory";
+       if (rman_init(&sc->oba_mem_rman) != 0 ||
+           rman_manage_region(&sc->oba_mem_rman, OBIO_MEM_START,
+               OBIO_MEM_END) != 0)
+               panic("obio_attach: failed to set up I/O rman");
+
+       sc->oba_irq_rman.rm_type = RMAN_ARRAY;
+       sc->oba_irq_rman.rm_descr = "OBIO IRQ";
+       if (rman_init(&sc->oba_irq_rman) != 0 ||
+           rman_manage_region(&sc->oba_irq_rman, 0, NIRQS-1) != 0)
+               panic("obio_attach: failed to set up IRQ rman");
+
+       /* Hook up our interrupt handler. */
+       if ((sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
+           RT305X_INTR, RT305X_INTR, 1,
+           RF_SHAREABLE | RF_ACTIVE)) == NULL) {
+               device_printf(dev, "unable to allocate IRQ resource\n");
+               return (ENXIO);
+       }
+
+       if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC, obio_intr, NULL,
+           sc, &sc->sc_ih))) {
+               device_printf(dev,
+                   "WARNING: unable to register interrupt handler\n");
+               return (ENXIO);
+       }
+
+       /* Hook up our FAST interrupt handler. */
+       if ((sc->sc_fast_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
+           RT305X_FAST_INTR, RT305X_FAST_INTR, 1,
+           RF_SHAREABLE | RF_ACTIVE)) == NULL) {
+               device_printf(dev, "unable to allocate IRQ resource\n");
+               return (ENXIO);
+       }
+
+       if ((bus_setup_intr(dev, sc->sc_fast_irq, INTR_TYPE_MISC, obio_intr,
+           NULL, sc, &sc->sc_fast_ih))) {
+               device_printf(dev,
+                   "WARNING: unable to register interrupt handler\n");
+               return (ENXIO);
+       }
+
+       /* disable all interrupts */
+       rt305x_ic_set(IC_INT_DIS, IC_INT_MASK|IC_LINE_GLOBAL);
+
+       bus_generic_probe(dev);
+
+       obio_add_res_child(dev, "rt305x_sysctl", 0, 
+           SYSCTL_BASE, (SYSCTL_END - SYSCTL_BASE + 1),
+           IC_SYSCTL);
+       obio_add_res_child(dev, "rt305x_ic", 0, 
+           INTCTL_BASE, (INTCTL_END - INTCTL_BASE + 1),
+           -1);
+#ifdef notyet
+       obio_add_res_child(dev, "timer",0, 
+           TIMER_BASE, (TIMER_END - TIMER_BASE  + 1),
+           IC_TIMER0);
+       obio_add_res_child(dev, "rt305x_memc", 0,
+           MEMCTRL_BASE, (MEMCTRL_END - MEMCTRL_BASE + 1),
+           -1);
+       obio_add_res_child(dev, "pcm",  0, 
+           PCM_BASE, (PCM_END - PCM_BASE  + 1),
+           IC_PCM);
+       obio_add_res_child(dev, "uart", 0, 
+           UART_BASE, (UART_END - UART_BASE + 1),
+           IC_UART);
+#endif
+       obio_add_res_child(dev, "gpio", 0, 
+           PIO_BASE, (PIO_END - PIO_BASE  + 1),
+           IC_PIO);
+#ifdef notyet
+       obio_add_res_child(dev, "rt305x_dma", 0,
+           GDMA_BASE, (GDMA_END - GDMA_BASE + 1),
+           IC_DMA);
+       obio_add_res_child(dev, "rt305x_nandc", 0,
+           NANDFC_BASE, (NANDFC_END - NANDFC_BASE  + 1),
+           IC_NAND);
+       obio_add_res_child(dev, "i2c",  0,
+           I2C_BASE, (I2C_END - I2C_BASE  + 1),
+           -1);
+       obio_add_res_child(dev, "i2s", 0,
+           I2S_BASE, (I2S_END - I2S_BASE  + 1),
+           IC_I2S);
+       obio_add_res_child(dev, "spi", 0, 
+           SPI_BASE, (SPI_END - SPI_BASE  + 1),
+           -1);
+#endif
+       obio_add_res_child(dev, "uart", 1,
+           UARTLITE_BASE, (UARTLITE_END - UARTLITE_BASE + 1),
+           IC_UARTLITE);
+       obio_add_res_child(dev, "cfi",  0,
+           FLASH_BASE, (FLASH_END - FLASH_BASE  + 1),
+           -1);
+       obio_add_res_child(dev, "dotg", 0,
+           USB_OTG_BASE, (USB_OTG_END - USB_OTG_BASE  + 1),
+           IC_OTG);
+       obio_add_res_child(dev, "switch", 0,
+           ETHSW_BASE, (ETHSW_END - ETHSW_BASE  + 1),
+           IC_ETHSW);
+
+       bus_enumerate_hinted_children(dev);
+       bus_generic_attach(dev);
+
+       /* enable IC */
+       rt305x_ic_set(IC_INT_ENA, IC_LINE_GLOBAL);
+
+       return (0);
+}
+
+static struct resource *
+obio_alloc_resource(device_t bus, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+       struct obio_softc               *sc = device_get_softc(bus);
+       struct obio_ivar                *ivar = device_get_ivars(child);
+       struct resource                 *rv;
+       struct resource_list_entry      *rle;
+       struct rman                     *rm;
+       int                              isdefault, needactivate, passthrough;
+
+       isdefault = (start == 0UL && end == ~0UL && count == 1);
+       needactivate = flags & RF_ACTIVE;
+       passthrough = (device_get_parent(child) != bus);
+       rle = NULL;
+
+       if (passthrough)
+               return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type,
+                   rid, start, end, count, flags));
+
+       /*
+        * If this is an allocation of the "default" range for a given RID,
+        * and we know what the resources for this device are (ie. they aren't
+        * maintained by a child bus), then work out the start/end values.
+        */
+       if (isdefault) {
+               rle = resource_list_find(&ivar->resources, type, *rid);
+               if (rle == NULL)
+                       return (NULL);
+               if (rle->res != NULL) {
+                       panic("%s: resource entry is busy", __func__);
+               }
+               start = rle->start;
+               end = rle->end;
+               count = rle->count;
+       }
+
+       switch (type) {
+       case SYS_RES_IRQ:
+               rm = &sc->oba_irq_rman;
+               break;
+       case SYS_RES_MEMORY:
+               rm = &sc->oba_mem_rman;
+               break;
+       default:
+               printf("%s: unknown resource type %d\n", __func__, type);
+               return (0);
+       }
+
+       rv = rman_reserve_resource(rm, start, end, count, flags, child);
+       if (rv == 0) {
+               printf("%s: could not reserve resource\n", __func__);
+               return (0);
+       }
+
+       rman_set_rid(rv, *rid);
+
+       if (needactivate) {
+               if (bus_activate_resource(child, type, *rid, rv)) {
+                       printf("%s: could not activate resource\n", __func__);
+                       rman_release_resource(rv);
+                       return (0);
+               }
+       }
+
+       return (rv);
+}
+
+static int
+obio_activate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+
+       /*
+        * If this is a memory resource, track the direct mapping
+        * in the uncached MIPS KSEG1 segment.
+        */
+       if (type == SYS_RES_MEMORY) {
+               void *vaddr;
+
+               vaddr = (void *)MIPS_PHYS_TO_KSEG1((intptr_t)rman_get_start(r));
+               rman_set_virtual(r, vaddr);
+               rman_set_bustag(r, mips_bus_space_generic);
+               rman_set_bushandle(r, (bus_space_handle_t)vaddr);
+       }
+
+       return (rman_activate_resource(r));
+}
+
+static int
+obio_deactivate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+
+       return (rman_deactivate_resource(r));
+}
+
+static int
+obio_release_resource(device_t dev, device_t child, int type,
+    int rid, struct resource *r)
+{
+       struct resource_list *rl;
+       struct resource_list_entry *rle;
+
+       rl = obio_get_resource_list(dev, child);
+       if (rl == NULL)
+               return (EINVAL);
+       rle = resource_list_find(rl, type, rid);
+       if (rle == NULL)
+               return (EINVAL);
+       rman_release_resource(r);
+       rle->res = NULL;
+
+       return (0);
+}
+
+static int
+obio_setup_intr(device_t dev, device_t child, struct resource *ires,
+               int flags, driver_filter_t *filt, driver_intr_t *handler,
+               void *arg, void **cookiep)
+{
+       struct obio_softc *sc = device_get_softc(dev);
+       struct intr_event *event;
+       int irq, error, priority;
+       uint32_t irqmask;
+
+       irq = rman_get_start(ires);
+
+       if (irq >= NIRQS)
+               panic("%s: bad irq %d", __func__, irq);
+
+       event = sc->sc_eventstab[irq];
+       if (event == NULL) {
+               error = intr_event_create(&event, (void *)irq, 0, irq,
+                   obio_mask_irq, obio_unmask_irq,
+                   NULL, NULL, "obio intr%d:", irq);
+
+               sc->sc_eventstab[irq] = event;
+       }
+       else
+               panic("obio: Can't share IRQs");
+
+       intr_event_add_handler(event, device_get_nameunit(child), filt,
+           handler, arg, intr_priority(flags), flags, cookiep);
+
+       irqmask = 1 << irq;
+       priority = irq_priorities[irq];
+
+       if (priority == INTR_FIQ)
+               rt305x_ic_set(IC_INTTYPE, rt305x_ic_get(IC_INTTYPE) | irqmask);
+       else
+               rt305x_ic_set(IC_INTTYPE, rt305x_ic_get(IC_INTTYPE) & ~irqmask);
+
+       /* enable */
+       obio_unmask_irq((void*)irq);
+
+       return (0);
+}
+
+static int
+obio_teardown_intr(device_t dev, device_t child, struct resource *ires,
+    void *cookie)
+{
+       struct obio_softc *sc = device_get_softc(dev);
+       int irq, result, priority;
+       uint32_t irqmask;
+
+       irq = rman_get_start(ires);
+       if (irq >= NIRQS)
+               panic("%s: bad irq %d", __func__, irq);
+
+       if (sc->sc_eventstab[irq] == NULL)
+               panic("Trying to teardown unoccupied IRQ");
+
+       irqmask = (1 << irq);
+       priority = irq_priorities[irq];
+
+       if (priority == INTR_FIQ)
+               rt305x_ic_set(IC_INTTYPE, rt305x_ic_get(IC_INTTYPE) & ~irqmask);
+       else
+               rt305x_ic_set(IC_INTTYPE, rt305x_ic_get(IC_INTTYPE) | irqmask);
+
+       /* disable */
+       obio_mask_irq((void*)irq);
+
+       result = intr_event_remove_handler(cookie);
+       if (!result) {
+               sc->sc_eventstab[irq] = NULL;
+       }
+
+       return (result);
+}
+
+static int
+obio_intr(void *arg)
+{
+       struct obio_softc *sc = arg;
+       struct intr_event *event;
+       uint32_t irqstat;
+       int irq;
+
+       irqstat = rt305x_ic_get(IC_IRQ0STAT);
+       irqstat |= rt305x_ic_get(IC_IRQ1STAT);
+
+       irq = 0;
+       while (irqstat != 0) {
+               if ((irqstat & 1) == 1) {
+                       event = sc->sc_eventstab[irq];
+                       if (!event || TAILQ_EMPTY(&event->ie_handlers))
+                               continue;
+
+                       /* TODO: pass frame as an argument*/
+                       /* TODO: log stray interrupt */
+                       intr_event_handle(event, NULL);
+               }
+               irq++;
+               irqstat >>= 1;
+       }
+
+       return (FILTER_HANDLED);
+}
+
+static void
+obio_add_res_child(device_t bus, const char *dname, int dunit, 
+    long maddr, int msize, int irq)
+{
+       device_t                child;
+       int                     result;
+
+       child = BUS_ADD_CHILD(bus, 0, dname, dunit);
+
+       result = bus_set_resource(child, SYS_RES_MEMORY, 0,
+           maddr, msize);
+       if (result != 0)
+               device_printf(bus, "warning: bus_set_resource() failed\n");
+
+       if (irq != -1) {
+               result = bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1);
+               if (result != 0)
+                       device_printf(bus,
+                           "warning: bus_set_resource() failed\n");
+       }
+}
+
+static void
+obio_hinted_child(device_t bus, const char *dname, int dunit)
+{
+       long                    maddr;
+       int                     msize;
+       int                     irq;
+
+       /*
+        * Set hard-wired resources for hinted child using
+        * specific RIDs.
+        */
+       resource_long_value(dname, dunit, "maddr", &maddr);
+       resource_int_value(dname, dunit, "msize", &msize);
+
+
+       if (resource_int_value(dname, dunit, "irq", &irq) == 0) irq = -1;
+
+       obio_add_res_child(bus, dname, dunit, maddr, msize, irq);
+}
+
+static device_t
+obio_add_child(device_t bus, u_int order, const char *name, int unit)
+{
+       device_t                child;
+       struct obio_ivar        *ivar;
+
+       ivar = malloc(sizeof(struct obio_ivar), M_DEVBUF, M_WAITOK | M_ZERO);
+       if (ivar == NULL) {
+               printf("Failed to allocate ivar\n");
+               return (0);
+       }
+       resource_list_init(&ivar->resources);
+
+       child = device_add_child_ordered(bus, order, name, unit);
+       if (child == NULL) {
+               printf("Can't add child %s%d ordered\n", name, unit);
+               return (0);
+       }
+
+       device_set_ivars(child, ivar);
+
+       return (child);
+}
+
+/*
+ * Helper routine for bus_generic_rl_get_resource/bus_generic_rl_set_resource
+ * Provides pointer to resource_list for these routines
+ */
+static struct resource_list *
+obio_get_resource_list(device_t dev, device_t child)
+{
+       struct obio_ivar *ivar;
+
+       ivar = device_get_ivars(child);
+       return (&(ivar->resources));
+}
+
+static int
+obio_print_all_resources(device_t dev)
+{
+       struct obio_ivar *ivar = device_get_ivars(dev);
+       struct resource_list *rl = &ivar->resources;
+       int retval = 0;
+
+       if (STAILQ_FIRST(rl))
+               retval += printf(" at");
+
+       retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx");
+       retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld");
+
+       return (retval);
+}
+
+static int
+obio_print_child(device_t bus, device_t child)
+{
+       int retval = 0;
+
+       retval += bus_print_child_header(bus, child);
+       retval += obio_print_all_resources(child);
+       if (device_get_flags(child))
+               retval += printf(" flags %#x", device_get_flags(child));
+       retval += printf(" on %s\n", device_get_nameunit(bus));
+
+       return (retval);
+}
+
+static device_method_t obio_methods[] = {
+       DEVMETHOD(bus_activate_resource,        obio_activate_resource),
+       DEVMETHOD(bus_add_child,                obio_add_child),
+       DEVMETHOD(bus_alloc_resource,           obio_alloc_resource),
+       DEVMETHOD(bus_deactivate_resource,      obio_deactivate_resource),
+       DEVMETHOD(bus_get_resource_list,        obio_get_resource_list),
+       DEVMETHOD(bus_hinted_child,             obio_hinted_child),
+       DEVMETHOD(bus_print_child,              obio_print_child),
+       DEVMETHOD(bus_release_resource,         obio_release_resource),
+       DEVMETHOD(bus_setup_intr,               obio_setup_intr),
+       DEVMETHOD(bus_teardown_intr,            obio_teardown_intr),
+       DEVMETHOD(device_attach,                obio_attach),
+       DEVMETHOD(device_probe,                 obio_probe),
+        DEVMETHOD(bus_get_resource,            bus_generic_rl_get_resource),
+        DEVMETHOD(bus_set_resource,            bus_generic_rl_set_resource),
+
+       {0, 0},
+};
+
+static driver_t obio_driver = {
+       "obio",
+       obio_methods,
+       sizeof(struct obio_softc),
+};
+static devclass_t obio_devclass;
+
+DRIVER_MODULE(obio, nexus, obio_driver, obio_devclass, 0, 0);

Added: head/sys/mips/rt305x/obiovar.h
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/mips/rt305x/obiovar.h      Sun Apr  3 14:39:55 2011        
(r220297)
@@ -0,0 +1,58 @@
+/*     $NetBSD: obiovar.h,v 1.4 2003/06/16 17:40:53 thorpej Exp $      */
+
+/*-
+ * Copyright (c) 2002, 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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 WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#ifndef _RT305X_OBIOVAR_H_
+#define        _RT305X_OBIOVAR_H_
+
+#include <sys/rman.h>
+
+/* Number of IRQs */
+#define        NIRQS   32
+
+
+struct obio_softc {
+       struct rman             oba_mem_rman;
+       struct rman             oba_irq_rman;
+       struct rman             oba_gpio_rman;
+       struct intr_event       *sc_eventstab[NIRQS]; /* IRQ events structs */
+       struct resource         *sc_irq;        /* IRQ resource */
+       void                    *sc_ih;         /* interrupt cookie */
+       struct resource         *sc_fast_irq;   /* IRQ resource */
+       void                    *sc_fast_ih;    /* interrupt cookie */
+};
+
+struct obio_ivar {
+       struct resource_list    resources;
+};
+
+#endif /* _RT305X_OBIOVAR_H_ */

Added: head/sys/mips/rt305x/rt305x_dotg.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/mips/rt305x/rt305x_dotg.c  Sun Apr  3 14:39:55 2011        
(r220297)
@@ -0,0 +1,247 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*-
+ * Copyright (c) 2010,2011 Aleksandr Rybalko. All rights reserved.
+ * Copyright (c) 2007-2008 Hans Petter Selasky. 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

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to