Remove sys/mips/rt305x. It's been replaced by sys/mips/mediatek.

OK'd by: Stanislav Galabov (who did both)
Discussed on: mips@
This commit is contained in:
Warner Losh 2018-01-01 04:06:24 +00:00
parent 9fb36b5eae
commit 039f26fab0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=327457
27 changed files with 0 additions and 6250 deletions

View File

@ -1,150 +0,0 @@
# MT7620 -- Kernel configuration file for FreeBSD/mips for Ralink MT7620 systems
#
# For more information on this file, please read the handbook section on
# Kernel Configuration Files:
#
# https://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 (https://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 MT7620
machine mips mipsel
makeoptions MIPS_LITTLE_ENDIAN=defined
makeoptions KERNLOADADDR=0x80010000
# Don't build any modules yet.
#makeoptions MODULES_OVERRIDE="wlan_xauth wlan_wep wlan_tkip wlan_acl wlan_amrr wlan_ccmp wlan_rssadapt 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 MODULES_OVERRIDE=""
makeoptions MT7620
include "../rt305x/std.rt305x"
hints "MT7620.hints" #Default places to look for devices.
#makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
options MT7620
options RT305X_UBOOT
# 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 TCP_HHOOK # hhook(9) framework for TCP
options NFSCL #Network Filesystem Client
options NFS_ROOT #NFS usable as /, requires NFSCL
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.uzip\"
#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 MROUTING # Multicast routing
options IPFIREWALL_DEFAULT_TO_ACCEPT
options GEOM_UZIP
options MD_ROOT
options ROOTDEVNAME=\"ufs:da0s1\"
device md
device random
device loop
# RT3050F, RT3052F have only pseudo PHYs, so mii not required
device rt
device spibus
device mx25l
device ether
device miibus
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 ehci
#device ohci
#device dwcotg # DWC like USB OTG Controller driver
#device u3g
#device umodem
#device uplcom
device cdce
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
device pci

View File

@ -1,136 +0,0 @@
# 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:
#
# https://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 (https://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 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
options RT3052F
options RT305X_UBOOT
# 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 TCP_HHOOK # hhook(9) framework for TCP
options NFSCL #Network Filesystem Client
options NFS_ROOT #NFS usable as /, requires NFSCL
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.uzip\"
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 MROUTING # Multicast routing
options IPFIREWALL_DEFAULT_TO_ACCEPT
device random
device loop
# RT3050F, RT3052F have only pseudo PHYs, so mii not required
device rt
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 dwcotg # 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

View File

@ -1,126 +0,0 @@
# RT5350 -- Kernel configuration file for FreeBSD/mips for Ralink RT5350 systems
#
# For more information on this file, please read the handbook section on
# Kernel Configuration Files:
#
# https://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 (https://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 RT5350
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 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 RT5350
include "../rt305x/std.rt305x"
hints "RT5350.hints" #Default places to look for devices.
#makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
options RT5350
options RT305X_UBOOT
# 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 INET #InterNETworking
options TCP_HHOOK # hhook(9) framework for TCP
#options NFSCL #Network Filesystem Client
#options NFS_ROOT #NFS usable as /, requires NFSCL
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 TMPFS # TMP Memory Filesystem
options FFS #Berkeley Fast Filesystem
#options ROOTDEVNAME=\"nfs:193.178.153.200:/bsdmips\"
#device geom_uzip
#options GEOM_UZIP
#options MD_ROOT
#options ROOTDEVNAME=\"ufs:md0.uzip\"
# 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 MROUTING # Multicast routing
options IPFIREWALL_DEFAULT_TO_ACCEPT
#device md
device random
device loop
# RT3050F, RT3052F have only pseudo PHYs, so mii not required
device rt
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 nvram2env
device spibus
device mx25l
device usb
device ehci
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

View File

@ -1,19 +0,0 @@
# $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/rt305x/rt305x_dotg.c optional dwcotg
mips/rt305x/rt305x_ehci.c optional ehci
mips/rt305x/rt305x_ohci.c optional ohci
mips/rt305x/rt305x_spi.c optional spibus
mips/rt305x/rt305x_pci.c optional pci
mips/mips/intr_machdep.c standard
mips/mips/tick.c standard
dev/rt/if_rt.c optional rt

View File

@ -1,634 +0,0 @@
/* $NetBSD: obio.c,v 1.11 2003/07/15 00:25:05 lukem Exp $ */
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* 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 *, rman_res_t,
rman_res_t, rman_res_t, 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 (BUS_PROBE_NOWILDCARD);
}
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);
#endif
obio_add_res_child(dev, "uart", 0,
UART_BASE, (UART_END - UART_BASE + 1),
IC_UART);
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);
#endif
obio_add_res_child(dev, "spi", 0,
SPI_BASE, (SPI_END - SPI_BASE + 1),
-1);
obio_add_res_child(dev, "uart", 1,
UARTLITE_BASE, (UARTLITE_END - UARTLITE_BASE + 1),
IC_UARTLITE);
#if !defined(RT5350) && !defined(MT7620)
obio_add_res_child(dev, "cfi", 0,
FLASH_BASE, (FLASH_END - FLASH_BASE + 1),
-1);
obio_add_res_child(dev, "dwcotg", 0,
USB_OTG_BASE, (USB_OTG_END - USB_OTG_BASE + 1),
IC_OTG);
#else
obio_add_res_child(dev, "ehci", 0,
USB_OTG_BASE, (USB_OTG_END - USB_OTG_BASE + 1),
IC_OTG);
obio_add_res_child(dev, "ohci", 0,
USB_OHCI_BASE, (USB_OHCI_END - USB_OHCI_BASE + 1),
IC_OTG);
#endif
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,
rman_res_t start, rman_res_t end, rman_res_t 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 = (RMAN_IS_DEFAULT_RANGE(start, end) && 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 == NULL) {
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);
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, "%#jx");
retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%jd");
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);

View File

@ -1,60 +0,0 @@
/* $NetBSD: obiovar.h,v 1.4 2003/06/16 17:40:53 thorpej Exp $ */
/*-
* SPDX-License-Identifier: BSD-2-Clause-NetBSD
*
* 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_ */

View File

@ -1,233 +0,0 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2015 Stanislav Galabov. All rights reserved.
* 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
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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/stdint.h>
#include <sys/stddef.h>
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <sys/module.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/condvar.h>
#include <sys/sysctl.h>
#include <sys/sx.h>
#include <sys/unistd.h>
#include <sys/callout.h>
#include <sys/malloc.h>
#include <sys/priv.h>
#include <sys/rman.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usb_core.h>
#include <dev/usb/usb_busdma.h>
#include <dev/usb/usb_process.h>
#include <dev/usb/usb_util.h>
#include <dev/usb/usb_controller.h>
#include <dev/usb/usb_bus.h>
#include <dev/usb/controller/dwc_otg.h>
#include <mips/rt305x/rt305xreg.h>
#include <mips/rt305x/rt305x_sysctlvar.h>
#define MEM_RID 0
static device_probe_t dotg_obio_probe;
static device_attach_t dotg_obio_attach;
static device_detach_t dotg_obio_detach;
static int
dotg_obio_probe(device_t dev)
{
device_set_desc(dev, "DWC like USB OTG controller");
return (0);
}
static int
dotg_obio_attach(device_t dev)
{
struct dwc_otg_softc *sc = device_get_softc(dev);
uint32_t tmp;
int err, rid;
/* setup controller interface softc */
/* initialise some bus fields */
sc->sc_mode = DWC_MODE_HOST;
sc->sc_bus.parent = dev;
sc->sc_bus.devices = sc->sc_devices;
sc->sc_bus.devices_max = DWC_OTG_MAX_DEVICES;
sc->sc_bus.dma_bits = 32;
/* get all DMA memory */
if (usb_bus_mem_alloc_all(&sc->sc_bus,
USB_GET_DMA_TAG(dev), NULL)) {
printf("No mem\n");
return (ENOMEM);
}
rid = 0;
sc->sc_io_res =
bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
if (!(sc->sc_io_res)) {
printf("Can`t alloc MEM\n");
goto error;
}
sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
sc->sc_io_size = rman_get_size(sc->sc_io_res);
rid = 0;
sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
&rid, RF_ACTIVE);
if (!(sc->sc_irq_res)) {
printf("Can`t alloc IRQ\n");
goto error;
}
sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
if (!(sc->sc_bus.bdev)) {
printf("Can`t add usbus\n");
goto error;
}
device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
#if (__FreeBSD_version >= 700031)
err = bus_setup_intr(dev, sc->sc_irq_res,
INTR_TYPE_TTY | INTR_MPSAFE, dwc_otg_filter_interrupt,
dwc_otg_interrupt, sc, &sc->sc_intr_hdl);
#else
#error error
err = bus_setup_intr(dev, sc->sc_irq_res,
INTR_TYPE_BIO | INTR_MPSAFE,(driver_intr_t*)dwc_otg_interrupt,
sc, &sc->sc_intr_hdl);
#endif
if (err) {
sc->sc_intr_hdl = NULL;
printf("Can`t set IRQ handle\n");
goto error;
}
/* Run clock for OTG core */
rt305x_sysctl_set(SYSCTL_CLKCFG1, rt305x_sysctl_get(SYSCTL_CLKCFG1) |
SYSCTL_CLKCFG1_OTG_CLK_EN);
tmp = rt305x_sysctl_get(SYSCTL_RSTCTRL);
rt305x_sysctl_set(SYSCTL_RSTCTRL, tmp | SYSCTL_RSTCTRL_OTG);
DELAY(100);
/*
* Docs say that RSTCTRL bits for RT305x are W1C, so there should
* be no need for the below, but who really knows?
*/
// rt305x_sysctl_set(SYSCTL_RSTCTRL, tmp & ~SYSCTL_RSTCTRL_OTG);
// DELAY(100);
err = dwc_otg_init(sc);
if (err) printf("dotg_init fail\n");
if (!err) {
err = device_probe_and_attach(sc->sc_bus.bdev);
if (err) printf("device_probe_and_attach fail %d\n", err);
}
if (err) {
goto error;
}
return (0);
error:
dotg_obio_detach(dev);
return (ENXIO);
}
static int
dotg_obio_detach(device_t dev)
{
struct dwc_otg_softc *sc = device_get_softc(dev);
int err;
/* during module unload there are lots of children leftover */
device_delete_children(dev);
if (sc->sc_irq_res && sc->sc_intr_hdl) {
/*
* only call dotg_obio_uninit() after dotg_obio_init()
*/
dwc_otg_uninit(sc);
/* Stop OTG clock */
rt305x_sysctl_set(SYSCTL_CLKCFG1,
rt305x_sysctl_get(SYSCTL_CLKCFG1) &
~SYSCTL_CLKCFG1_OTG_CLK_EN);
err = bus_teardown_intr(dev, sc->sc_irq_res,
sc->sc_intr_hdl);
sc->sc_intr_hdl = NULL;
}
if (sc->sc_irq_res) {
bus_release_resource(dev, SYS_RES_IRQ, 0,
sc->sc_irq_res);
sc->sc_irq_res = NULL;
}
if (sc->sc_io_res) {
bus_release_resource(dev, SYS_RES_MEMORY, 0,
sc->sc_io_res);
sc->sc_io_res = NULL;
}
usb_bus_mem_free_all(&sc->sc_bus, NULL);
return (0);
}
static device_method_t dotg_obio_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, dotg_obio_probe),
DEVMETHOD(device_attach, dotg_obio_attach),
DEVMETHOD(device_detach, dotg_obio_detach),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
static driver_t dotg_obio_driver = {
.name = "dwcotg",
.methods = dotg_obio_methods,
.size = sizeof(struct dwc_otg_softc),
};
static devclass_t dotg_obio_devclass;
DRIVER_MODULE(dwcotg, obio, dotg_obio_driver, dotg_obio_devclass, 0, 0);

View File

@ -1,239 +0,0 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*-
* Copyright (c) 2015 Stanislav Galabov. All rights reserved.
* 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
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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/stdint.h>
#include <sys/stddef.h>
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <sys/module.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/condvar.h>
#include <sys/sysctl.h>
#include <sys/sx.h>
#include <sys/unistd.h>
#include <sys/callout.h>
#include <sys/malloc.h>
#include <sys/priv.h>
#include <sys/rman.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usb_core.h>
#include <dev/usb/usb_busdma.h>
#include <dev/usb/usb_process.h>
#include <dev/usb/usb_util.h>
#include <dev/usb/usb_controller.h>
#include <dev/usb/usb_bus.h>
#include <dev/usb/controller/ehci.h>
#include <mips/rt305x/rt305xreg.h>
#include <mips/rt305x/rt305x_sysctlvar.h>
#define EHCI_HC_DEVSTR "Ralink integrated USB 2.0 controller"
static device_probe_t ehci_obio_probe;
static device_attach_t ehci_obio_attach;
static device_detach_t ehci_obio_detach;
static int
ehci_obio_probe(device_t self)
{
device_set_desc(self, EHCI_HC_DEVSTR);
return (BUS_PROBE_DEFAULT);
}
static int
ehci_obio_attach(device_t self)
{
ehci_softc_t *sc = device_get_softc(self);
uint32_t reg;
int err;
int rid;
/* setup controller interface softc */
reg = rt305x_sysctl_get(SYSCTL_SYSCFG1);
reg |= SYSCTL_SYSCFG1_USB0_HOST_MODE;
rt305x_sysctl_set(SYSCTL_SYSCFG1, reg);
reg = rt305x_sysctl_get(SYSCTL_CLKCFG1);
reg |= SYSCTL_CLKCFG1_UPHY0_CLK_EN;
#ifdef MT7620
reg |= SYSCTL_CLKCFG1_UPHY1_CLK_EN;
#endif
rt305x_sysctl_set(SYSCTL_CLKCFG1, reg);
reg = rt305x_sysctl_get(SYSCTL_RSTCTRL);
reg |= SYSCTL_RSTCTRL_UPHY0 | SYSCTL_RSTCTRL_UPHY1;
rt305x_sysctl_set(SYSCTL_RSTCTRL, reg);
reg &= ~(SYSCTL_RSTCTRL_UPHY0 | SYSCTL_RSTCTRL_UPHY1);
DELAY(100000);
rt305x_sysctl_set(SYSCTL_RSTCTRL, reg);
DELAY(100000);
/* initialise some bus fields */
sc->sc_bus.parent = self;
sc->sc_bus.devices = sc->sc_devices;
sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
sc->sc_bus.dma_bits = 32;
/* get all DMA memory */
if (usb_bus_mem_alloc_all(&sc->sc_bus,
USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc)) {
printf("No mem\n");
return (ENOMEM);
}
rid = 0;
sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (!sc->sc_io_res) {
device_printf(self, "Could not map memory\n");
goto error;
}
sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
sc->sc_io_size = rman_get_size(sc->sc_io_res);
rid = 0;
sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
RF_SHAREABLE | RF_ACTIVE);
if (sc->sc_irq_res == NULL) {
device_printf(self, "Could not allocate irq\n");
goto error;
}
sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
if (!(sc->sc_bus.bdev)) {
device_printf(self, "Could not add USB device\n");
goto error;
}
device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
device_set_desc(sc->sc_bus.bdev, EHCI_HC_DEVSTR);
sprintf(sc->sc_vendor, "Ralink");
err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
NULL, (driver_intr_t *)ehci_interrupt, sc, &sc->sc_intr_hdl);
if (err) {
device_printf(self, "Could not setup irq, %d\n", err);
sc->sc_intr_hdl = NULL;
goto error;
}
err = ehci_init(sc);
if (!err) {
err = device_probe_and_attach(sc->sc_bus.bdev);
}
if (err) {
device_printf(self, "USB init failed err=%d\n", err);
goto error;
}
return (0);
error:
ehci_obio_detach(self);
return (ENXIO);
}
static int
ehci_obio_detach(device_t self)
{
ehci_softc_t *sc = device_get_softc(self);
int err;
/* during module unload there are lots of children leftover */
device_delete_children(self);
if (sc->sc_irq_res && sc->sc_intr_hdl) {
/*
* only call ehci_detach() after ehci_init()
*/
ehci_detach(sc);
/* Stop EHCI clock */
rt305x_sysctl_set(SYSCTL_CLKCFG1,
rt305x_sysctl_get(SYSCTL_CLKCFG1) &
~(SYSCTL_CLKCFG1_UPHY0_CLK_EN
#ifdef MT7620
| SYSCTL_CLKCFG1_UPHY1_CLK_EN
#endif
));
err = bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl);
if (err)
device_printf(self, "Could not tear down irq, %d\n",
err);
sc->sc_intr_hdl = NULL;
}
if (sc->sc_irq_res) {
bus_release_resource(self, SYS_RES_IRQ, 0,
sc->sc_irq_res);
sc->sc_irq_res = NULL;
}
if (sc->sc_io_res) {
bus_release_resource(self, SYS_RES_MEMORY, 0,
sc->sc_io_res);
sc->sc_io_res = NULL;
}
usb_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc);
return (0);
}
static device_method_t ehci_obio_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ehci_obio_probe),
DEVMETHOD(device_attach, ehci_obio_attach),
DEVMETHOD(device_detach, ehci_obio_detach),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
static driver_t ehci_obio_driver = {
.name = "ehci",
.methods = ehci_obio_methods,
.size = sizeof(ehci_softc_t),
};
static devclass_t ehci_obio_devclass;
DRIVER_MODULE(ehci, obio, ehci_obio_driver, ehci_obio_devclass, 0, 0);

View File

