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:
parent
9fb36b5eae
commit
039f26fab0
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=327457
@ -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
|
@ -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
|
||||
|
||||
|
@ -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
|
@ -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
|
@ -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);
|
@ -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_ */
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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_ */
|
||||
|
@ -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_ */
|
||||
|
||||
|
@ -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);
|
@ -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_ */
|
||||
|
@ -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);
|
||||
}
|
@ -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);
|
@ -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);
|
||||
}
|
@ -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__ */
|
@ -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
|
@ -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);
|
@ -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_ */
|
||||
|
@ -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_ */
|
@ -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_ */
|
@ -1,7 +0,0 @@
|
||||
# $FreeBSD$
|
||||
# Standard include file for RT305XF SoC
|
||||
|
||||
files "../rt305x/files.rt305x"
|
||||
|
||||
cpu CPU_MIPS24K
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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 */
|
Loading…
Reference in New Issue
Block a user