@ -1,628 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2010-2011, Aleksandr Rybalko <ray@ddteam.net>
* Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org>
* Copyright (c) 2009, Luiz Otavio O Souza.
* 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 unmodified, 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
*/
/*
* GPIO driver for RT305X SoC.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/rman.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/gpio.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <mips/rt305x/rt305xreg.h>
#include <mips/rt305x/rt305x_gpio.h>
#include <mips/rt305x/rt305x_gpiovar.h>
#include <mips/rt305x/rt305x_sysctlvar.h>
#include <dev/gpio/gpiobusvar.h>
#include "gpio_if.h"
#ifdef notyet
#define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_INVIN | \
GPIO_PIN_INVOUT | GPIO_PIN_REPORT )
#else
#define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_INVIN | \
GPIO_PIN_INVOUT )
#endif
/*
* Helpers
*/
static void rt305x_gpio_pin_configure(struct rt305x_gpio_softc *sc,
struct gpio_pin *pin, uint32_t flags);
/*
* Driver stuff
*/
static int rt305x_gpio_probe(device_t dev);
static int rt305x_gpio_attach(device_t dev);
static int rt305x_gpio_detach(device_t dev);
static int rt305x_gpio_intr(void *arg);
int rt305x_get_int_mask (device_t);
void rt305x_set_int_mask (device_t, uint32_t);
int rt305x_get_int_status(device_t);
void rt305x_set_int_status(device_t, uint32_t);
/*
* GPIO interface
*/
static device_t rt305x_gpio_get_bus(device_t);
static int rt305x_gpio_pin_max(device_t dev, int *maxpin);
static int rt305x_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps);
static int rt305x_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t
*flags);
static int rt305x_gpio_pin_getname(device_t dev, uint32_t pin, char *name);
static int rt305x_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags);
static int rt305x_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value);
static int rt305x_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val);
static int rt305x_gpio_pin_toggle(device_t dev, uint32_t pin);
static void
rt305x_gpio_pin_configure(struct rt305x_gpio_softc *sc, struct gpio_pin *pin,
unsigned int flags)
{
GPIO_LOCK(sc);
/*
* Manage input/output
*/
if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);
if (flags & GPIO_PIN_OUTPUT) {
pin->gp_flags |= GPIO_PIN_OUTPUT;
GPIO_BIT_SET(sc, pin->gp_pin, DIR);
}
else {
pin->gp_flags |= GPIO_PIN_INPUT;
GPIO_BIT_CLR(sc, pin->gp_pin, DIR);
}
}
if (flags & GPIO_PIN_INVOUT) {
pin->gp_flags |= GPIO_PIN_INVOUT;
GPIO_BIT_SET(sc, pin->gp_pin, POL);
}
else {
pin->gp_flags &= ~GPIO_PIN_INVOUT;
GPIO_BIT_CLR(sc, pin->gp_pin, POL);
}
if (flags & GPIO_PIN_INVIN) {
pin->gp_flags |= GPIO_PIN_INVIN;
GPIO_BIT_SET(sc, pin->gp_pin, POL);
}
else {
pin->gp_flags &= ~GPIO_PIN_INVIN;
GPIO_BIT_CLR(sc, pin->gp_pin, POL);
}
#ifdef notyet
/* Enable interrupt bits for rising/falling transitions */
if (flags & GPIO_PIN_REPORT) {
pin->gp_flags |= GPIO_PIN_REPORT;
GPIO_BIT_SET(sc, pin->gp_pin, RENA);
GPIO_BIT_SET(sc, pin->gp_pin, FENA);
device_printf(sc->dev, "Will report interrupt on pin %d\n",
pin->gp_pin);
}
else {
pin->gp_flags &= ~GPIO_PIN_REPORT;
GPIO_BIT_CLR(sc, pin->gp_pin, RENA);
GPIO_BIT_CLR(sc, pin->gp_pin, FENA);
}
#else
/* Disable generating interrupts for now */
GPIO_BIT_CLR(sc, pin->gp_pin, RENA);
GPIO_BIT_CLR(sc, pin->gp_pin, FENA);
#endif
GPIO_UNLOCK(sc);
}
static device_t
rt305x_gpio_get_bus(device_t dev)
{
struct rt305x_gpio_softc *sc;
sc = device_get_softc(dev);
return (sc->busdev);
}
static int
rt305x_gpio_pin_max(device_t dev, int *maxpin)
{
*maxpin = NGPIO - 1;
return (0);
}
static int
rt305x_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
{
struct rt305x_gpio_softc *sc = device_get_softc(dev);
int i;
for (i = 0; i < sc->gpio_npins; i++) {
if (sc->gpio_pins[i].gp_pin == pin)
break;
}
if (i >= sc->gpio_npins)
return (EINVAL);
GPIO_LOCK(sc);
*caps = sc->gpio_pins[i].gp_caps;
GPIO_UNLOCK(sc);
return (0);
}
static int
rt305x_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
{
struct rt305x_gpio_softc *sc = device_get_softc(dev);
int i;
for (i = 0; i < sc->gpio_npins; i++) {
if (sc->gpio_pins[i].gp_pin == pin)
break;
}
if (i >= sc->gpio_npins)
return (EINVAL);
GPIO_LOCK(sc);
*flags = sc->gpio_pins[i].gp_flags;
GPIO_UNLOCK(sc);
return (0);
}
static int
rt305x_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
{
struct rt305x_gpio_softc *sc = device_get_softc(dev);
int i;
for (i = 0; i < sc->gpio_npins; i++) {
if (sc->gpio_pins[i].gp_pin == pin)
break;
}
if (i >= sc->gpio_npins)
return (EINVAL);
GPIO_LOCK(sc);
memcpy(name, sc->gpio_pins[i].gp_name, GPIOMAXNAME);
GPIO_UNLOCK(sc);
return (0);
}
static int
rt305x_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
{
int i;
struct rt305x_gpio_softc *sc = device_get_softc(dev);
for (i = 0; i < sc->gpio_npins; i++) {
if (sc->gpio_pins[i].gp_pin == pin)
break;
}
if (i >= sc->gpio_npins)
return (EINVAL);
rt305x_gpio_pin_configure(sc, &sc->gpio_pins[i], flags);
return (0);
}
static int
rt305x_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
{
struct rt305x_gpio_softc *sc = device_get_softc(dev);
int i;
for (i = 0; i < sc->gpio_npins; i++) {
if (sc->gpio_pins[i].gp_pin == pin)
break;
}
if (i >= sc->gpio_npins)
return (EINVAL);
GPIO_LOCK(sc);
if (value) GPIO_BIT_SET(sc, i, DATA);
else GPIO_BIT_CLR(sc, i, DATA);
GPIO_UNLOCK(sc);
return (0);
}
static int
rt305x_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
{
struct rt305x_gpio_softc *sc = device_get_softc(dev);
int i;
for (i = 0; i < sc->gpio_npins; i++) {
if (sc->gpio_pins[i].gp_pin == pin)
break;
}
if (i >= sc->gpio_npins)
return (EINVAL);
GPIO_LOCK(sc);
*val = GPIO_BIT_GET(sc, i, DATA);
GPIO_UNLOCK(sc);
return (0);
}
static int
rt305x_gpio_pin_toggle(device_t dev, uint32_t pin)
{
int i;
struct rt305x_gpio_softc *sc = device_get_softc(dev);
for (i = 0; i < sc->gpio_npins; i++) {
if (sc->gpio_pins[i].gp_pin == pin)
break;
}
if (i >= sc->gpio_npins)
return (EINVAL);
GPIO_LOCK(sc);
GPIO_BIT_SET(sc, i, TOG);
GPIO_UNLOCK(sc);
return (0);
}
static int
rt305x_gpio_intr(void *arg)
{
struct rt305x_gpio_softc *sc = arg;
#ifdef notyet
uint32_t i;
#endif
uint64_t input, value;
#ifdef notyet
uint64_t reset_pin;
char notify[16];
char pinname[6];
#endif
/* Read all reported pins */
input = GPIO_READ_ALL(sc, INT);
/* Clear int status */
GPIO_WRITE_ALL(sc, INT, input);
/* Clear report for OUTs */
input &= ~GPIO_READ_ALL(sc, DIR);
value = input & GPIO_READ_ALL(sc, DATA);
if (!input) goto intr_done;
#ifdef notyet
/* if reset_gpio and this pin is input */
if (sc->reset_gpio >= 0 && (input & (1 << sc->reset_gpio))) {
/* get reset_gpio pin value */
reset_pin = (value & (1 << sc->reset_gpio))?1:0;
if ( sc->reset_gpio_last != reset_pin ) {
/*
* if now reset is high, check how long
* and do reset if less than 2 seconds
*/
if ( reset_pin &&
(time_uptime - sc->reset_gpio_ontime) < 2 )
shutdown_nice(0);
sc->reset_gpio_last = reset_pin;
sc->reset_gpio_ontime = time_uptime;
}
}
for ( i = 0; i < NGPIO; i ++ )
{
/* Next if output pin */
if ( !(( input >> i) & 1) ) continue;
if ( (((value & input) >> i) & 1) != sc->gpio_pins[i].gp_last )
{
/* !system=GPIO subsystem=pin7 type=PIN_HIGH period=3 */
snprintf(notify , sizeof(notify ), "period=%d",
(uint32_t)time_uptime - sc->gpio_pins[i].gp_time);
snprintf(pinname, sizeof(pinname), "pin%02d", i);
devctl_notify("GPIO", pinname,
(((value & input) >> i) & 1)?"PIN_HIGH":"PIN_LOW",
notify);
printf("GPIO[%s] %s %s\n", pinname,
(((value & input) >> i) & 1)?"PIN_HIGH":"PIN_LOW",
notify);
sc->gpio_pins[i].gp_last = ((value & input) >> i) & 1;
sc->gpio_pins[i].gp_time = time_uptime;
}
}
#endif
intr_done:
return (FILTER_HANDLED);
}
static int
rt305x_gpio_probe(device_t dev)
{
device_set_desc(dev, "RT305X GPIO driver");
return (0);
}
static uint64_t
rt305x_gpio_init(device_t dev)
{
uint64_t avl = ~0ULL;
uint32_t gmode = rt305x_sysctl_get(SYSCTL_GPIOMODE);
if (!(gmode & SYSCTL_GPIOMODE_RGMII_GPIO_MODE))
avl &= ~RGMII_GPIO_MODE_MASK;
if (!(gmode & SYSCTL_GPIOMODE_SDRAM_GPIO_MODE))
avl &= ~SDRAM_GPIO_MODE_MASK;
if (!(gmode & SYSCTL_GPIOMODE_MDIO_GPIO_MODE))
avl &= ~MDIO_GPIO_MODE_MASK;
if (!(gmode & SYSCTL_GPIOMODE_JTAG_GPIO_MODE))
avl &= ~JTAG_GPIO_MODE_MASK;
if (!(gmode & SYSCTL_GPIOMODE_UARTL_GPIO_MODE))
avl &= ~UARTL_GPIO_MODE_MASK;
if (!(gmode & SYSCTL_GPIOMODE_SPI_GPIO_MODE))
avl &= ~SPI_GPIO_MODE_MASK;
if (!(gmode & SYSCTL_GPIOMODE_I2C_GPIO_MODE))
avl &= ~I2C_GPIO_MODE_MASK;
if ((gmode & SYSCTL_GPIOMODE_UARTF_SHARE_MODE_GPIO) !=
SYSCTL_GPIOMODE_UARTF_SHARE_MODE_GPIO)
avl &= ~I2C_GPIO_MODE_MASK;
/* D-Link DAP-1350 Board have
* MDIO_GPIO_MODE
* UARTF_GPIO_MODE
* SPI_GPIO_MODE
* I2C_GPIO_MODE
* So we have
* 00000001 10000000 01111111 11111110
*/
return (avl);
}
#define DAP1350_RESET_GPIO 10
static int
rt305x_gpio_attach(device_t dev)
{
struct rt305x_gpio_softc *sc = device_get_softc(dev);
int i;
uint64_t avlpins = 0;
sc->reset_gpio = DAP1350_RESET_GPIO;
KASSERT((device_get_unit(dev) == 0),
("rt305x_gpio_gpio: Only one gpio module supported"));
mtx_init(&sc->gpio_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
/* Map control/status registers. */
sc->gpio_mem_rid = 0;
sc->gpio_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&sc->gpio_mem_rid, RF_ACTIVE);
if (sc->gpio_mem_res == NULL) {
device_printf(dev, "couldn't map memory\n");
rt305x_gpio_detach(dev);
return (ENXIO);
}
if ((sc->gpio_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
&sc->gpio_irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
device_printf(dev, "unable to allocate IRQ resource\n");
rt305x_gpio_detach(dev);
return (ENXIO);
}
if ((bus_setup_intr(dev, sc->gpio_irq_res, INTR_TYPE_MISC,
/* rt305x_gpio_filter, */
rt305x_gpio_intr, NULL, sc, &sc->gpio_ih))) {
device_printf(dev,
"WARNING: unable to register interrupt handler\n");
rt305x_gpio_detach(dev);
return (ENXIO);
}
sc->dev = dev;
avlpins = rt305x_gpio_init(dev);
/* Configure all pins as input */
/* disable interrupts for all pins */
/* TODO */
sc->gpio_npins = NGPIO;
resource_int_value(device_get_name(dev), device_get_unit(dev),
"pins", &sc->gpio_npins);
for (i = 0; i < sc->gpio_npins; i++) {
sc->gpio_pins[i].gp_pin = i;
sc->gpio_pins[i].gp_caps = DEFAULT_CAPS;
sc->gpio_pins[i].gp_flags = 0;
}
/* Setup reset pin interrupt */
if (TUNABLE_INT_FETCH("reset_gpio", &sc->reset_gpio)) {
device_printf(dev, "\tHinted reset_gpio %d\n", sc->reset_gpio);
}
#ifdef notyet
if (sc->reset_gpio != -1) {
rt305x_gpio_pin_setflags(dev, sc->reset_gpio,
GPIO_PIN_INPUT|GPIO_PIN_INVOUT|
GPIO_PIN_INVOUT|GPIO_PIN_REPORT);
device_printf(dev, "\tUse reset_gpio %d\n", sc->reset_gpio);
}
#else
if (sc->reset_gpio != -1) {
rt305x_gpio_pin_setflags(dev, sc->reset_gpio,
GPIO_PIN_INPUT|GPIO_PIN_INVOUT);
device_printf(dev, "\tUse reset_gpio %d\n", sc->reset_gpio);
}
#endif
sc->busdev = gpiobus_attach_bus(dev);
if (sc->busdev == NULL) {
rt305x_gpio_detach(dev);
return (ENXIO);
}
return (0);
}
static int
rt305x_gpio_detach(device_t dev)
{
struct rt305x_gpio_softc *sc = device_get_softc(dev);
KASSERT(mtx_initialized(&sc->gpio_mtx), ("gpio mutex not initialized"));
gpiobus_detach_bus(dev);
if (sc->gpio_ih)
bus_teardown_intr(dev, sc->gpio_irq_res, sc->gpio_ih);
if (sc->gpio_irq_res)
bus_release_resource(dev, SYS_RES_IRQ, sc->gpio_irq_rid,
sc->gpio_irq_res);
if (sc->gpio_mem_res)
bus_release_resource(dev, SYS_RES_MEMORY, sc->gpio_mem_rid,
sc->gpio_mem_res);
mtx_destroy(&sc->gpio_mtx);
return(0);
}
#ifdef notyet
static struct resource *
rt305x_gpio_alloc_resource(device_t bus, device_t child, int type, int *rid,
rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
{
struct obio_softc *sc = device_get_softc(bus);
struct resource *rv;
struct rman *rm;
switch (type) {
case SYS_RES_GPIO:
rm = &sc->gpio_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 == NULL) {
printf("%s: could not reserve resource\n", __func__);
return (0);
}
rman_set_rid(rv, *rid);
return (rv);
}
static int
rt305x_gpio_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
return (rman_activate_resource(r));
}
static int
rt305x_gpio_deactivate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
return (rman_deactivate_resource(r));
}
static int
rt305x_gpio_release_resource(device_t dev, device_t child, int type,
int rid, struct resource *r)
{
rman_release_resource(r);
return (0);
}
#endif
static device_method_t rt305x_gpio_methods[] = {
DEVMETHOD(device_probe, rt305x_gpio_probe),
DEVMETHOD(device_attach, rt305x_gpio_attach),
DEVMETHOD(device_detach, rt305x_gpio_detach),
/* GPIO protocol */
DEVMETHOD(gpio_get_bus, rt305x_gpio_get_bus),
DEVMETHOD(gpio_pin_max, rt305x_gpio_pin_max),
DEVMETHOD(gpio_pin_getname, rt305x_gpio_pin_getname),
DEVMETHOD(gpio_pin_getflags, rt305x_gpio_pin_getflags),
DEVMETHOD(gpio_pin_getcaps, rt305x_gpio_pin_getcaps),
DEVMETHOD(gpio_pin_setflags, rt305x_gpio_pin_setflags),
DEVMETHOD(gpio_pin_get, rt305x_gpio_pin_get),
DEVMETHOD(gpio_pin_set, rt305x_gpio_pin_set),
DEVMETHOD(gpio_pin_toggle, rt305x_gpio_pin_toggle),
{0, 0},
};
static driver_t rt305x_gpio_driver = {
"gpio",
rt305x_gpio_methods,
sizeof(struct rt305x_gpio_softc),
};
static devclass_t rt305x_gpio_devclass;
DRIVER_MODULE(rt305x_gpio, obio, rt305x_gpio_driver,
rt305x_gpio_devclass, 0, 0);

View File

@ -1,113 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2010 Aleksandr Rybalko.
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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_GPIO_H_
#define _RT305X_GPIO_H_
#define NGPIO 52
#define RGMII_GPIO_MODE_MASK (0x0fffULL<<40)
#define SDRAM_GPIO_MODE_MASK (0xffffULL<<24)
#define MDIO_GPIO_MODE_MASK (0x0003ULL<<22)
#define JTAG_GPIO_MODE_MASK (0x001fULL<<17)
#define UARTL_GPIO_MODE_MASK (0x0003ULL<<15)
#define UARTF_GPIO_MODE_MASK (0x00ffULL<<7)
#define SPI_GPIO_MODE_MASK (0x000fULL<<3)
#define I2C_GPIO_MODE_MASK (0x0003ULL<<1)
#define GPIO23_00_INT 0x00 /* Programmed I/O Int Status */
#define GPIO23_00_EDGE 0x04 /* Programmed I/O Edge Status */
#define GPIO23_00_RENA 0x08 /* Programmed I/O Int on Rising */
#define GPIO23_00_FENA 0x0C /* Programmed I/O Int on Falling */
#define GPIO23_00_DATA 0x20 /* Programmed I/O Data */
#define GPIO23_00_DIR 0x24 /* Programmed I/O Direction */
#define GPIO23_00_POL 0x28 /* Programmed I/O Pin Polarity */
#define GPIO23_00_SET 0x2C /* Set PIO Data Bit */
#define GPIO23_00_RESET 0x30 /* Clear PIO Data bit */
#define GPIO23_00_TOG 0x34 /* Toggle PIO Data bit */
#define GPIO39_24_INT 0x38
#define GPIO39_24_EDGE 0x3c
#define GPIO39_24_RENA 0x40
#define GPIO39_24_FENA 0x44
#define GPIO39_24_DATA 0x48
#define GPIO39_24_DIR 0x4c
#define GPIO39_24_POL 0x50
#define GPIO39_24_SET 0x54
#define GPIO39_24_RESET 0x58
#define GPIO39_24_TOG 0x5c
#define GPIO51_40_INT 0x60
#define GPIO51_40_EDGE 0x64
#define GPIO51_40_RENA 0x68
#define GPIO51_40_FENA 0x6C
#define GPIO51_40_DATA 0x70
#define GPIO51_40_DIR 0x74
#define GPIO51_40_POL 0x78
#define GPIO51_40_SET 0x7C
#define GPIO51_40_RESET 0x80
#define GPIO51_40_TOG 0x84
#define GPIO_REG(g, n) \
((g<24)?(GPIO23_00_##n):(g<40)?(GPIO39_24_##n):(GPIO51_40_##n))
#define GPIO_MASK(g) \
((g<24)?(1<<g):(g<40)?(1<<(g-24)):(1<<(g-40)))
#define GPIO_BIT_SHIFT(g) ((g<24)?(g):(g<40)?(g-24):(g-40))
#define GPIO_READ(r, g, n) \
bus_read_4(r->gpio_mem_res, GPIO_REG(g, n))
#define GPIO_WRITE(r, g, n, v) \
bus_write_4(r->gpio_mem_res, GPIO_REG(g, n), v)
#define GPIO_READ_ALL(r, n) \
(((uint64_t)bus_read_4(r->gpio_mem_res, GPIO23_00_##n)) | \
(((uint64_t)bus_read_4(r->gpio_mem_res, GPIO39_24_##n)) << 24) |\
(((uint64_t)bus_read_4(r->gpio_mem_res, GPIO51_40_##n)) << 40))
#define GPIO_WRITE_ALL(r, n, v) \
{bus_write_4(r->gpio_mem_res,GPIO23_00_##n, v &0x00ffffff);\
bus_write_4(r->gpio_mem_res, GPIO39_24_##n, (v>>24)&0x0000ffff);\
bus_write_4(r->gpio_mem_res, GPIO51_40_##n, (v>>40)&0x00000fff);}
#define GPIO_BIT_CLR(r, g, n) \
bus_write_4(r->gpio_mem_res, GPIO_REG(g, n), \
bus_read_4(r->gpio_mem_res, GPIO_REG(g, n)) & ~GPIO_MASK(g))
#define GPIO_BIT_SET(r, g, n) \
bus_write_4(r->gpio_mem_res, GPIO_REG(g, n), \
bus_read_4(r->gpio_mem_res, GPIO_REG(g, n)) | GPIO_MASK(g))
#define GPIO_BIT_GET(r, g, n) \
((bus_read_4(r->gpio_mem_res, GPIO_REG(g, n)) >> \
GPIO_BIT_SHIFT(g)) & 1)
#define GPIO_LOCK(_sc) mtx_lock(&(_sc)->gpio_mtx)
#define GPIO_UNLOCK(_sc) mtx_unlock(&(_sc)->gpio_mtx)
#define GPIO_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->gpio_mtx, MA_OWNED)
#endif /* _RT305X_GPIO_H_ */

View File

@ -1,51 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2010 Aleksandr Rybalko.
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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_GPIOVAR_H_
#define _RT305X_GPIOVAR_H_
struct rt305x_gpio_softc {
device_t dev;
device_t busdev;
struct mtx gpio_mtx;
struct resource *gpio_mem_res;
int gpio_mem_rid;
struct resource *gpio_irq_res;
int gpio_irq_rid;
void *gpio_ih;
int gpio_npins;
struct gpio_pin gpio_pins[NGPIO];
int reset_gpio;
int reset_gpio_last;
time_t reset_gpio_ontime;
};
#endif /* _RT305X_GPIOVAR_H_ */

View File

@ -1,143 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2010 Aleksandr Rybalko.
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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/rt305x_icvar.h>
static int rt305x_ic_probe(device_t);
static int rt305x_ic_attach(device_t);
static int rt305x_ic_detach(device_t);
static struct rt305x_ic_softc *rt305x_ic_softc = NULL;
static int
rt305x_ic_probe(device_t dev)
{
device_set_desc(dev, "RT305X Interrupt Controller driver");
return (0);
}
static int
rt305x_ic_attach(device_t dev)
{
struct rt305x_ic_softc *sc = device_get_softc(dev);
int error = 0;
KASSERT((device_get_unit(dev) == 0),
("rt305x_ic: Only one Interrupt Controller module supported"));
if (rt305x_ic_softc != NULL)
return (ENXIO);
rt305x_ic_softc = sc;
/* Map control/status registers. */
sc->mem_rid = 0;
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&sc->mem_rid, RF_ACTIVE);
if (sc->mem_res == NULL) {
device_printf(dev, "couldn't map memory\n");
error = ENXIO;
rt305x_ic_detach(dev);
return(error);
}
return (bus_generic_attach(dev));
}
static int
rt305x_ic_detach(device_t dev)
{
struct rt305x_ic_softc *sc = device_get_softc(dev);
bus_generic_detach(dev);
if (sc->mem_res)
bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid,
sc->mem_res);
return(0);
}
uint32_t
rt305x_ic_get(uint32_t reg)
{
struct rt305x_ic_softc *sc = rt305x_ic_softc;
if (!sc)
return (0);
return (bus_read_4(sc->mem_res, reg));
}
void
rt305x_ic_set(uint32_t reg, uint32_t val)
{
struct rt305x_ic_softc *sc = rt305x_ic_softc;
if (!sc)
return;
bus_write_4(sc->mem_res, reg, val);
return;
}
static device_method_t rt305x_ic_methods[] = {
DEVMETHOD(device_probe, rt305x_ic_probe),
DEVMETHOD(device_attach, rt305x_ic_attach),
DEVMETHOD(device_detach, rt305x_ic_detach),
{0, 0},
};
static driver_t rt305x_ic_driver = {
"rt305x_ic",
rt305x_ic_methods,
sizeof(struct rt305x_ic_softc),
};
static devclass_t rt305x_ic_devclass;
DRIVER_MODULE(rt305x_ic, obio, rt305x_ic_driver, rt305x_ic_devclass, 0, 0);

View File

@ -1,44 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2010 Aleksandr Rybalko.
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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_ICVAR_H_
#define _RT305X_ICVAR_H_
struct rt305x_ic_softc {
device_t dev;
struct resource *mem_res;
int mem_rid;
};
uint32_t rt305x_ic_get(uint32_t);
void rt305x_ic_set(uint32_t, uint32_t);
#endif /* _RT305X_ICVAR_H_ */

View File

@ -1,209 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (C) 2010-2011 by Aleksandr Rybalko. All rights reserved.
* Copyright (C) 2007 by Oleksandr Tymoshenko. 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 OR HIS RELATIVES 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 MIND, 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 "opt_ddb.h"
#include <sys/param.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/imgact.h>
#include <sys/bio.h>
#include <sys/buf.h>
#include <sys/bus.h>
#include <sys/cpu.h>
#include <sys/cons.h>
#include <sys/exec.h>
#include <sys/ucontext.h>
#include <sys/proc.h>
#include <sys/kdb.h>
#include <sys/ptrace.h>
#include <sys/reboot.h>
#include <sys/signalvar.h>
#include <sys/sysent.h>
#include <sys/sysproto.h>
#include <sys/user.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <machine/cache.h>
#include <machine/clock.h>
#include <machine/cpu.h>
#include <machine/cpuinfo.h>
#include <machine/cpufunc.h>
#include <machine/cpuregs.h>
#include <machine/hwfunc.h>
#include <machine/intr_machdep.h>
#include <machine/locore.h>
#include <machine/md_var.h>
#include <machine/pte.h>
#include <machine/sigframe.h>
#include <machine/trap.h>
#include <machine/vmparam.h>
#include <mips/rt305x/rt305xreg.h>
#include <mips/rt305x/rt305x_sysctlvar.h>
extern int *edata;
extern int *end;
static char boot1_env[0x1000];
void
platform_cpu_init()
{
/* Nothing special */
}
static void
mips_init(void)
{
int i;
char *memsize;
printf("entry: mips_init()\n");
if ((memsize = kern_getenv("memsize")) != NULL)
realmem = btoc(strtol(memsize, NULL, 0) << 20);
else
realmem = btoc(32 << 20);
bootverbose = 1;
for (i = 0; i < 10; i++) {
phys_avail[i] = 0;
}
/* phys_avail regions are in bytes */
dump_avail[0] = phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end);
dump_avail[1] = phys_avail[1] = ctob(realmem);
physmem = realmem;
init_param1();
init_param2(physmem);
mips_cpu_init();
pmap_bootstrap();
mips_proc0_init();
mutex_init();
kdb_init();
#ifdef KDB
if (boothowto & RB_KDB)
kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
#endif
}
void
platform_reset(void)
{
#if !defined(MT7620) && !defined(RT5350)
__asm __volatile("li $25, 0xbf000000");
__asm __volatile("j $25");
#else
rt305x_sysctl_set(SYSCTL_RSTCTRL, 1);
while (1);
#endif
}
void
platform_start(__register_t a0 __unused, __register_t a1 __unused,
__register_t a2 __unused, __register_t a3 __unused)
{
vm_offset_t kernend;
uint64_t platform_counter_freq = PLATFORM_COUNTER_FREQ;
int i;
int argc = a0;
char **argv = (char **)MIPS_PHYS_TO_KSEG0(a1);
char **envp = (char **)MIPS_PHYS_TO_KSEG0(a2);
/* clear the BSS and SBSS segments */
kernend = (vm_offset_t)&end;
memset(&edata, 0, kernend - (vm_offset_t)(&edata));
mips_postboot_fixup();
/* Initialize pcpu stuff */
mips_pcpu0_init();
mips_timer_early_init(platform_counter_freq / 2);
/* initialize console so that we have printf */
boothowto |= (RB_SERIAL | RB_MULTIPLE); /* Use multiple consoles */
boothowto |= (RB_VERBOSE);
cninit();
init_static_kenv(boot1_env, sizeof(boot1_env));
printf("U-Boot args (from %d args):\n", argc - 1);
if (argc == 1)
printf("\tNone\n");
for (i = 1; i < argc; i++) {
char *n = "argv ", *arg;
if (i > 99)
break;
if (argv[i])
{
arg = (char *)(intptr_t)MIPS_PHYS_TO_KSEG0(argv[i]);
printf("\targv[%d] = %s\n", i, arg);
sprintf(n, "argv%d", i);
kern_setenv(n, arg);
}
}
printf("Environment:\n");
for (i = 0; envp[i] && MIPS_IS_VALID_PTR(envp[i]); i++) {
char *n, *arg;
arg = (char *)(intptr_t)MIPS_PHYS_TO_KSEG0(envp[i]);
if (! MIPS_IS_VALID_PTR(arg))
continue;
printf("\t%s\n", arg);
n = strsep(&arg, "=");
if (arg == NULL)
kern_setenv(n, "1");
else
kern_setenv(n, arg);
}
mips_init();
mips_timer_init_params(platform_counter_freq, 1);
}

View File

@ -1,239 +0,0 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*-
* Copyright (c) 2015 Stanislav Galabov. All rights reserved.
* 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
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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/stdint.h>
#include <sys/stddef.h>
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <sys/module.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/condvar.h>
#include <sys/sysctl.h>
#include <sys/sx.h>
#include <sys/unistd.h>
#include <sys/callout.h>
#include <sys/malloc.h>
#include <sys/priv.h>
#include <sys/rman.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usb_core.h>
#include <dev/usb/usb_busdma.h>
#include <dev/usb/usb_process.h>
#include <dev/usb/usb_util.h>
#include <dev/usb/usb_controller.h>
#include <dev/usb/usb_bus.h>
#include <dev/usb/controller/ohci.h>
#include <mips/rt305x/rt305xreg.h>
#include <mips/rt305x/rt305x_sysctlvar.h>
#define OHCI_HC_DEVSTR "Ralink integrated USB controller"
static device_probe_t ohci_obio_probe;
static device_attach_t ohci_obio_attach;
static device_detach_t ohci_obio_detach;
static int
ohci_obio_probe(device_t self)
{
device_set_desc(self, OHCI_HC_DEVSTR);
return (BUS_PROBE_DEFAULT);
}
static int
ohci_obio_attach(device_t self)
{
ohci_softc_t *sc = device_get_softc(self);
uint32_t reg;
int err;
int rid;
/* setup controller interface softc */
reg = rt305x_sysctl_get(SYSCTL_SYSCFG1);
reg |= SYSCTL_SYSCFG1_USB0_HOST_MODE;
rt305x_sysctl_set(SYSCTL_SYSCFG1, reg);
reg = rt305x_sysctl_get(SYSCTL_CLKCFG1);
reg |= SYSCTL_CLKCFG1_UPHY0_CLK_EN;
#ifdef MT7620
reg |= SYSCTL_CLKCFG1_UPHY1_CLK_EN;
#endif
rt305x_sysctl_set(SYSCTL_CLKCFG1, reg);
reg = rt305x_sysctl_get(SYSCTL_RSTCTRL);
reg |= SYSCTL_RSTCTRL_UPHY0 | SYSCTL_RSTCTRL_UPHY1;
rt305x_sysctl_set(SYSCTL_RSTCTRL, reg);
reg &= ~(SYSCTL_RSTCTRL_UPHY0 | SYSCTL_RSTCTRL_UPHY1);
DELAY(100000);
rt305x_sysctl_set(SYSCTL_RSTCTRL, reg);
DELAY(100000);
/* initialise some bus fields */
sc->sc_bus.parent = self;
sc->sc_bus.devices = sc->sc_devices;
sc->sc_bus.devices_max = OHCI_MAX_DEVICES;
sc->sc_bus.dma_bits = 32;
/* get all DMA memory */
if (usb_bus_mem_alloc_all(&sc->sc_bus,
USB_GET_DMA_TAG(self), &ohci_iterate_hw_softc)) {
printf("No mem\n");
return (ENOMEM);
}
rid = 0;
sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (!sc->sc_io_res) {
device_printf(self, "Could not map memory\n");
goto error;
}
sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
sc->sc_io_size = rman_get_size(sc->sc_io_res);
rid = 0;
sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
RF_SHAREABLE | RF_ACTIVE);
if (sc->sc_irq_res == NULL) {
device_printf(self, "Could not allocate irq\n");
goto error;
}
sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
if (!(sc->sc_bus.bdev)) {
device_printf(self, "Could not add USB device\n");
goto error;
}
device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
device_set_desc(sc->sc_bus.bdev, OHCI_HC_DEVSTR);
sprintf(sc->sc_vendor, "Ralink");
err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
NULL, (driver_intr_t *)ohci_interrupt, sc, &sc->sc_intr_hdl);
if (err) {
device_printf(self, "Could not setup irq, %d\n", err);
sc->sc_intr_hdl = NULL;
goto error;
}
err = ohci_init(sc);
if (!err) {
err = device_probe_and_attach(sc->sc_bus.bdev);
}
if (err) {
device_printf(self, "USB init failed err=%d\n", err);
goto error;
}
return (0);
error:
ohci_obio_detach(self);
return (ENXIO);
}
static int
ohci_obio_detach(device_t self)
{
ohci_softc_t *sc = device_get_softc(self);
int err;
/* during module unload there are lots of children leftover */
device_delete_children(self);
if (sc->sc_irq_res && sc->sc_intr_hdl) {
/*
* only call ohci_detach() after ohci_init()
*/
ohci_detach(sc);
/* Stop OHCI clock */
rt305x_sysctl_set(SYSCTL_CLKCFG1,
rt305x_sysctl_get(SYSCTL_CLKCFG1) &
~(SYSCTL_CLKCFG1_UPHY0_CLK_EN
#ifdef MT7620
| SYSCTL_CLKCFG1_UPHY1_CLK_EN
#endif
));
err = bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl);
if (err)
device_printf(self, "Could not tear down irq, %d\n",
err);
sc->sc_intr_hdl = NULL;
}
if (sc->sc_irq_res) {
bus_release_resource(self, SYS_RES_IRQ, 0,
sc->sc_irq_res);
sc->sc_irq_res = NULL;
}
if (sc->sc_io_res) {
bus_release_resource(self, SYS_RES_MEMORY, 0,
sc->sc_io_res);
sc->sc_io_res = NULL;
}
usb_bus_mem_free_all(&sc->sc_bus, &ohci_iterate_hw_softc);
return (0);
}
static device_method_t ohci_obio_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ohci_obio_probe),
DEVMETHOD(device_attach, ohci_obio_attach),
DEVMETHOD(device_detach, ohci_obio_detach),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
static driver_t ohci_obio_driver = {
.name = "ohci",
.methods = ohci_obio_methods,
.size = sizeof(ohci_softc_t),
};
static devclass_t ohci_obio_devclass;
DRIVER_MODULE(ohci, obio, ohci_obio_driver, ohci_obio_devclass, 0, 0);

View File

@ -1,955 +0,0 @@
/*-
* Copyright (c) 2015 Stanislav Galabov.
*
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
*
* This is based on the pci allocator code from sys/dev/arm/mv/:
*
* Copyright (c) 2008 MARVELL INTERNATIONAL LTD.
* Copyright (c) 2010 The FreeBSD Foundation
* Copyright (c) 2010-2012 Semihalf
* All rights reserved.
*
* Developed by Semihalf.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/interrupt.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/rman.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/endian.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_extern.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/intr_machdep.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcib_private.h>
#include "pcib_if.h"
#include <mips/rt305x/rt305xreg.h>
#include <mips/rt305x/rt305x_pcireg.h>
#include <mips/rt305x/rt305x_sysctlvar.h>
struct mtx rt305x_pci_mtx;
MTX_SYSINIT(rt305x_pci_mtx, &rt305x_pci_mtx, "rt305x PCI/PCIe mutex", MTX_SPIN);
struct rt305x_pci_softc {
device_t sc_dev;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
int sc_busno;
struct rman sc_mem_rman;
struct rman sc_io_rman;
struct rman sc_irq_rman;
bus_addr_t sc_mem_base;
bus_addr_t sc_mem_size;
uint32_t sc_mem_map[(256*1024*1024) /
(PCI_MIN_MEM_ALLOC * BITS_PER_UINT32)];
bus_addr_t sc_io_base;
bus_addr_t sc_io_size;
uint32_t sc_io_map[(16*1024*1024) /
(PCI_MIN_IO_ALLOC * BITS_PER_UINT32)];
struct intr_event *sc_eventstab[RT305X_PCI_NIRQS];
mips_intrcnt_t sc_intr_counter[RT305X_PCI_NIRQS];
int pcie_link_status;
};
static void rt305x_pci_phy_init(device_t);
static void rt305x_pci_init(device_t);
static int rt305x_pcib_init(device_t, int, int);
static int rt305x_pci_intr(void *);
static void rt305x_pci_dump_regs(device_t);
static struct rt305x_pci_softc *rt_sc = NULL;
static int
rt305x_pci_probe(device_t dev)
{
return (BUS_PROBE_NOWILDCARD);
}
static int
rt305x_pci_attach(device_t dev)
{
struct rt305x_pci_softc *sc = device_get_softc(dev);
rt_sc = sc;
sc->sc_dev = dev;
sc->sc_mem_base = PCIE_MEM_BASE;
sc->sc_mem_size = 0x10000000;
sc->sc_io_base = PCIE_IO_BASE;
sc->sc_io_size = 0x10000;
sc->sc_bsh = MIPS_PHYS_TO_KSEG1(PCIE_BASE);
sc->sc_bst = mips_bus_space_generic;
sc->sc_mem_rman.rm_type = RMAN_ARRAY;
sc->sc_mem_rman.rm_descr = "rt305x pci memory window";
if (rman_init(&sc->sc_mem_rman) != 0 ||
rman_manage_region(&sc->sc_mem_rman, sc->sc_mem_base,
sc->sc_mem_base + sc->sc_mem_size - 1) != 0) {
panic("%s: failed to set up memory rman", __FUNCTION__);
}
sc->sc_io_rman.rm_type = RMAN_ARRAY;
sc->sc_io_rman.rm_descr = "rt305x pci io window";
if (rman_init(&sc->sc_io_rman) != 0 ||
rman_manage_region(&sc->sc_io_rman, sc->sc_io_base,
sc->sc_io_base + sc->sc_io_size - 1) != 0) {
panic("%s: failed to set up io rman", __FUNCTION__);
}
sc->sc_irq_rman.rm_type = RMAN_ARRAY;
sc->sc_irq_rman.rm_descr = "rt305x pci irqs";
if (rman_init(&sc->sc_irq_rman) != 0 ||
rman_manage_region(&sc->sc_irq_rman, RT305X_PCIE0_IRQ,
RT305X_PCIE0_IRQ) != 0) {
panic("%s: failed to set up irq rman", __FUNCTION__);
}
cpu_establish_hardintr("pci", rt305x_pci_intr, NULL, sc,
RT305X_PCI_INTR_PIN, INTR_TYPE_MISC | INTR_EXCL, NULL);
rt305x_pci_phy_init(dev);
rt305x_pci_init(dev);
rt305x_pci_dump_regs(dev);
rt305x_pcib_init(dev, 0, PCI_SLOTMAX);
device_add_child(dev, "pci", -1);
return (bus_generic_attach(dev));
}
static int
rt305x_pci_read_ivar(device_t dev, device_t child, int which,
uintptr_t *result)
{
struct rt305x_pci_softc *sc = device_get_softc(dev);
switch (which) {
case PCIB_IVAR_DOMAIN:
*result = device_get_unit(dev);
return (0);
case PCIB_IVAR_BUS:
*result = sc->sc_busno;
return (0);
}
return (ENOENT);
}
static int
rt305x_pci_write_ivar(device_t dev, device_t child, int which,
uintptr_t result)
{
struct rt305x_pci_softc *sc = device_get_softc(dev);
switch (which) {
case PCIB_IVAR_BUS:
sc->sc_busno = result;
return (0);
}
return (ENOENT);
}
static struct resource *
rt305x_pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
{
struct rt305x_pci_softc *sc = device_get_softc(bus);
struct resource *rv;
struct rman *rm;
vm_offset_t va;
switch (type) {
case SYS_RES_IRQ:
rm = &sc->sc_irq_rman;
break;
case SYS_RES_IOPORT:
rm = &sc->sc_io_rman;
break;
case SYS_RES_MEMORY:
rm = &sc->sc_mem_rman;
break;
default:
return (NULL);
}
rv = rman_reserve_resource(rm, start, end, count, flags, child);
if (rv == NULL)
return (NULL);
rman_set_rid(rv, *rid);
if (type != SYS_RES_IRQ) {
if (type == SYS_RES_MEMORY) {
va = (vm_offset_t)pmap_mapdev(start, count);
} else if (type == SYS_RES_IOPORT){
va = (vm_offset_t)MIPS_PHYS_TO_KSEG1(start);
}
rman_set_bushandle(rv, va);
rman_set_virtual(rv, (void *)va);
rman_set_bustag(rv, mips_bus_space_generic);
}
if (flags & RF_ACTIVE) {
if (bus_activate_resource(child, type, *rid, rv)) {
rman_release_resource(rv);
return (NULL);
}
}
return (rv);
}
static int
rt305x_pci_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
return rman_activate_resource(r);
}
static inline int
rt305x_idx_to_irq(int idx)
{
return ((idx == 0) ? RT305X_PCIE0_IRQ :
(idx == 1) ? RT305X_PCIE1_IRQ :
(idx == 2) ? RT305X_PCIE2_IRQ : -1);
}
static inline int
rt305x_irq_to_idx(int irq)
{
return ((irq == RT305X_PCIE0_IRQ) ? 0 :
(irq == RT305X_PCIE1_IRQ) ? 1 :
(irq == RT305X_PCIE2_IRQ) ? 2 : -1);
}
static void
rt305x_pci_mask_irq(void *source)
{
RT_WRITE32(rt_sc, RT305X_PCI_PCIENA,
RT_READ32(rt_sc, RT305X_PCI_PCIENA) & ~(1<<((int)source)));
}
static void
rt305x_pci_unmask_irq(void *source)
{
RT_WRITE32(rt_sc, RT305X_PCI_PCIENA,
RT_READ32(rt_sc, RT305X_PCI_PCIENA) | (1<<((int)source)));
}
static int
rt305x_pci_setup_intr(device_t bus, device_t child, struct resource *ires,
int flags, driver_filter_t *filt, driver_intr_t *handler,
void *arg, void **cookiep)
{
struct rt305x_pci_softc *sc = device_get_softc(bus);
struct intr_event *event;
int irq, error, irqidx;
irq = rman_get_start(ires);
if ((irqidx = rt305x_irq_to_idx(irq)) == -1)
panic("%s: bad irq %d", __FUNCTION__, irq);
event = sc->sc_eventstab[irqidx];
if (event == NULL) {
error = intr_event_create(&event, (void *)irq, 0, irq,
rt305x_pci_mask_irq, rt305x_pci_unmask_irq, NULL, NULL,
"pci intr%d:", irq);
if (error == 0) {
sc->sc_eventstab[irqidx] = event;
sc->sc_intr_counter[irqidx] =
mips_intrcnt_create(event->ie_name);
}
else
return (error);
}
intr_event_add_handler(event, device_get_nameunit(child), filt,
handler, arg, intr_priority(flags), flags, cookiep);
mips_intrcnt_setname(sc->sc_intr_counter[irqidx], event->ie_fullname);
rt305x_pci_unmask_irq((void*)irq);
return (0);
}
static int
rt305x_pci_teardown_intr(device_t dev, device_t child, struct resource *ires,
void *cookie)
{
struct rt305x_pci_softc *sc = device_get_softc(dev);
int irq, result, irqidx;
irq = rman_get_start(ires);
if ((irqidx = rt305x_irq_to_idx(irq)) == -1)
panic("%s: bad irq %d", __FUNCTION__, irq);
if (sc->sc_eventstab[irqidx] == NULL)
panic("Trying to teardown unoccupied IRQ");
rt305x_pci_mask_irq((void*)irq);
result = intr_event_remove_handler(cookie);
if (!result)
sc->sc_eventstab[irqidx] = NULL;
return (result);
}
static inline uint32_t
rt305x_pci_make_addr(int bus, int slot, int func, int reg)
{
uint32_t addr;
addr = (((reg & 0xf00) >> 8) << 24) | (bus << 16) | (slot << 11) |
(func << 8) | (reg & 0xfc) | (1 << 31);
return (addr);
}
static int
rt305x_pci_maxslots(device_t dev)
{
return (PCI_SLOTMAX);
}
static uint32_t
rt305x_pci_read_config(device_t dev, u_int bus, u_int slot, u_int func,
u_int reg, int bytes)
{
struct rt305x_pci_softc *sc = device_get_softc(dev);
uint32_t addr = 0, data = 0;
if (bus == 0 && (sc->pcie_link_status & (1<<slot)) == 0)
return (~0U);
mtx_lock_spin(&rt305x_pci_mtx);
addr = rt305x_pci_make_addr(bus, slot, func, (reg & ~3));
RT_WRITE32(sc, RT305X_PCI_CFGADDR, addr);
switch (bytes % 4) {
case 0:
data = RT_READ32(sc, RT305X_PCI_CFGDATA);
break;
case 1:
data = RT_READ8(sc, RT305X_PCI_CFGDATA + (reg & 0x3));
break;
case 2:
data = RT_READ16(sc, RT305X_PCI_CFGDATA + (reg & 0x3));
break;
default:
panic("%s(): Wrong number of bytes (%d) requested!\n",
__FUNCTION__, bytes % 4);
}
mtx_unlock_spin(&rt305x_pci_mtx);
return (data);
}
static void
rt305x_pci_write_config(device_t dev, u_int bus, u_int slot, u_int func,
u_int reg, uint32_t val, int bytes)
{
struct rt305x_pci_softc *sc = device_get_softc(dev);
uint32_t addr = 0, data = val;
if (bus == 0 && (sc->pcie_link_status & (1<<slot)) == 0)
return;
mtx_lock_spin(&rt305x_pci_mtx);
addr = rt305x_pci_make_addr(bus, slot, func, (reg & ~3));
RT_WRITE32(sc, RT305X_PCI_CFGADDR, addr);
switch (bytes % 4) {
case 0:
RT_WRITE32(sc, RT305X_PCI_CFGDATA, data);
break;
case 1:
RT_WRITE8(sc, RT305X_PCI_CFGDATA + (reg & 0x3), data);
break;
case 2:
RT_WRITE16(sc, RT305X_PCI_CFGDATA + (reg & 0x3), data);
break;
default:
panic("%s(): Wrong number of bytes (%d) requested!\n",
__FUNCTION__, bytes % 4);
}
mtx_unlock_spin(&rt305x_pci_mtx);
}
static int
rt305x_pci_route_interrupt(device_t pcib, device_t device, int pin)
{
//struct rt305x_pci_softc *sc = device_get_softc(pcib);
int bus, sl;
bus = pci_get_bus(device);
sl = pci_get_slot(device);
if (bus != 0)
panic("Unexpected bus number %d\n", bus);
//printf("%s: not done yet.\n", __FUNCTION__);
switch (sl) {
case 0: return RT305X_PCIE0_IRQ;
default: return (-1);
}
return (-1);
}
static device_method_t rt305x_pci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, rt305x_pci_probe),
DEVMETHOD(device_attach, rt305x_pci_attach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
/* Bus interface */
DEVMETHOD(bus_read_ivar, rt305x_pci_read_ivar),
DEVMETHOD(bus_write_ivar, rt305x_pci_write_ivar),
DEVMETHOD(bus_alloc_resource, rt305x_pci_alloc_resource),
DEVMETHOD(bus_release_resource, bus_generic_release_resource),
DEVMETHOD(bus_activate_resource, rt305x_pci_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_setup_intr, rt305x_pci_setup_intr),
DEVMETHOD(bus_teardown_intr, rt305x_pci_teardown_intr),
/* pcib interface */
DEVMETHOD(pcib_maxslots, rt305x_pci_maxslots),
DEVMETHOD(pcib_read_config, rt305x_pci_read_config),
DEVMETHOD(pcib_write_config, rt305x_pci_write_config),
DEVMETHOD(pcib_route_interrupt, rt305x_pci_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),
DEVMETHOD_END
};
static driver_t rt305x_pci_driver = {
"pcib",
rt305x_pci_methods,
sizeof(struct rt305x_pci_softc),
};
static devclass_t rt305x_pci_devclass;
DRIVER_MODULE(rt305x_pci, nexus, rt305x_pci_driver, rt305x_pci_devclass, 0, 0);
static void
rt305x_pci_dump_regs(device_t dev)
{
#if 0
struct rt305x_pci_softc *sc = device_get_softc(dev);
uint32_t reg = 0;
reg = 0x0000;
printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
reg = 0x0008;
printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
reg = 0x000c;
printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
reg = 0x0020;
printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
reg = 0x0024;
printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
reg = 0x0028;
printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
reg = 0x002c;
printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
reg = 0x2010;
printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
reg = 0x2014;
printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
reg = 0x2018;
printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
reg = 0x2030;
printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
reg = 0x2034;
printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
reg = 0x2038;
printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
reg = 0x2050;
printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
reg = 0x2060;
printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
reg = 0x2064;
printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
#endif
}
static void
rt305x_pci_init(device_t dev)
{
struct rt305x_pci_softc *sc = device_get_softc(dev);
uint32_t tmp;
rt305x_sysctl_set(SYSCTL_SYSCFG1,
rt305x_sysctl_get(SYSCTL_SYSCFG1) | (1 << 8));
rt305x_sysctl_set(SYSCTL_GPIOMODE,
rt305x_sysctl_get(SYSCTL_GPIOMODE) & ~(0x3 << 16));
rt305x_sysctl_set(SYSCTL_RSTCTRL,
rt305x_sysctl_get(SYSCTL_RSTCTRL) & ~(1<<26));
rt305x_sysctl_set(SYSCTL_CLKCFG1,
rt305x_sysctl_get(SYSCTL_CLKCFG1) | (1<<26));
tmp = rt305x_sysctl_get(SYSCTL_PPLL_CFG1);
if ((tmp & (1<<23)) == 0) {
device_printf(dev, "PPLL not locked\n");
return;
}
tmp = rt305x_sysctl_get(SYSCTL_PPLL_DRV);
tmp |= (1<<19);
rt305x_sysctl_set(SYSCTL_PPLL_DRV, tmp);
tmp &= ~(1<<18);
rt305x_sysctl_set(SYSCTL_PPLL_DRV, tmp);
tmp &= ~(1<<17);
rt305x_sysctl_set(SYSCTL_PPLL_DRV, tmp);
tmp|= (1<<31);
rt305x_sysctl_set(SYSCTL_PPLL_DRV, tmp);
RT_WRITE32(sc, RT305X_PCI_MEMBASE, sc->sc_mem_base);
RT_WRITE32(sc, RT305X_PCI_IOBASE, sc->sc_io_base);
RT_WRITE32(sc, RT305X_PCI_PCICFG, RT_READ32(sc, 0) & ~(1<<1));
DELAY(500000);
if ((RT_READ32(sc, RT305X_PCI_PCIE0_STATUS) & 0x1) == 1)
sc->pcie_link_status = 1;
else
sc->pcie_link_status = 0;
RT_WRITE32(sc, RT305X_PCI_PCIE0_BAR0SETUP, 0x7FFF0001);
RT_WRITE32(sc, RT305X_PCI_PCIE0_BAR1SETUP, 0x00000000);
RT_WRITE32(sc, RT305X_PCI_PCIE0_IMBASEBAR0, 0x00000000);
RT_WRITE32(sc, RT305X_PCI_PCIE0_CLASS, 0x06040001);
tmp = rt305x_pci_read_config(dev, 0, 0, 0, 4, 4);
rt305x_pci_write_config(dev, 0, 0, 0, 4, tmp | 0x7, 4);
tmp = rt305x_pci_read_config(dev, 0, 0, 0, 0x70c, 4);
tmp &= ~(0xff)<<8;
tmp |= 0x50<<8;
rt305x_pci_write_config(dev, 0, 0, 0, 0x70c, tmp, 4);
tmp = rt305x_pci_read_config(dev, 0, 0, 0, 0x70c, 4);
rt305x_pci_write_config(dev, 0, 0, 0, PCIR_BAR(0), 0, 4);
}
static inline uint32_t
pcib_bit_get(uint32_t *map, uint32_t bit)
{
uint32_t n = bit / BITS_PER_UINT32;
bit = bit % BITS_PER_UINT32;
return (map[n] & (1 << bit));
}
static inline void
pcib_bit_set(uint32_t *map, uint32_t bit)
{
uint32_t n = bit / BITS_PER_UINT32;
bit = bit % BITS_PER_UINT32;
map[n] |= (1 << bit);
}
static inline uint32_t
pcib_map_check(uint32_t *map, uint32_t start, uint32_t bits)
{
uint32_t i;
for (i = start; i < start + bits; i++)
if (pcib_bit_get(map, i))
return (0);
return (1);
}
static inline void
pcib_map_set(uint32_t *map, uint32_t start, uint32_t bits)
{
uint32_t i;
for (i = start; i < start + bits; i++)
pcib_bit_set(map, i);
}
static bus_addr_t
pcib_alloc(device_t dev, uint32_t smask)
{
struct rt305x_pci_softc *sc = device_get_softc(dev);
uint32_t bits, bits_limit, i, *map, min_alloc, size;
bus_addr_t addr = 0;
bus_addr_t base;
if (smask & 1) {
base = sc->sc_io_base;
min_alloc = PCI_MIN_IO_ALLOC;
bits_limit = sc->sc_io_size / min_alloc;
map = sc->sc_io_map;
smask &= ~0x3;
} else {
base = sc->sc_mem_base;
min_alloc = PCI_MIN_MEM_ALLOC;
bits_limit = sc->sc_mem_size / min_alloc;
map = sc->sc_mem_map;
smask &= ~0xF;
}
size = ~smask + 1;
bits = size / min_alloc;
for (i = 0; i + bits <= bits_limit; i+= bits)
if (pcib_map_check(map, i, bits)) {
pcib_map_set(map, i, bits);
addr = base + (i * min_alloc);
return (addr);
}
return (addr);
}
static int
rt305x_pcib_init_bar(device_t dev, int bus, int slot, int func, int barno)
{
uint32_t addr, bar;
int reg, width;
reg = PCIR_BAR(barno);
rt305x_pci_write_config(dev, bus, slot, func, reg, ~0, 4);
bar = rt305x_pci_read_config(dev, bus, slot, func, reg, 4);
if (bar == 0)
return (1);
/* Calculate BAR size: 64 or 32 bit (in 32-bit units) */
width = ((bar & 7) == 4) ? 2 : 1;
addr = pcib_alloc(dev, bar);
if (!addr)
return (-1);
if (bootverbose)
printf("PCI %u:%u:%u: reg %x: smask=%08x: addr=%08x\n",
bus, slot, func, reg, bar, addr);
rt305x_pci_write_config(dev, bus, slot, func, reg, addr, 4);
if (width == 2)
rt305x_pci_write_config(dev, bus, slot, func, reg + 4, 0, 4);
return (width);
}
static int
rt305x_pcib_init_all_bars(device_t dev, int bus, int slot, int func,
int hdrtype)
{
int maxbar, bar, i;
maxbar = (hdrtype & PCIM_HDRTYPE) ? 0 : 6;
bar = 0;
while (bar < maxbar) {
i = rt305x_pcib_init_bar(dev, bus, slot, func, bar);
bar += i;
if (i < 0) {
device_printf(dev, "PCI IO/Memory space exhausted\n");
return (ENOMEM);
}
}
return (0);
}
static inline int
rt305x_pci_slot_has_link(device_t dev, int slot)
{
struct rt305x_pci_softc *sc = device_get_softc(dev);
return !!(sc->pcie_link_status & (1<<slot));
}
static int cur_secbus = 0;
static void
rt305x_pcib_init_bridge(device_t dev, int bus, int slot, int func)
{
struct rt305x_pci_softc *sc = device_get_softc(dev);
bus_addr_t io_base, mem_base;
uint32_t io_limit, mem_limit;
int secbus;
if (bus == 0 && !rt305x_pci_slot_has_link(dev, slot)) {
device_printf(dev, "Skip bus %d due to no link\n",++cur_secbus);
return;
}
io_base = sc->sc_io_base;
io_limit = io_base + sc->sc_io_size - 1;
mem_base = sc->sc_mem_base;
mem_limit = mem_base + sc->sc_mem_size - 1;
rt305x_pci_write_config(dev, bus, slot, func, PCIR_IOBASEL_1,
io_base >> 8, 1);
rt305x_pci_write_config(dev, bus, slot, func, PCIR_IOBASEH_1,
io_base >> 16, 2);
rt305x_pci_write_config(dev, bus, slot, func, PCIR_IOLIMITL_1,
io_limit >> 8, 1);
rt305x_pci_write_config(dev, bus, slot, func, PCIR_IOLIMITH_1,
io_limit >> 16, 2);
rt305x_pci_write_config(dev, bus, slot, func, PCIR_MEMBASE_1,
mem_base >> 16, 2);
rt305x_pci_write_config(dev, bus, slot, func, PCIR_MEMLIMIT_1,
mem_limit >> 16, 2);
rt305x_pci_write_config(dev, bus, slot, func, PCIR_PMBASEL_1,
0x10, 2);
rt305x_pci_write_config(dev, bus, slot, func, PCIR_PMBASEH_1,
0x0, 4);
rt305x_pci_write_config(dev, bus, slot, func, PCIR_PMLIMITL_1,
0xF, 2);
rt305x_pci_write_config(dev, bus, slot, func, PCIR_PMLIMITH_1,
0x0, 4);
secbus = rt305x_pci_read_config(dev, bus, slot, func, PCIR_SECBUS_1, 1);
if (secbus == 0) {
rt305x_pci_write_config(dev, bus, slot, func, PCIR_SECBUS_1,
++cur_secbus, 1);
rt305x_pci_write_config(dev, bus, slot, func, PCIR_SUBBUS_1,
cur_secbus, 1);
secbus = cur_secbus;
}
rt305x_pcib_init(dev, secbus, PCI_SLOTMAX);
}
static int
rt305x_pcib_init(device_t dev, int bus, int maxslot)
{
int slot, func, maxfunc, error;
uint8_t hdrtype, command, class, subclass;
for (slot = 0; slot <= maxslot; slot++) {
maxfunc = 0;
for (func = 0; func <= maxfunc; func++) {
hdrtype = rt305x_pci_read_config(dev, bus, slot, func,
PCIR_HDRTYPE, 1);
if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE)
continue;
if (func == 0 && (hdrtype & PCIM_MFDEV))
maxfunc = PCI_FUNCMAX;
command = rt305x_pci_read_config(dev, bus, slot, func,
PCIR_COMMAND, 1);
command &= ~(PCIM_CMD_MEMEN | PCIM_CMD_PORTEN);
rt305x_pci_write_config(dev, bus, slot, func,
PCIR_COMMAND, command, 1);
error = rt305x_pcib_init_all_bars(dev, bus, slot, func,
hdrtype);
if (error)
return (error);
command |= PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN |
PCIM_CMD_PORTEN;
rt305x_pci_write_config(dev, bus, slot, func,
PCIR_COMMAND, command, 1);
rt305x_pci_write_config(dev, bus, slot, func,
PCIR_CACHELNSZ, 16, 1);
class = rt305x_pci_read_config(dev, bus, slot, func,
PCIR_CLASS, 1);
subclass = rt305x_pci_read_config(dev, bus, slot, func,
PCIR_SUBCLASS, 1);
if (class != PCIC_BRIDGE || subclass != PCIS_BRIDGE_PCI)
continue;
rt305x_pcib_init_bridge(dev, bus, slot, func);
}
}
return (0);
}
#define BUSY 0x80000000
#define WAITRETRY_MAX 10
#define WRITE_MODE (1<<23)
#define DATA_SHIFT 0
#define ADDR_SHIFT 8
static int
rt305x_wait_pci_phy_busy(struct rt305x_pci_softc *sc)
{
uint32_t reg_value = 0x0, retry = 0;
while (1) {
reg_value = RT_READ32(sc, RT305X_PCI_PHY0_CFG);
if (reg_value & BUSY)
DELAY(100000);
else
break;
if (retry++ > WAITRETRY_MAX) {
printf("PHY retry failed\n");
return (-1);
}
}
return (0);
}
static uint32_t
rt305x_pci_phy(struct rt305x_pci_softc *sc, char rwmode, uint32_t addr,
uint32_t val)
{
uint32_t reg_value = 0x0;
rt305x_wait_pci_phy_busy(sc);
if (rwmode == 'w') {
reg_value |= WRITE_MODE;
reg_value |= (val) << DATA_SHIFT;
}
reg_value |= (addr) << ADDR_SHIFT;
RT_WRITE32(sc, RT305X_PCI_PHY0_CFG, reg_value);
DELAY(1000);
rt305x_wait_pci_phy_busy(sc);
if (rwmode == 'r') {
reg_value = RT_READ32(sc, RT305X_PCI_PHY0_CFG);
return (reg_value);
}
return (0);
}
static void
rt305x_pci_phy_init(device_t dev)
{
struct rt305x_pci_softc *sc = device_get_softc(dev);
uint32_t tmp;
rt305x_pci_phy(sc, 'w', 0x00, 0x80);
rt305x_pci_phy(sc, 'w', 0x01, 0x04);
rt305x_pci_phy(sc, 'w', 0x68, 0x84);
rt305x_sysctl_set(SYSCTL_RSTCTRL,
rt305x_sysctl_get(SYSCTL_RSTCTRL) | (1<<26));
rt305x_sysctl_set(SYSCTL_CLKCFG1,
rt305x_sysctl_get(SYSCTL_CLKCFG1) & ~(1<<26));
tmp = rt305x_sysctl_get(SYSCTL_PPLL_CFG1);
tmp &= ~(1<<19);
rt305x_sysctl_set(SYSCTL_PPLL_CFG1, tmp);
tmp |= (1<<31);
rt305x_sysctl_set(SYSCTL_PPLL_CFG1, tmp);
}
static int
rt305x_pci_intr(void *arg)
{
struct rt305x_pci_softc *sc = arg;
struct intr_event *event;
uint32_t reg, irq, irqidx;
reg = RT_READ32(sc, RT305X_PCI_PCIINT);
for (irqidx = 0; irqidx < RT305X_PCI_NIRQS; irqidx++) {
irq = rt305x_idx_to_irq(irqidx);
if (reg & (1<<irq)) {
event = sc->sc_eventstab[irqidx];
if (!event || TAILQ_EMPTY(&event->ie_handlers)) {
if (irq != 0)
printf("Stray PCI IRQ %d\n", irq);
continue;
}
intr_event_handle(event, NULL);
mips_intrcnt_inc(sc->sc_intr_counter[irqidx]);
}
}
return (FILTER_HANDLED);
}

View File

@ -1,76 +0,0 @@
/*-
* Copyright (c) 2015 Stanislav Galabov.
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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_PCIREG_H__
#define __RT305X_PCIREG_H__
#define RT305X_PCI_NIRQS 1
#define RT305X_PCI_BASESLOT 0
#define RT305X_PCI_PCICFG 0x0000
#define RT305X_PCI_PCIINT 0x0008
#define RT305X_PCI_PCIENA 0x000C
#define RT305X_PCI_CFGADDR 0x0020
#define RT305X_PCI_CFGDATA 0x0024
#define RT305X_PCI_MEMBASE 0x0028
#define RT305X_PCI_IOBASE 0x002C
#define RT305X_PCI_PHY0_CFG 0x0090
#define RT305X_PCI_PCIE0_BAR0SETUP 0x2010
#define RT305X_PCI_PCIE0_BAR1SETUP 0x2014
#define RT305X_PCI_PCIE0_IMBASEBAR0 0x2018
#define RT305X_PCI_PCIE0_ID 0x2030
#define RT305X_PCI_PCIE0_CLASS 0x2034
#define RT305X_PCI_PCIE0_SUBID 0x2038
#define RT305X_PCI_PCIE0_STATUS 0x2050
#define RT305X_PCI_PCIE0_DLECR 0x2060
#define RT305X_PCI_PCIE0_ECRC 0x2064
#define RT305X_PCIE0_IRQ 20
#define RT305X_PCIE1_IRQ 21
#define RT305X_PCIE2_IRQ 22
#define RT305X_PCI_INTR_PIN 2
#define PCI_MIN_IO_ALLOC 4
#define PCI_MIN_MEM_ALLOC 16
#define BITS_PER_UINT32 (NBBY * sizeof(uint32_t))
#define RT_WRITE32(sc, off, val) \
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (off), (val))
#define RT_WRITE16(sc, off, val) \
bus_space_write_2((sc)->sc_bst, (sc)->sc_bsh, (off), (val))
#define RT_WRITE8(sc, off, val) \
bus_space_write_1((sc)->sc_bst, (sc)->sc_bsh, (off), (val))
#define RT_READ32(sc, off) \
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (off))
#define RT_READ16(sc, off) \
bus_space_read_2((sc)->sc_bst, (sc)->sc_bsh, (off))
#define RT_READ8(sc, off) \
bus_space_read_1((sc)->sc_bst, (sc)->sc_bsh, (off))
#endif /* __RT305X_PCIREG_H__ */

View File

@ -1,354 +0,0 @@
/*-
* Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org>
* Copyright (c) 2011, Aleksandr Rybalko <ray@FreeBSD.org>
* Copyright (c) 2013, Alexander A. Mityaev <sansan@adm.ua>
* 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 unmodified, 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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/kernel.h>
#include <sys/module.h>
#include <sys/rman.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <machine/bus.h>
#include <machine/cpu.h>
//#include <machine/pmap.h>
#include <dev/spibus/spi.h>
#include <dev/spibus/spibusvar.h>
#include "spibus_if.h"
#include "opt_platform.h"
#ifdef FDT
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#endif
#include <mips/rt305x/rt305xreg.h>
#include <dev/flash/mx25lreg.h>
#undef RT305X_SPI_DEBUG
#ifdef RT305X_SPI_DEBUG
#define dprintf printf
#else
#define dprintf(x, arg...)
#endif
/*
* register space access macros
*/
#define SPI_WRITE(sc, reg, val) do { \
bus_write_4(sc->sc_mem_res, (reg), (val)); \
} while (0)
#define SPI_READ(sc, reg) bus_read_4(sc->sc_mem_res, (reg))
#define SPI_SET_BITS(sc, reg, bits) \
SPI_WRITE(sc, reg, SPI_READ(sc, (reg)) | (bits))
#define SPI_CLEAR_BITS(sc, reg, bits) \
SPI_WRITE(sc, reg, SPI_READ(sc, (reg)) & ~(bits))
struct rt305x_spi_softc {
device_t sc_dev;
struct resource *sc_mem_res;
};
static int rt305x_spi_probe(device_t);
static int rt305x_spi_attach(device_t);
static int rt305x_spi_detach(device_t);
static int rt305x_spi_wait(struct rt305x_spi_softc *);
static void rt305x_spi_chip_activate(struct rt305x_spi_softc *);
static void rt305x_spi_chip_deactivate(struct rt305x_spi_softc *);
static uint8_t rt305x_spi_txrx(struct rt305x_spi_softc *, uint8_t *, int);
static int rt305x_spi_transfer(device_t, device_t, struct spi_command *);
#ifdef FDT
static phandle_t rt305x_spi_get_node(device_t, device_t);
#endif
static int
rt305x_spi_probe(device_t dev)
{
#ifdef FDT
if (!ofw_bus_is_compatible(dev, "ralink,rt305x-spi"))
return(ENXIO);
#endif
device_set_desc(dev, "RT305X SPI");
return (0);
}
static int
rt305x_spi_attach(device_t dev)
{
struct rt305x_spi_softc *sc = device_get_softc(dev);
int rid;
sc->sc_dev = dev;
rid = 0;
sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (!sc->sc_mem_res) {
device_printf(dev, "Could not map memory\n");
return (ENXIO);
}
if (rt305x_spi_wait(sc)) {
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
return (EBUSY);
}
SPI_WRITE(sc, RT305X_SPICFG, MSBFIRST | SPICLKPOL | TX_ON_CLK_FALL |
SPI_CLK_DIV8); /* XXX: make it configurable */
/*
* W25Q64CV max 104MHz, bus 120-192 MHz, so divide by 2.
* Update: divide by 4, DEV2 to fast for flash.
*/
device_add_child(dev, "spibus", 0);
return (bus_generic_attach(dev));
}
static int
rt305x_spi_detach(device_t dev)
{
struct rt305x_spi_softc *sc = device_get_softc(dev);
SPI_SET_BITS(sc, RT305X_SPICTL, HIZSMOSI | CS_HIGH);
if (sc->sc_mem_res)
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
return (0);
}
static void
rt305x_spi_chip_activate(struct rt305x_spi_softc *sc)
{
// printf("%s\n", __func__);
rt305x_spi_wait(sc);
/*
* Put all CSx to low
*/
SPI_CLEAR_BITS(sc, RT305X_SPICTL, CS_HIGH | HIZSMOSI);
}
static void
rt305x_spi_chip_deactivate(struct rt305x_spi_softc *sc)
{
// printf("%s\n", __func__);
rt305x_spi_wait(sc);
/*
* Put all CSx to high
*/
SPI_SET_BITS(sc, RT305X_SPICTL, CS_HIGH | HIZSMOSI);
}
static int
rt305x_spi_wait(struct rt305x_spi_softc *sc)
{
int i = 1000;
while (i--) {
if (!SPI_READ(sc, RT305X_SPIBUSY))
break;
}
if (i == 0) {
printf("busy\n");
return (1);
}
return (0);
}
static uint8_t
rt305x_spi_txrx(struct rt305x_spi_softc *sc, uint8_t *data, int write)
{
if (rt305x_spi_wait(sc))
return (EBUSY);
if (write == RT305X_SPI_WRITE) {
SPI_WRITE(sc, RT305X_SPIDATA, *data);
SPI_SET_BITS(sc, RT305X_SPICTL, START_WRITE);
//printf("%s(W:%d)\n", __func__, *data);
} else {/* RT305X_SPI_READ */
SPI_SET_BITS(sc, RT305X_SPICTL, START_READ);
if (rt305x_spi_wait(sc))
return (EBUSY);
*data = SPI_READ(sc, RT305X_SPIDATA) & 0xff;
//printf("%s(R:%d)\n", __func__, *data);
}
return (0);
}
static int
rt305x_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
{
struct rt305x_spi_softc *sc;
uint32_t cs;
uint8_t *buf, byte, *tx_buf;
int i, sz, error = 0, write = 0;
sc = device_get_softc(dev);
spibus_get_cs(child, &cs);
cs &= ~SPIBUS_CS_HIGH;
if (cs != 0)
/* Only 1 CS */
return (ENXIO);
/* There is always a command to transfer. */
tx_buf = (uint8_t *)(cmd->tx_cmd);
/* Perform some fixup because RT305X dont support duplex SPI */
switch(tx_buf[0]) {
case CMD_READ_IDENT:
cmd->tx_cmd_sz = 1;
cmd->rx_cmd_sz = 3;
break;
case CMD_WRITE_ENABLE:
case CMD_WRITE_DISABLE:
cmd->tx_cmd_sz = 1;
cmd->rx_cmd_sz = 0;
break;
case CMD_READ_STATUS:
cmd->tx_cmd_sz = 1;
cmd->rx_cmd_sz = 1;
break;
case CMD_READ:
cmd->tx_cmd_sz = 4;
case CMD_FAST_READ:
cmd->tx_cmd_sz = 5;
cmd->rx_cmd_sz = cmd->tx_data_sz = 0;
break;
case CMD_SECTOR_ERASE:
cmd->tx_cmd_sz = 4;
cmd->rx_cmd_sz = cmd->tx_data_sz = 0;
break;
case CMD_PAGE_PROGRAM:
cmd->tx_cmd_sz = 4;
cmd->rx_cmd_sz = cmd->rx_data_sz = 0;
break;
}
rt305x_spi_chip_activate(sc);
if (cmd->tx_cmd_sz + cmd->rx_cmd_sz) {
buf = (uint8_t *)(cmd->rx_cmd);
tx_buf = (uint8_t *)(cmd->tx_cmd);
sz = cmd->tx_cmd_sz + cmd->rx_cmd_sz;
for (i = 0; i < sz; i++) {
if(i < cmd->tx_cmd_sz) {
byte = tx_buf[i];
error = rt305x_spi_txrx(sc, &byte,
RT305X_SPI_WRITE);
if (error)
goto rt305x_spi_transfer_fail;
continue;
}
error = rt305x_spi_txrx(sc, &byte,
RT305X_SPI_READ);
if (error)
goto rt305x_spi_transfer_fail;
buf[i] = byte;
}
}
/*
* Transfer/Receive data
*/
if (cmd->tx_data_sz + cmd->rx_data_sz) {
write = (cmd->tx_data_sz > 0)?1:0;
buf = (uint8_t *)(write ? cmd->tx_data : cmd->rx_data);
sz = write ? cmd->tx_data_sz : cmd->rx_data_sz;
for (i = 0; i < sz; i++) {
byte = buf[i];
error = rt305x_spi_txrx(sc, &byte,
write?RT305X_SPI_WRITE:RT305X_SPI_READ);
if (error)
goto rt305x_spi_transfer_fail;
buf[i] = byte;
}
}
rt305x_spi_transfer_fail:
rt305x_spi_chip_deactivate(sc);
return (error);
}
#ifdef FDT
static phandle_t
rt305x_spi_get_node(device_t bus, device_t dev)
{
/* We only have one child, the SPI bus, which needs our own node. */
return (ofw_bus_get_node(bus));
}
#endif
static device_method_t rt305x_spi_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, rt305x_spi_probe),
DEVMETHOD(device_attach, rt305x_spi_attach),
DEVMETHOD(device_detach, rt305x_spi_detach),
DEVMETHOD(spibus_transfer, rt305x_spi_transfer),
#ifdef FDT
/* ofw_bus interface */
DEVMETHOD(ofw_bus_get_node, rt305x_spi_get_node),
#endif
DEVMETHOD_END
};
static driver_t rt305x_spi_driver = {
.name = "spi",
.methods = rt305x_spi_methods,
.size = sizeof(struct rt305x_spi_softc),
};
static devclass_t rt305x_spi_devclass;
DRIVER_MODULE(rt305x_spi, obio, rt305x_spi_driver, rt305x_spi_devclass, 0, 0);
#ifdef FDT
DRIVER_MODULE(rt305x_spi, simplebus, rt305x_spi_driver, rt305x_spi_devclass, 0, 0);
#endif

View File

@ -1,244 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2010 Aleksandr Rybalko.
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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/rt305x_sysctlvar.h>
static int rt305x_sysctl_probe(device_t);
static int rt305x_sysctl_attach(device_t);
static int rt305x_sysctl_detach(device_t);
static struct rt305x_sysctl_softc *rt305x_sysctl_softc = NULL;
static void
rt305x_sysctl_dump_config(device_t dev)
{
uint32_t val;
#define DUMPREG(r) \
val = rt305x_sysctl_get(r); printf(" " #r "=%#08x\n", val)
val = rt305x_sysctl_get(SYSCTL_CHIPID0_3);
printf("\tChip ID: \"%c%c%c%c",
(val >> 0 ) & 0xff,
(val >> 8 ) & 0xff,
(val >> 16) & 0xff,
(val >> 24) & 0xff);
val = rt305x_sysctl_get(SYSCTL_CHIPID4_7);
printf("%c%c%c%c\"\n",
(val >> 0 ) & 0xff,
(val >> 8 ) & 0xff,
(val >> 16) & 0xff,
(val >> 24) & 0xff);
DUMPREG(SYSCTL_SYSCFG);
#if !defined(RT5350) && !defined(MT7620)
if ( val & SYSCTL_SYSCFG_INIC_EE_SDRAM)
printf("\tGet SDRAM config from EEPROM\n");
if ( val & SYSCTL_SYSCFG_INIC_8MB_SDRAM)
printf("\tBootstrap flag is set\n");
printf("\tGE0 mode %u\n",
((val & SYSCTL_SYSCFG_GE0_MODE_MASK) >>
SYSCTL_SYSCFG_GE0_MODE_SHIFT));
if ( val & SYSCTL_SYSCFG_BOOT_ADDR_1F00)
printf("\tBoot from 0x1f000000\n");
if ( val & SYSCTL_SYSCFG_BYPASS_PLL)
printf("\tBypass PLL\n");
if ( val & SYSCTL_SYSCFG_BIG_ENDIAN)
printf("\tBig Endian\n");
if ( val & SYSCTL_SYSCFG_CPU_CLK_SEL_384MHZ)
printf("\tClock is 384MHz\n");
printf("\tBoot from %u\n",
((val & SYSCTL_SYSCFG_BOOT_FROM_MASK) >>
SYSCTL_SYSCFG_BOOT_FROM_SHIFT));
printf("\tBootstrap test code %u\n",
((val & SYSCTL_SYSCFG_TEST_CODE_MASK) >>
SYSCTL_SYSCFG_TEST_CODE_SHIFT));
printf("\tSRAM_CS mode %u\n",
((val & SYSCTL_SYSCFG_SRAM_CS_MODE_MASK) >>
SYSCTL_SYSCFG_SRAM_CS_MODE_SHIFT));
printf("\t%umA SDRAM_CLK driving\n",
(val & SYSCTL_SYSCFG_SDRAM_CLK_DRV)?12:8);
DUMPREG(SYSCTL_CLKCFG0);
printf("\tSDRAM_CLK_SKEW %uns\n", (val >> 30) & 0x03);
DUMPREG(SYSCTL_CLKCFG1);
if ( val & SYSCTL_CLKCFG1_PBUS_DIV_CLK_BY2)
printf("\tPbus clock is 1/2 of System clock\n");
if ( val & SYSCTL_CLKCFG1_OTG_CLK_EN)
printf("\tUSB OTG clock is enabled\n");
if ( val & SYSCTL_CLKCFG1_I2S_CLK_EN)
printf("\tI2S clock is enabled\n");
printf("\tI2S clock is %s\n",
(val & SYSCTL_CLKCFG1_I2S_CLK_SEL_EXT)?
"external":"internal 15.625MHz");
printf("\tI2S clock divider %u\n",
((val & SYSCTL_CLKCFG1_I2S_CLK_DIV_MASK) >>
SYSCTL_CLKCFG1_I2S_CLK_DIV_SHIFT));
if ( val & SYSCTL_CLKCFG1_PCM_CLK_EN)
printf("\tPCM clock is enabled\n");
printf("\tPCM clock is %s\n",
(val & SYSCTL_CLKCFG1_PCM_CLK_SEL_EXT)?
"external":"internal 15.625MHz");
printf("\tPCM clock divider %u\n",
((val & SYSCTL_CLKCFG1_PCM_CLK_DIV_MASK) >>
SYSCTL_CLKCFG1_PCM_CLK_DIV_SHIFT));
DUMPREG(SYSCTL_GPIOMODE);
#endif
#undef DUMPREG
return;
}
static int
rt305x_sysctl_probe(device_t dev)
{
device_set_desc(dev, "RT305X System Control driver");
return (0);
}
static int
rt305x_sysctl_attach(device_t dev)
{
struct rt305x_sysctl_softc *sc = device_get_softc(dev);
int error = 0;
KASSERT((device_get_unit(dev) == 0),
("rt305x_sysctl: Only one sysctl module supported"));
if (rt305x_sysctl_softc != NULL)
return (ENXIO);
rt305x_sysctl_softc = sc;
/* Map control/status registers. */
sc->mem_rid = 0;
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&sc->mem_rid, RF_ACTIVE);
if (sc->mem_res == NULL) {
device_printf(dev, "couldn't map memory\n");
error = ENXIO;
rt305x_sysctl_detach(dev);
return(error);
}
#ifdef notyet
sc->irq_rid = 0;
if ((sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
&sc->irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
device_printf(dev, "unable to allocate IRQ resource\n");
return (ENXIO);
}
if ((bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC,
rt305x_sysctl_intr, NULL, sc, &sc->sysctl_ih))) {
device_printf(dev,
"WARNING: unable to register interrupt handler\n");
return (ENXIO);
}
#endif
rt305x_sysctl_dump_config(dev);
return (bus_generic_attach(dev));
}
static int
rt305x_sysctl_detach(device_t dev)
{
struct rt305x_sysctl_softc *sc = device_get_softc(dev);
bus_generic_detach(dev);
if (sc->mem_res)
bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid,
sc->mem_res);
#ifdef notyet
if (sc->irq_res)
bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid,
sc->irq_res);
#endif
return(0);
}
#ifdef notyet
static int
rt305x_sysctl_intr(void *arg)
{
return (FILTER_HANDLED);
}
#endif
uint32_t
rt305x_sysctl_get(uint32_t reg)
{
struct rt305x_sysctl_softc *sc = rt305x_sysctl_softc;
return (bus_read_4(sc->mem_res, reg));
}
void
rt305x_sysctl_set(uint32_t reg, uint32_t val)
{
struct rt305x_sysctl_softc *sc = rt305x_sysctl_softc;
bus_write_4(sc->mem_res, reg, val);
return;
}
static device_method_t rt305x_sysctl_methods[] = {
DEVMETHOD(device_probe, rt305x_sysctl_probe),
DEVMETHOD(device_attach, rt305x_sysctl_attach),
DEVMETHOD(device_detach, rt305x_sysctl_detach),
{0, 0},
};
static driver_t rt305x_sysctl_driver = {
"rt305x_sysctl",
rt305x_sysctl_methods,
sizeof(struct rt305x_sysctl_softc),
};
static devclass_t rt305x_sysctl_devclass;
DRIVER_MODULE(rt305x_sysctl, obio, rt305x_sysctl_driver, rt305x_sysctl_devclass, 0, 0);

View File

@ -1,47 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2010 Aleksandr Rybalko.
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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_SYSCTLVAR_H_
#define _RT305X_SYSCTLVAR_H_
struct rt305x_sysctl_softc {
device_t dev;
struct resource *mem_res;
int mem_rid;
struct resource *irq_res;
int irq_rid;
int sysctl_ih;
};
uint32_t rt305x_sysctl_get(uint32_t);
void rt305x_sysctl_set(uint32_t, uint32_t);
#endif /* _RT305X_SYSCTLVAR_H_ */

View File

@ -1,534 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2015 Stanislav Galabov.
* Copyright (c) 2010 Aleksandr Rybalko.
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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 _RT305XREG_H_
#define _RT305XREG_H_
#include "opt_rt305x.h"
#ifdef RT3052F
#define PLATFORM_COUNTER_FREQ (384 * 1000 * 1000)
#endif
#ifdef RT3050F
#define PLATFORM_COUNTER_FREQ (320 * 1000 * 1000)
#endif
#ifdef MT7620
#define PLATFORM_COUNTER_FREQ (580 * 1000 * 1000)
#endif
#ifdef RT5350
#define PLATFORM_COUNTER_FREQ (360 * 1000 * 1000)
#endif
#ifndef PLATFORM_COUNTER_FREQ
#error "No platform selected"
#endif
#ifndef MT7620
#define SYSTEM_CLOCK (PLATFORM_COUNTER_FREQ/3)
#define SDRAM_BASE 0x00000000
#define SDRAM_END 0x03FFFFFF
#define SYSCTL_BASE 0x10000000
#define SYSCTL_END 0x100000FF
#define TIMER_BASE 0x10000100
#define TIMER_END 0x100001FF
#define INTCTL_BASE 0x10000200
#define INTCTL_END 0x100002FF
#define MEMCTRL_BASE 0x10000300
#define MEMCTRL_END 0x100003FF /* SDRAM & Flash/SRAM */
#ifndef RT5350
#define PCM_BASE 0x10000400
#define PCM_END 0x100004FF
#else
#define PCM_BASE 0x10002000
#define PCM_END 0x100027FF
#endif
#define UART_BASE 0x10000500
#define UART_END 0x100005FF
#define PIO_BASE 0x10000600
#define PIO_END 0x100006FF
#ifndef RT5350
#define GDMA_BASE 0x10000700
#define GDMA_END 0x100007FF /* Generic DMA */
#define NANDFC_BASE 0x10000800
#define NANDFC_END 0x100008FF /* NAND Flash Controller */
#else
#define GDMA_BASE 0x10002800
#define GDMA_END 0x10002FFF
#endif
#define I2C_BASE 0x10000900
#define I2C_END 0x100009FF
#define I2S_BASE 0x10000A00
#define I2S_END 0x10000AFF
#define SPI_BASE 0x10000B00
#define SPI_END 0x10000BFF
#define UARTLITE_BASE 0x10000C00
#define UARTLITE_END 0x10000CFF
#define FRENG_BASE 0x10100000
#define FRENG_END 0x1010FFFF /* Frame Engine */
#define ETHSW_BASE 0x10110000
#define ETHSW_END 0x10117FFF /* Ethernet Switch */
#define ROM_BASE 0x10118000
#define ROM_END 0x10119FFF
#define WLAN_BASE 0x10180000
#define WLAN_END 0x101BFFFF /* 802.11n MAC/BBP */
#ifndef RT5350
#define USB_OTG_BASE 0x101C0000
#define USB_OTG_END 0x101FFFFF
#else
#define USB_OTG_BASE 0x101C0000
#define USB_OTG_END 0x101C0FFF
#define USB_OHCI_BASE 0x101C1000
#define USB_OHCI_END 0x101C1FFF
#endif
#define EMEM_BASE 0x1B000000
#define EMEM_END 0x1BFFFFFF /* External SRAM/Flash */
#ifdef RT5350
#define BOOT_ROM_BASE 0x1C000000
#define BOOT_ROM_END 0x1C003FFF
#endif
#ifndef RT5350
#define FLASH_BASE 0x1F000000
#define FLASH_END 0x1FFFFFFF /* Flash window */
#endif
#define OBIO_MEM_BASE SYSCTL_BASE
#define OBIO_MEM_START OBIO_MEM_BASE
#ifndef RT5350
#define OBIO_MEM_END FLASH_END
#else
#define OBIO_MEM_END BOOT_ROM_END
#endif
#else /* MT7620 */
#define SYSTEM_CLOCK (40 * 1000 * 1000)
#define SDRAM_BASE 0x00000000
#define SDRAM_END 0x0FFFFFFF
#define SYSCTL_BASE 0x10000000
#define SYSCTL_END 0x100000FF
#define TIMER_BASE 0x10000100
#define TIMER_END 0x100001FF
#define INTCTL_BASE 0x10000200
#define INTCTL_END 0x100002FF
#define MEMCTRL_BASE 0x10000300
#define MEMCTRL_END 0x100003FF /* SDRAM & Flash/SRAM */
#define PCM_BASE 0x10002000
#define PCM_END 0x100027FF
#define UART_BASE 0x10000500
#define UART_END 0x100005FF
#define PIO_BASE 0x10000600
#define PIO_END 0x100006FF
#define GDMA_BASE 0x10002800
#define GDMA_END 0x10002FFF /* Generic DMA */
#define NANDFC_BASE 0x10000800
#define NANDFC_END 0x100008FF /* NAND Flash Controller */
#define I2C_BASE 0x10000900
#define I2C_END 0x100009FF
#define I2S_BASE 0x10000A00
#define I2S_END 0x10000AFF
#define SPI_BASE 0x10000B00
#define SPI_END 0x10000BFF
#define UARTLITE_BASE 0x10000C00
#define UARTLITE_END 0x10000CFF
#define FRENG_BASE 0x10100000
#define FRENG_END 0x1010FFFF /* Frame Engine */
#define ETHSW_BASE 0x10110000
#define ETHSW_END 0x10117FFF /* Ethernet Switch */
#define ROM_BASE 0x10118000
#define ROM_END 0x1011FFFF
#define WLAN_BASE 0x10180000
#define WLAN_END 0x101BFFFF /* 802.11n MAC/BBP */
#define USB_OTG_BASE 0x101C0000
#define USB_OTG_END 0x101C0FFF
#define USB_OHCI_BASE 0x101C1000
#define USB_OHCI_END 0x101C1FFF
#define PCIE_BASE 0x10140000
#define PCIE_END 0x1017FFFF
#define SDHC_BASE 0x10130000
#define SDHC_END 0x10133FFF
#define PCIE_IO_BASE 0x10160000
#define PCIE_IO_END 0x1016FFFF
#define PCIE_MEM_BASE 0x20000000
#define PCIE_MEM_END 0x2FFFFFFF
// TODO: fix below mappings?
#define EMEM_BASE 0x1B000000
#define EMEM_END 0x1BFFFFFF /* External SRAM/Flash */
#define FLASH_BASE 0x1F000000
#define FLASH_END 0x1FFFFFFF /* Flash window */
#define OBIO_MEM_BASE SYSCTL_BASE
#define OBIO_MEM_START OBIO_MEM_BASE
#define OBIO_MEM_END FLASH_END
#endif
/* System Control */
#define SYSCTL_CHIPID0_3 0x00
#define SYSCTL_CHIPID4_7 0x04
#ifdef RT5350
#define SYSCTL_REVID 0x0C
#endif
#define SYSCTL_SYSCFG 0x10
#if !defined(RT5350) && !defined(MT7620)
#define SYSCTL_SYSCFG_INIC_EE_SDRAM (1<<29)
#define SYSCTL_SYSCFG_INIC_8MB_SDRAM (1<<28)
#define SYSCTL_SYSCFG_GE0_MODE_MASK 0x03000000
#define SYSCTL_SYSCFG_GE0_MODE_SHIFT 24
#define SYSCTL_SYSCFG_GE0_MODE_RGMII 0 /* RGMII Mode */
#define SYSCTL_SYSCFG_GE0_MODE_MII 1 /* MII Mode */
#define SYSCTL_SYSCFG_GE0_MODE_REV_MII 2 /*Reversed MII Mode*/
#define SYSCTL_SYSCFG_BOOT_ADDR_1F00 (1<<22)
#define SYSCTL_SYSCFG_BYPASS_PLL (1<<21)
#define SYSCTL_SYSCFG_BIG_ENDIAN (1<<20)
#define SYSCTL_SYSCFG_CPU_CLK_SEL_384MHZ (1<<18)
#define SYSCTL_SYSCFG_BOOT_FROM_MASK 0x00030000
#define SYSCTL_SYSCFG_BOOT_FROM_SHIFT 16
#define SYSCTL_SYSCFG_BOOT_FROM_FLASH16 0
#define SYSCTL_SYSCFG_BOOT_FROM_FLASH8 1
#define SYSCTL_SYSCFG_BOOT_FROM_NANDFLASH 2
#define SYSCTL_SYSCFG_BOOT_FROM_ROM 3
#define SYSCTL_SYSCFG_TEST_CODE_MASK 0x0000ff00
#define SYSCTL_SYSCFG_TEST_CODE_SHIFT 8
#define SYSCTL_SYSCFG_SRAM_CS_MODE_MASK 0x0000000c
#define SYSCTL_SYSCFG_SRAM_CS_MODE_SHIFT 2
#define SYSCTL_SYSCFG_SRAM_CS_MODE_SRAM 0
#define SYSCTL_SYSCFG_SRAM_CS_MODE_WDOG_RST 1
#define SYSCTL_SYSCFG_SRAM_CS_MODE_BT_COEX 2
#define SYSCTL_SYSCFG_SDRAM_CLK_DRV (1<<0) /* 8mA/12mA */
#endif
#ifdef RT5350
#define SYSCTL1_SYSCFG_PULL_EN (1<<26)
#define SYSCTL1_SYSCFG_SDR_PAD_DRV_MASK 0x0700000
#define SYSCTL1_SYSCFG_SDR_PAD_DRV_SHIFT 20
#define SYSCTL1_SYSCFG_SDR_PAD_DRV_0 0
#define SYSCTL1_SYSCFG_SDR_PAD_DRV_1 1
#define SYSCTL1_SYSCFG_SDR_PAD_DRV_2 2
#endif
#define SYSCTL_SYSCFG1 0x14
#define SYSCTL_SYSCFG1_USB0_HOST_MODE (1 << 10)
#define SYSCTL_TESTSTAT 0x18
#define SYSCTL_TESTSTAT2 0x1C
#define SYSCTL_CLKCFG0 0x2C
#define SYSCTL_CLKCFG0_SDRAM_CLK_SKEW_MASK 0xc0000000
#define SYSCTL_CLKCFG0_SDRAM_CLK_SKEW_SHIFT 30
#define SYSCTL_CLKCFG0_SDRAM_CLK_SKEW_ZERO_DELAY 0
#define SYSCTL_CLKCFG0_SDRAM_CLK_SKEW_1NS_DELAY 1
#define SYSCTL_CLKCFG0_SDRAM_CLK_SKEW_2NS_DELAY 2
#define SYSCTL_CLKCFG0_SDRAM_CLK_SKEW_3NS_DELAY 3
#define SYSCTL_CLKCFG1 0x30
#if !defined(RT5350)
#define SYSCTL_CLKCFG1_PBUS_DIV_CLK_BY2 (1<<30)
#define SYSCTL_CLKCFG1_UPHY0_CLK_EN (1<<25)
#define SYSCTL_CLKCFG1_UPHY1_CLK_EN (1<<22)
#define SYSCTL_CLKCFG1_OTG_CLK_EN (1<<18)
#define SYSCTL_CLKCFG1_I2S_CLK_EN (1<<15)
#define SYSCTL_CLKCFG1_I2S_CLK_SEL_EXT (1<<14)
#define SYSCTL_CLKCFG1_I2S_CLK_DIV_MASK 0x00003f00
#define SYSCTL_CLKCFG1_I2S_CLK_DIV_SHIFT 8
#define SYSCTL_CLKCFG1_PCM_CLK_EN (1<<7)
#define SYSCTL_CLKCFG1_PCM_CLK_SEL_EXT (1<<6)
#define SYSCTL_CLKCFG1_PCM_CLK_DIV_MASK 0x0000003f
#define SYSCTL_CLKCFG1_PCM_CLK_DIV_SHIFT 0
#endif
#ifdef RT5350
#define SYSCTL_CLKCFG1_SYSTICK_EN (1<<29)
#define SYSCTL_CLKCFG1_PDMA_CSR_CLK_GATE_BYP (1<<23)
#define SYSCTL_CLKCFG1_UPHY0_CLK_EN (1<<18)
#endif
#define SYSCTL_RSTCTRL 0x34
#define SYSCTL_RSTCTRL_ETHSW (1<<23)
#if !defined(MT7620) && !defined(RT5350)
#define SYSCTL_RSTCTRL_OTG (1<<22)
#else
#define SYSCTL_RSTCTRL_UPHY0 (1<<25)
#define SYSCTL_RSTCTRL_UPHY1 (1<<22)
#endif
#define SYSCTL_RSTCTRL_FRENG (1<<21)
#define SYSCTL_RSTCTRL_WLAN (1<<20)
#define SYSCTL_RSTCTRL_UARTL (1<<19)
#define SYSCTL_RSTCTRL_SPI (1<<18)
#define SYSCTL_RSTCTRL_I2S (1<<17)
#define SYSCTL_RSTCTRL_I2C (1<<16)
#define SYSCTL_RSTCTRL_DMA (1<<14)
#define SYSCTL_RSTCTRL_PIO (1<<13)
#define SYSCTL_RSTCTRL_UART (1<<12)
#define SYSCTL_RSTCTRL_PCM (1<<11)
#define SYSCTL_RSTCTRL_MC (1<<10)
#define SYSCTL_RSTCTRL_INTC (1<<9)
#define SYSCTL_RSTCTRL_TIMER (1<<8)
#define SYSCTL_RSTCTRL_SYS (1<<0)
#define SYSCTL_RSTSTAT 0x38
#define SYSCTL_RSTSTAT_SWCPURST (1<<3)
#define SYSCTL_RSTSTAT_SWSYSRST (1<<2)
#define SYSCTL_RSTSTAT_WDRST (1<<1)
#define SYSCTL_GPIOMODE 0x60
#define SYSCTL_GPIOMODE_RGMII_GPIO_MODE (1<<9)
#define SYSCTL_GPIOMODE_SDRAM_GPIO_MODE (1<<8)
#define SYSCTL_GPIOMODE_MDIO_GPIO_MODE (1<<7)
#define SYSCTL_GPIOMODE_JTAG_GPIO_MODE (1<<6)
#define SYSCTL_GPIOMODE_UARTL_GPIO_MODE (1<<5)
#define SYSCTL_GPIOMODE_UARTF_SHARE_MODE_UARTF (0<<2)
#define SYSCTL_GPIOMODE_UARTF_SHARE_MODE_PCM_UARTF (1<<2)
#define SYSCTL_GPIOMODE_UARTF_SHARE_MODE_PCM_I2S (2<<2)
#define SYSCTL_GPIOMODE_UARTF_SHARE_MODE_I2S_UARTF (3<<2)
#define SYSCTL_GPIOMODE_UARTF_SHARE_MODE_PCM_GPIO (4<<2)
#define SYSCTL_GPIOMODE_UARTF_SHARE_MODE_GPIO_UARTF (5<<2)
#define SYSCTL_GPIOMODE_UARTF_SHARE_MODE_GPIO_I2S (6<<2)
#define SYSCTL_GPIOMODE_UARTF_SHARE_MODE_GPIO (7<<2)
#define SYSCTL_GPIOMODE_SPI_GPIO_MODE (1<<1)
#define SYSCTL_GPIOMODE_I2C_GPIO_MODE (1<<0)
#define SYSCTL_MEMO0 0x68
#define SYSCTL_MEMO1 0x6C
#define SYSCTL_PPLL_CFG1 0x9C
#define SYSCTL_PPLL_DRV 0xA0
/* Timer */
#define TIMER_TMRSTAT 0x00
#define TIMER_TMRSTAT_TMR1RST (1<<5)
#define TIMER_TMRSTAT_TMR0RST (1<<4)
#define TIMER_TMRSTAT_TMR1INT (1<<1)
#define TIMER_TMRSTAT_TMR0INT (1<<0)
#define TIMER_TMR0LOAD 0x10
#define TIMER_TMR0VAL 0x14
#define TIMER_TMR0CTL 0x18
#define TIMER_TMR1LOAD 0x20
#define TIMER_TMR1VAL 0x24
#define TIMER_TMR1CTL 0x28
#define TIMER_TMRLOAD_TMR0LOAD_MASK 0xffff
#define TIMER_TMRVAL_TMR0VAL_MASK 0xffff
#define TIMER_TMRCTL_ENABLE (1<<7)
#define TIMER_TMRCTL_MODE_MASK 0x00000030
#define TIMER_TMRCTL_MODE_SHIFT 4
#define TIMER_TMRCTL_MODE_FREE 0
#define TIMER_TMRCTL_MODE_PERIODIC 1
#define TIMER_TMRCTL_MODE_TIMOUT 2
#define TIMER_TMRCTL_MODE_TIMOUT3 3
#define TIMER_TMRCTL_PRESCALE_MASK 0x0000000f
#define TIMER_TMRCTL_PRESCALE_SHIFT 0
#define TIMER_TMRCTL_PRESCALE_NONE 0
#define TIMER_TMRCTL_PRESCALE_BY_4 1
#define TIMER_TMRCTL_PRESCALE_BY_8 2
#define TIMER_TMRCTL_PRESCALE_BY_16 3
#define TIMER_TMRCTL_PRESCALE_BY_32 4
#define TIMER_TMRCTL_PRESCALE_BY_64 5
#define TIMER_TMRCTL_PRESCALE_BY_128 6
#define TIMER_TMRCTL_PRESCALE_BY_256 7
#define TIMER_TMRCTL_PRESCALE_BY_512 8
#define TIMER_TMRCTL_PRESCALE_BY_1K 9
#define TIMER_TMRCTL_PRESCALE_BY_2K 10
#define TIMER_TMRCTL_PRESCALE_BY_4K 11
#define TIMER_TMRCTL_PRESCALE_BY_8K 12
#define TIMER_TMRCTL_PRESCALE_BY_16K 13
#define TIMER_TMRCTL_PRESCALE_BY_32K 14
#define TIMER_TMRCTL_PRESCALE_BY_64K 15
/* Interrupt Controller */
#define IC_IRQ0STAT 0x00
#define IC_IRQ1STAT 0x04
#define IC_INTTYPE 0x20
#define IC_INTRAW 0x30
#define IC_INT_ENA 0x34
#define IC_INT_DIS 0x38
#define IC_OTG 18
#define IC_ETHSW 17
#define IC_R2P 15
#define IC_SDHC 14
#define IC_UARTLITE 12
#define IC_SPI 11
#define IC_I2S 10
#define IC_PERFC 9
#define IC_NAND 8
#define IC_DMA 7
#define IC_PIO 6
#define IC_UART 5
#define IC_PCM 4
#define IC_ILL_ACCESS 3
#define IC_WDTIMER 2
#define IC_TIMER0 1
#define IC_SYSCTL 0
#define IC_LINE_GLOBAL (1<<31) /* Only for DIS/ENA regs */
#define IC_LINE_OTG (1<<18)
#define IC_LINE_ETHSW (1<<17)
#define IC_LINE_UARTLITE (1<<12)
#define IC_LINE_I2S (1<<10)
#define IC_LINE_PERFC (1<<9)
#define IC_LINE_NAND (1<<8)
#define IC_LINE_DMA (1<<7)
#define IC_LINE_PIO (1<<6)
#define IC_LINE_UART (1<<5)
#define IC_LINE_PCM (1<<4)
#define IC_LINE_ILL_ACCESS (1<<3)
#define IC_LINE_WDTIMER (1<<2)
#define IC_LINE_TIMER0 (1<<1)
#define IC_LINE_SYSCTL (1<<0)
#define IC_INT_MASK 0x000617ff
/* GPIO */
#define GPIO23_00_INT 0x00 /* Programmed I/O Int Status */
#define GPIO23_00_EDGE 0x04 /* Programmed I/O Edge Status */
#define GPIO23_00_RENA 0x08 /* Programmed I/O Int on Rising */
#define GPIO23_00_FENA 0x0C /* Programmed I/O Int on Falling */
#define GPIO23_00_DATA 0x20 /* Programmed I/O Data */
#define GPIO23_00_DIR 0x24 /* Programmed I/O Direction */
#define GPIO23_00_POL 0x28 /* Programmed I/O Pin Polarity */
#define GPIO23_00_SET 0x2C /* Set PIO Data Bit */
#define GPIO23_00_RESET 0x30 /* Clear PIO Data bit */
#define GPIO23_00_TOG 0x34 /* Toggle PIO Data bit */
#define GPIO39_24_INT 0x38
#define GPIO39_24_EDGE 0x3c
#define GPIO39_24_RENA 0x40
#define GPIO39_24_FENA 0x44
#define GPIO39_24_DATA 0x48
#define GPIO39_24_DIR 0x4c
#define GPIO39_24_POL 0x50
#define GPIO39_24_SET 0x54
#define GPIO39_24_RESET 0x58
#define GPIO39_24_TOG 0x5c
#define GPIO51_40_INT 0x60
#define GPIO51_40_EDGE 0x64
#define GPIO51_40_RENA 0x68
#define GPIO51_40_FENA 0x6C
#define GPIO51_40_DATA 0x70
#define GPIO51_40_DIR 0x74
#define GPIO51_40_POL 0x78
#define GPIO51_40_SET 0x7C
#define GPIO51_40_RESET 0x80
#define GPIO51_40_TOG 0x84
#define GDMA_CHANNEL_REQ0 0
#define GDMA_CHANNEL_REQ1 1 /* (NAND-flash) */
#define GDMA_CHANNEL_REQ2 2 /* (I2S) */
#define GDMA_CHANNEL_REQ3 3 /* (PCM0-RX) */
#define GDMA_CHANNEL_REQ4 4 /* (PCM1-RX) */
#define GDMA_CHANNEL_REQ5 5 /* (PCM0-TX) */
#define GDMA_CHANNEL_REQ6 6 /* (PCM1-TX) */
#define GDMA_CHANNEL_REQ7 7
#define GDMA_CHANNEL_MEM 8
/* Generic DMA Controller */
/* GDMA Channel n Source Address */
#define GDMASA(n) (0x00 + 0x10*n)
/* GDMA Channel n Destination Address */
#define GDMADA(n) (0x04 + 0x10*n)
/* GDMA Channel n Control Register 0 */
#define GDMACT0(n) (0x08 + 0x10*n)
#define GDMACT0_TR_COUNT_MASK 0x0fff0000
#define GDMACT0_TR_COUNT_SHIFT 16
#define GDMACT0_SRC_CHAN_SHIFT 12
#define GDMACT0_SRC_CHAN_MASK 0x0000f000
#define GDMACT0_DST_CHAN_SHIFT 8
#define GDMACT0_DST_CHAN_MASK 0x00000f00
#define GDMACT0_SRC_BURST_MODE (1<<7)
#define GDMACT0_DST_BURST_MODE (1<<6)
#define GDMACT0_BURST_SIZE_SHIFT 3
#define GDMACT0_BURST_SIZE_MASK 0x00000038
#define GDMACT0_BURST_SIZE_1 0
#define GDMACT0_BURST_SIZE_2 1
#define GDMACT0_BURST_SIZE_4 2
#define GDMACT0_BURST_SIZE_8 3
#define GDMACT0_BURST_SIZE_16 4
#define GDMACT0_DONE_INT_EN (1<<2)
#define GDMACT0_CHAN_EN (1<<1)
/*
* In software mode, the data transfer will start when the Channel Enable bit
* is set.
* In hardware mode, the data transfer will start when the DMA Request is
* asserted.
*/
#define GDMACT0_SWMODE (1<<0)
/* SPI controller interface */
#define RT305X_SPISTAT 0x00
/* SPIBUSY is alias for SPIBUSY, because SPISTAT have only BUSY bit*/
#define RT305X_SPIBUSY RT305X_SPISTAT
#define RT305X_SPICFG 0x10
#define MSBFIRST (1<<8)
#define SPICLKPOL (1<<6)
#define CAPT_ON_CLK_FALL (1<<5)
#define TX_ON_CLK_FALL (1<<4)
#define HIZSPI (1<<3) /* Set SPI pins to Tri-state */
#define SPI_CLK_SHIFT 0 /* SPI clock divide control */
#define SPI_CLK_MASK 0x00000007
#define SPI_CLK_DIV2 0
#define SPI_CLK_DIV4 1
#define SPI_CLK_DIV8 2
#define SPI_CLK_DIV16 3
#define SPI_CLK_DIV32 4
#define SPI_CLK_DIV64 5
#define SPI_CLK_DIV128 6
#define SPI_CLK_DISABLED 7
#define RT305X_SPICTL 0x14
#define HIZSMOSI (1<<3)
#define START_WRITE (1<<2)
#define START_READ (1<<1)
#define CS_HIGH (1<<0)
#define RT305X_SPIDATA 0x20
#define SPIDATA_MASK 0x000000ff
#define RT305X_SPI_WRITE 1
#define RT305X_SPI_READ 0
#endif /* _RT305XREG_H_ */

View File

@ -1,162 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2010 Aleksandr Rybalko.
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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 _RT_SWREG_H_
#define _RT_SWREG_H_
/* XXX: must move to config */
#define RT3052F
#define RT_SW_BASE 0x10110000
#define RT_SW_ISR 0x00
#define WATCHDOG1_TMR_EXPIRED (1<<29)
#define WATCHDOG0_TMR_EXPIRED (1<<28)
#define HAS_INTRUDER (1<<27)
#define PORT_ST_CHG (1<<26)
#define BC_STORM (1<<25)
#define MUST_DROP_LAN (1<<24)
#define GLOBAL_QUE_FULL (1<<23)
#define LAN_QUE_FULL6 (1<<20)
#define LAN_QUE_FULL5 (1<<19)
#define LAN_QUE_FULL4 (1<<18)
#define LAN_QUE_FULL3 (1<<17)
#define LAN_QUE_FULL2 (1<<16)
#define LAN_QUE_FULL1 (1<<15)
#define LAN_QUE_FULL0 (1<<14)
#define RT_SW_IMR 0x04
#define RT_SW_FCT0 0x08
#define RT_SW_FCT1 0x0c
#define RT_SW_PFC0 0x10
#define RT_SW_PFC1 0x14
#define RT_SW_PFC2 0x18
#define RT_SW_GQS0 0x1c
#define RT_SW_GQS1 0x20
#define RT_SW_ATS 0x24
#define RT_SW_ATS0 0x28
#define RT_SW_ATS1 0x2c
#define RT_SW_ATS2 0x30
#define RT_SW_WMAD0 0x34
#define RT_SW_WMAD1 0x38
#define RT_SW_WMAD2 0x3c
#define RT_SW_PVIDC0 0x40
#define RT_SW_PVIDC1 0x44
#define RT_SW_PVIDC2 0x48
#define RT_SW_PVIDC3 0x4c
#define RT_SW_VID0 0x50
#define RT_SW_VID1 0x54
#define RT_SW_VID2 0x58
#define RT_SW_VID3 0x5c
#define RT_SW_VID4 0x60
#define RT_SW_VID5 0x64
#define RT_SW_VID6 0x68
#define RT_SW_VID7 0x6c
#define RT_SW_VMSC0 0x70
#define RT_SW_VMSC1 0x74
#define RT_SW_VMSC2 0x78
#define RT_SW_VMSC3 0x7c
#define RT_SW_POA 0x80
#define RT_SW_FPA 0x84
#define RT_SW_PTS 0x88
#define RT_SW_SOCPC 0x8c
#define RT_SW_POC0 0x90
#define RT_SW_POC1 0x94
#define RT_SW_POC2 0x98
#define RT_SW_SGC 0x9c
#define RT_SW_STRT 0xa0
#define RT_SW_LEDP0 0xa4
#define RT_SW_LEDP1 0xa8
#define RT_SW_LEDP2 0xac
#define RT_SW_LEDP3 0xb0
#define RT_SW_LEDP4 0xb4
#define RT_SW_WDTR 0xb8
#define RT_SW_DES 0xbc
#define RT_SW_PCR0 0xc0
#define RT_SW_PCR1 0xc4
#define RT_SW_FPA 0xc8
#define RT_SW_FCT2 0xcc
#define RT_SW_QSS0 0xd0
#define RT_SW_QSS1 0xd4
#define RT_SW_DEC 0xd8
#define BRIDGE_IPG_SHIFT 24
#define DEBUG_SW_PORT_SEL_SHIFT 3
#define DEBUG_SW_PORT_SEL_MASK 0x00000038
#define RT_SW_MTI 0xdc
#define SKIP_BLOCKS_SHIFT 7
#define SKIP_BLOCKS_MASK 0x0000ff80
#define SW_RAM_TEST_DONE (1<<6)
#define AT_RAM_TEST_DONE (1<<5)
#define AT_RAM_TEST_FAIL (1<<4)
#define LK_RAM_TEST_DONE (1<<3)
#define LK_RAM_TEST_FAIL (1<<2)
#define DT_RAM_TEST_DONE (1<<1)
#define DT_RAM_TEST_FAIL (1<<0)
#define RT_SW_PPC 0xe0
#define SW2FE_CNT_SHIFT 16
#define FE2SW_CNT_SHIFT 0
#define RT_SW_SGC2 0xe4
#define FE2SW_WL_FC_EN (1<<30)
#define LAN_PMAP_P0_IS_LAN (1<<24)
#define LAN_PMAP_P1_IS_LAN (1<<25)
#define LAN_PMAP_P2_IS_LAN (1<<26)
#define LAN_PMAP_P3_IS_LAN (1<<27)
#define LAN_PMAP_P4_IS_LAN (1<<28)
#define LAN_PMAP_P5_IS_LAN (1<<29)
/* Transmit CPU TPID(810x) port bit map */
#define TX_CPU_TPID_BIT_MAP_SHIFT 16
#define TX_CPU_TPID_BIT_MAP_MASK 0x007f0000
#define ARBITER_LAN_EN (1<<11)
#define CPU_TPID_EN (1<<10)
#define P0_DOUBLE_TAG_EN (1<<0)
#define P1_DOUBLE_TAG_EN (1<<1)
#define P2_DOUBLE_TAG_EN (1<<2)
#define P3_DOUBLE_TAG_EN (1<<3)
#define P4_DOUBLE_TAG_EN (1<<4)
#define P5_DOUBLE_TAG_EN (1<<5)
#define RT_SW_P0PC 0xe8
#define RT_SW_P1PC 0xec
#define RT_SW_P2PC 0xf0
#define RT_SW_P3PC 0xf4
#define RT_SW_P4PC 0xf8
#define RT_SW_P5PC 0xfc
#define BAD_PCOUNT_SHIFT 16
#define BAD_PCOUNT_MASK 0xffff0000
#define GOOD_PCOUNT_SHIFT 0
#define GOOD_PCOUNT_MASK 0x0000ffff
#endif /* _RT_SWREG_H_ */

View File

@ -1,7 +0,0 @@
# $FreeBSD$
# Standard include file for RT305XF SoC
files "../rt305x/files.rt305x"
cpu CPU_MIPS24K

View File

@ -1,96 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2007 Bruce M. Simpson.
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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
* $Id$
*/
/*
* Skeleton of this file was based on respective code for ARM
* code written by Olivier Houchard.
*/
/*
* XXXMIPS: This file is hacked from arm/... . XXXMIPS here means this file is
* experimental and was written for MIPS32 port.
*/
#include "opt_uart.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <dev/pci/pcivar.h>
#include <dev/uart/uart.h>
#include <dev/uart/uart_bus.h>
#include <dev/uart/uart_cpu.h>
#include <mips/rt305x/rt305xreg.h>
#include "uart_if.h"
static int uart_rt305x_probe(device_t dev);
extern struct uart_class uart_rt305x_uart_class;
static device_method_t uart_rt305x_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, uart_rt305x_probe),
DEVMETHOD(device_attach, uart_bus_attach),
DEVMETHOD(device_detach, uart_bus_detach),
{ 0, 0 }
};
static driver_t uart_rt305x_driver = {
uart_driver_name,
uart_rt305x_methods,
sizeof(struct uart_softc),
};
static int
uart_rt305x_probe(device_t dev)
{
struct uart_softc *sc;
sc = device_get_softc(dev);
sc->sc_class = &uart_rt305x_uart_class;
sc->sc_bas.regshft = 2;
sc->sc_bas.bst = mips_bus_space_generic;
sc->sc_bas.bsh =
MIPS_PHYS_TO_KSEG1(device_get_unit(dev)?UARTLITE_BASE:UART_BASE);
return (uart_bus_probe(dev, 2, 0, SYSTEM_CLOCK, 0, 0));
}
DRIVER_MODULE(uart, obio, uart_rt305x_driver, uart_devclass, 0, 0);

View File

@ -1,88 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2006 Wojciech A. Koszek <wkoszek@FreeBSD.org>
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
*
* $Id$
*/
/*
* Skeleton of this file was based on respective code for ARM
* code written by Olivier Houchard.
*/
/*
* XXXMIPS: This file is hacked from arm/... . XXXMIPS here means this file is
* experimental and was written for MIPS32 port.
*/
#include "opt_uart.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/cons.h>
#include <machine/bus.h>
#include <dev/uart/uart.h>
#include <dev/uart/uart_cpu.h>
#include <mips/rt305x/rt305xreg.h>
extern struct uart_class uart_rt305x_uart_class;
bus_space_tag_t uart_bus_space_io;
bus_space_tag_t uart_bus_space_mem;
int
uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
{
return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0);
}
int
uart_cpu_getdev(int devtype, struct uart_devinfo *di)
{
di->ops = uart_getops(&uart_rt305x_uart_class);
di->bas.chan = 0;
di->bas.bst = mips_bus_space_generic;
di->bas.regshft = 2;
di->bas.rclk = SYSTEM_CLOCK;
di->baudrate = 115200;
di->databits = 8;
di->stopbits = 1;
di->parity = UART_PARITY_NONE;
uart_bus_space_io = NULL;
uart_bus_space_mem = mips_bus_space_generic;
#ifdef RT305X_USE_UART
di->bas.bsh = MIPS_PHYS_TO_KSEG1(UART_BASE);
#else
di->bas.bsh = MIPS_PHYS_TO_KSEG1(UARTLITE_BASE);
#endif
return (0);
}

View File

@ -1,535 +0,0 @@
/* $NetBSD: uart.c,v 1.2 2007/03/23 20:05:47 dogcow Exp $ */
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2010 Aleksandr Rybalko.
* Copyright (c) 2007 Ruslan Ermilov and Vsevolod Lobko.
* Copyright (c) 2007 Oleksandr Tymoshenko.
* 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 AUTHORS ``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 AUTHORS
* 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 "opt_ddb.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kdb.h>
#include <sys/reboot.h>
#include <sys/sysctl.h>
#include <sys/kernel.h>
#include <machine/bus.h>
#include <dev/uart/uart.h>
#include <dev/uart/uart_cpu.h>
#include <dev/uart/uart_bus.h>
#include <mips/rt305x/uart_dev_rt305x.h>
#include <mips/rt305x/rt305xreg.h>
#include "uart_if.h"
/*
* Low-level UART interface.
*/
static int rt305x_uart_probe(struct uart_bas *bas);
static void rt305x_uart_init(struct uart_bas *bas, int, int, int, int);
static void rt305x_uart_term(struct uart_bas *bas);
static void rt305x_uart_putc(struct uart_bas *bas, int);
static int rt305x_uart_rxready(struct uart_bas *bas);
static int rt305x_uart_getc(struct uart_bas *bas, struct mtx *);
static struct uart_ops uart_rt305x_uart_ops = {
.probe = rt305x_uart_probe,
.init = rt305x_uart_init,
.term = rt305x_uart_term,
.putc = rt305x_uart_putc,
.rxready = rt305x_uart_rxready,
.getc = rt305x_uart_getc,
};
static int uart_output = 1;
SYSCTL_INT(_kern, OID_AUTO, uart_output, CTLFLAG_RWTUN,
&uart_output, 0, "UART output enabled.");
static int
rt305x_uart_probe(struct uart_bas *bas)
{
return (0);
}
static void
rt305x_uart_init(struct uart_bas *bas, int baudrate, int databits,
int stopbits, int parity)
{
#ifdef notyet
/* CLKDIV = 384000000/ 3/ 16/ br */
/* for 384MHz CLKDIV = 8000000 / baudrate; */
switch (databits) {
case 5:
databits = UART_LCR_5B;
break;
case 6:
databits = UART_LCR_6B;
break;
case 7:
databits = UART_LCR_7B;
break;
case 8:
databits = UART_LCR_8B;
break;
default:
/* Unsupported */
return;
}
switch (parity) {
case UART_PARITY_EVEN: parity = (UART_LCR_PEN|UART_LCR_EVEN); break;
case UART_PARITY_NONE: parity = (UART_LCR_PEN); break;
case UART_PARITY_ODD: parity = 0; break;
/* Unsupported */
default: return;
}
uart_setreg(bas, UART_CDDL_REG, 8000000/baudrate);
uart_barrier(bas);
uart_setreg(bas, UART_LCR_REG, databits | (stopbits==1?0:4) | parity);
uart_barrier(bas);
#endif
}
static void
rt305x_uart_term(struct uart_bas *bas)
{
uart_setreg(bas, UART_MCR_REG, 0);
uart_barrier(bas);
}
static void
rt305x_uart_putc(struct uart_bas *bas, int c)
{
char chr;
if (!uart_output) return;
chr = c;
while (!(uart_getreg(bas, UART_LSR_REG) & UART_LSR_THRE));
uart_setreg(bas, UART_TX_REG, c);
uart_barrier(bas);
while (!(uart_getreg(bas, UART_LSR_REG) & UART_LSR_THRE));
}
static int
rt305x_uart_rxready(struct uart_bas *bas)
{
#ifdef notyet
if (uart_getreg(bas, UART_LSR_REG) & UART_LSR_DR)
return (1);
return (0);
#else
return (1);
#endif
}
static int
rt305x_uart_getc(struct uart_bas *bas, struct mtx *hwmtx)
{
int c;
uart_lock(hwmtx);
while (!(uart_getreg(bas, UART_LSR_REG) & UART_LSR_DR)) {
uart_unlock(hwmtx);
DELAY(10);
uart_lock(hwmtx);
}
c = uart_getreg(bas, UART_RX_REG);
uart_unlock(hwmtx);
return (c);
}
/*
* High-level UART interface.
*/
struct rt305x_uart_softc {
struct uart_softc base;
};
static int rt305x_uart_bus_attach(struct uart_softc *);
static int rt305x_uart_bus_detach(struct uart_softc *);
static int rt305x_uart_bus_flush(struct uart_softc *, int);
static int rt305x_uart_bus_getsig(struct uart_softc *);
static int rt305x_uart_bus_ioctl(struct uart_softc *, int, intptr_t);
static int rt305x_uart_bus_ipend(struct uart_softc *);
static int rt305x_uart_bus_param(struct uart_softc *, int, int, int, int);
static int rt305x_uart_bus_probe(struct uart_softc *);
static int rt305x_uart_bus_receive(struct uart_softc *);
static int rt305x_uart_bus_setsig(struct uart_softc *, int);
static int rt305x_uart_bus_transmit(struct uart_softc *);
static void rt305x_uart_bus_grab(struct uart_softc *);
static void rt305x_uart_bus_ungrab(struct uart_softc *);
static kobj_method_t rt305x_uart_methods[] = {
KOBJMETHOD(uart_attach, rt305x_uart_bus_attach),
KOBJMETHOD(uart_detach, rt305x_uart_bus_detach),
KOBJMETHOD(uart_flush, rt305x_uart_bus_flush),
KOBJMETHOD(uart_getsig, rt305x_uart_bus_getsig),
KOBJMETHOD(uart_ioctl, rt305x_uart_bus_ioctl),
KOBJMETHOD(uart_ipend, rt305x_uart_bus_ipend),
KOBJMETHOD(uart_param, rt305x_uart_bus_param),
KOBJMETHOD(uart_probe, rt305x_uart_bus_probe),
KOBJMETHOD(uart_receive, rt305x_uart_bus_receive),
KOBJMETHOD(uart_setsig, rt305x_uart_bus_setsig),
KOBJMETHOD(uart_transmit, rt305x_uart_bus_transmit),
KOBJMETHOD(uart_grab, rt305x_uart_bus_grab),
KOBJMETHOD(uart_ungrab, rt305x_uart_bus_ungrab),
{ 0, 0 }
};
struct uart_class uart_rt305x_uart_class = {
"rt305x",
rt305x_uart_methods,
sizeof(struct rt305x_uart_softc),
.uc_ops = &uart_rt305x_uart_ops,
.uc_range = 1, /* use hinted range */
.uc_rclk = SYSTEM_CLOCK,
.uc_rshift = 0
};
#define SIGCHG(c, i, s, d) \
if (c) { \
i |= (i & s) ? s : s | d; \
} else { \
i = (i & s) ? (i & ~s) | d : i; \
}
/*
* Disable TX interrupt. uart should be locked
*/
static __inline void
rt305x_uart_disable_txintr(struct uart_softc *sc)
{
struct uart_bas *bas = &sc->sc_bas;
uint8_t cr;
cr = uart_getreg(bas, UART_IER_REG);
cr &= ~UART_IER_ETBEI;
uart_setreg(bas, UART_IER_REG, cr);
uart_barrier(bas);
}
/*
* Enable TX interrupt. uart should be locked
*/
static __inline void
rt305x_uart_enable_txintr(struct uart_softc *sc)
{
struct uart_bas *bas = &sc->sc_bas;
uint8_t cr;
cr = uart_getreg(bas, UART_IER_REG);
cr |= UART_IER_ETBEI;
uart_setreg(bas, UART_IER_REG, cr);
uart_barrier(bas);
}
static int
rt305x_uart_bus_attach(struct uart_softc *sc)
{
struct uart_bas *bas;
struct uart_devinfo *di;
bas = &sc->sc_bas;
if (sc->sc_sysdev != NULL) {
di = sc->sc_sysdev;
rt305x_uart_init(bas, di->baudrate, di->databits, di->stopbits,
di->parity);
} else {
rt305x_uart_init(bas, 115200, 8, 1, 0);
}
(void)rt305x_uart_bus_getsig(sc);
/* Enable FIFO */
uart_setreg(bas, UART_FCR_REG,
uart_getreg(bas, UART_FCR_REG) |
UART_FCR_FIFOEN | UART_FCR_TXTGR_1 | UART_FCR_RXTGR_1);
uart_barrier(bas);
/* Enable interrupts */
uart_setreg(bas, UART_IER_REG,
UART_IER_EDSSI | UART_IER_ELSI | UART_IER_ERBFI);
uart_barrier(bas);
return (0);
}
static int
rt305x_uart_bus_detach(struct uart_softc *sc)
{
return (0);
}
static int
rt305x_uart_bus_flush(struct uart_softc *sc, int what)
{
struct uart_bas *bas = &sc->sc_bas;
uint32_t fcr = uart_getreg(bas, UART_FCR_REG);
if (what & UART_FLUSH_TRANSMITTER) {
uart_setreg(bas, UART_FCR_REG, fcr|UART_FCR_TXRST);
uart_barrier(bas);
}
if (what & UART_FLUSH_RECEIVER) {
uart_setreg(bas, UART_FCR_REG, fcr|UART_FCR_RXRST);
uart_barrier(bas);
}
uart_setreg(bas, UART_FCR_REG, fcr);
uart_barrier(bas);
return (0);
}
static int
rt305x_uart_bus_getsig(struct uart_softc *sc)
{
uint32_t new, old, sig;
uint8_t bes;
do {
old = sc->sc_hwsig;
sig = old;
uart_lock(sc->sc_hwmtx);
bes = uart_getreg(&sc->sc_bas, UART_MSR_REG);
uart_unlock(sc->sc_hwmtx);
/* XXX: chip can show delta */
SIGCHG(bes & UART_MSR_CTS, sig, SER_CTS, SER_DCTS);
SIGCHG(bes & UART_MSR_DCD, sig, SER_DCD, SER_DDCD);
SIGCHG(bes & UART_MSR_DSR, sig, SER_DSR, SER_DDSR);
new = sig & ~SER_MASK_DELTA;
} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
return (sig);
}
static int
rt305x_uart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
{
struct uart_bas *bas;
int baudrate, divisor, error;
bas = &sc->sc_bas;
error = 0;
uart_lock(sc->sc_hwmtx);
switch (request) {
case UART_IOCTL_BREAK:
/* TODO: Send BREAK */
break;
case UART_IOCTL_BAUD:
divisor = uart_getreg(bas, UART_CDDL_REG);
baudrate = bas->rclk / (divisor * 16);
*(int*)data = baudrate;
break;
default:
error = EINVAL;
break;
}
uart_unlock(sc->sc_hwmtx);
return (error);
}
static int
rt305x_uart_bus_ipend(struct uart_softc *sc)
{
struct uart_bas *bas;
int ipend;
uint8_t iir, lsr, msr;
bas = &sc->sc_bas;
ipend = 0;
uart_lock(sc->sc_hwmtx);
iir = uart_getreg(&sc->sc_bas, UART_IIR_REG);
lsr = uart_getreg(&sc->sc_bas, UART_LSR_REG);
uart_setreg(&sc->sc_bas, UART_LSR_REG, lsr);
msr = uart_getreg(&sc->sc_bas, UART_MSR_REG);
uart_setreg(&sc->sc_bas, UART_MSR_REG, msr);
if (iir & UART_IIR_INTP) {
uart_unlock(sc->sc_hwmtx);
return (0);
}
switch ((iir >> 1) & 0x07) {
case UART_IIR_ID_THRE:
ipend |= SER_INT_TXIDLE;
break;
case UART_IIR_ID_DR2:
rt305x_uart_bus_flush(sc, UART_FLUSH_RECEIVER);
/* passthrough */
case UART_IIR_ID_DR:
ipend |= SER_INT_RXREADY;
break;
case UART_IIR_ID_MST:
case UART_IIR_ID_LINESTATUS:
ipend |= SER_INT_SIGCHG;
if (lsr & UART_LSR_BI)
{
ipend |= SER_INT_BREAK;
#ifdef KDB
breakpoint();
#endif
}
if (lsr & UART_LSR_OE)
ipend |= SER_INT_OVERRUN;
break;
default:
/* XXX: maybe return error here */
break;
}
uart_unlock(sc->sc_hwmtx);
return (ipend);
}
static int
rt305x_uart_bus_param(struct uart_softc *sc, int baudrate, int databits,
int stopbits, int parity)
{
uart_lock(sc->sc_hwmtx);
rt305x_uart_init(&sc->sc_bas, baudrate, databits, stopbits, parity);
uart_unlock(sc->sc_hwmtx);
return (0);
}
static int
rt305x_uart_bus_probe(struct uart_softc *sc)
{
char buf[80];
int error;
error = rt305x_uart_probe(&sc->sc_bas);
if (error)
return (error);
sc->sc_rxfifosz = 16;
sc->sc_txfifosz = 16;
snprintf(buf, sizeof(buf), "rt305x_uart");
device_set_desc_copy(sc->sc_dev, buf);
return (0);
}
static int
rt305x_uart_bus_receive(struct uart_softc *sc)
{
struct uart_bas *bas;
int xc;
uint8_t lsr;
bas = &sc->sc_bas;
uart_lock(sc->sc_hwmtx);
lsr = uart_getreg(bas, UART_LSR_REG);
while ((lsr & UART_LSR_DR)) {
if (uart_rx_full(sc)) {
sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
break;
}
xc = 0;
xc = uart_getreg(bas, UART_RX_REG);
if (lsr & UART_LSR_FE)
xc |= UART_STAT_FRAMERR;
if (lsr & UART_LSR_PE)
xc |= UART_STAT_PARERR;
if (lsr & UART_LSR_OE)
xc |= UART_STAT_OVERRUN;
uart_barrier(bas);
uart_rx_put(sc, xc);
lsr = uart_getreg(bas, UART_LSR_REG);
}
uart_unlock(sc->sc_hwmtx);
return (0);
}
static int
rt305x_uart_bus_setsig(struct uart_softc *sc, int sig)
{
/* TODO: implement (?) */
return (0);
}
static int
rt305x_uart_bus_transmit(struct uart_softc *sc)
{
struct uart_bas *bas = &sc->sc_bas;
int i;
if (!uart_output) return (0);
bas = &sc->sc_bas;
uart_lock(sc->sc_hwmtx);
while ((uart_getreg(bas, UART_LSR_REG) & UART_LSR_THRE) == 0)
;
rt305x_uart_enable_txintr(sc);
for (i = 0; i < sc->sc_txdatasz; i++) {
uart_setreg(bas, UART_TX_REG, sc->sc_txbuf[i]);
uart_barrier(bas);
}
sc->sc_txbusy = 1;
uart_unlock(sc->sc_hwmtx);
return (0);
}
static void
rt305x_uart_bus_grab(struct uart_softc *sc)
{
struct uart_bas *bas = &sc->sc_bas;
/* disable interrupts -- XXX not sure which one is RX, so kill them all */
uart_lock(sc->sc_hwmtx);
uart_setreg(bas, UART_IER_REG, 0);
uart_barrier(bas);
uart_unlock(sc->sc_hwmtx);
}
static void
rt305x_uart_bus_ungrab(struct uart_softc *sc)
{
struct uart_bas *bas = &sc->sc_bas;
/* Enable interrupts */
uart_lock(sc->sc_hwmtx);
uart_setreg(bas, UART_IER_REG,
UART_IER_EDSSI | UART_IER_ELSI | UART_IER_ERBFI);
uart_barrier(bas);
uart_unlock(sc->sc_hwmtx);
}

View File

@ -1,128 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2010 Aleksandr Rybalko.
* 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 names of the authors may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS
* 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 _RT305XUART_H
#define _RT305XUART_H
#undef uart_getreg
#undef uart_setreg
#define uart_getreg(bas, reg) \
bus_space_read_4((bas)->bst, (bas)->bsh, reg)
#define uart_setreg(bas, reg, value) \
bus_space_write_4((bas)->bst, (bas)->bsh, reg, value)
/* UART registers */
#define UART_RX_REG 0x00
#define UART_TX_REG 0x04
#define UART_IER_REG 0x08
#define UART_IER_EDSSI (1<<3) /* Only full UART */
#define UART_IER_ELSI (1<<2)
#define UART_IER_ETBEI (1<<1)
#define UART_IER_ERBFI (1<<0)
#define UART_IIR_REG 0x0c
#define UART_IIR_RXFIFO (1<<7)
#define UART_IIR_TXFIFO (1<<6)
#define UART_IIR_ID_MST 0
#define UART_IIR_ID_THRE 1
#define UART_IIR_ID_DR 2
#define UART_IIR_ID_LINESTATUS 3
#define UART_IIR_ID_DR2 6
#define UART_IIR_ID_SHIFT 1
#define UART_IIR_ID_MASK 0x0000000e
#define UART_IIR_INTP (1<<0)
#define UART_FCR_REG 0x10
#define UART_FCR_RXTGR_1 (0<<6)
#define UART_FCR_RXTGR_4 (1<<6)
#define UART_FCR_RXTGR_8 (2<<6)
#define UART_FCR_RXTGR_12 (3<<6)
#define UART_FCR_TXTGR_1 (0<<4)
#define UART_FCR_TXTGR_4 (1<<4)
#define UART_FCR_TXTGR_8 (2<<4)
#define UART_FCR_TXTGR_12 (3<<4)
#define UART_FCR_DMA (1<<3)
#define UART_FCR_TXRST (1<<2)
#define UART_FCR_RXRST (1<<1)
#define UART_FCR_FIFOEN (1<<0)
#define UART_LCR_REG 0x14
#define UART_LCR_DLAB (1<<7)
#define UART_LCR_BRK (1<<6)
#define UART_LCR_FPAR (1<<5)
#define UART_LCR_EVEN (1<<4)
#define UART_LCR_PEN (1<<3)
#define UART_LCR_STB_15 (1<<2)
#define UART_LCR_5B 0
#define UART_LCR_6B 1
#define UART_LCR_7B 2
#define UART_LCR_8B 3
#define UART_MCR_REG 0x18
#define UART_MCR_LOOP (1<<4)
#define UART_MCR_OUT2_L (1<<3) /* Only full UART */
#define UART_MCR_OUT1_L (1<<2) /* Only full UART */
#define UART_MCR_RTS_L (1<<1) /* Only full UART */
#define UART_MCR_DTR_L (1<<0) /* Only full UART */
#define UART_LSR_REG 0x1c
#define UART_LSR_ERINF (1<<7)
#define UART_LSR_TEMT (1<<6)
#define UART_LSR_THRE (1<<5)
#define UART_LSR_BI (1<<4)
#define UART_LSR_FE (1<<3)
#define UART_LSR_PE (1<<2)
#define UART_LSR_OE (1<<1)
#define UART_LSR_DR (1<<0)
#define UART_MSR_REG 0x20 /* Only full UART */
#define UART_MSR_DCD (1<<7) /* Only full UART */
#define UART_MSR_RI (1<<6) /* Only full UART */
#define UART_MSR_DSR (1<<5) /* Only full UART */
#define UART_MSR_CTS (1<<4) /* Only full UART */
#define UART_MSR_DDCD (1<<3) /* Only full UART */
#define UART_MSR_TERI (1<<2) /* Only full UART */
#define UART_MSR_DDSR (1<<1) /* Only full UART */
#define UART_MSR_DCTS (1<<0) /* Only full UART */
#define UART_CDDL_REG 0x28
#define UART_CDDLL_REG 0x2c
#define UART_CDDLH_REG 0x30
#define UART_IFCTL_REG 0x34
#define UART_IFCTL_IFCTL (1<<0)
int uart_cnattach(void);
#endif /* _RT305XUART_H */