[arm] [rt1310] add initial RT1310 SoC code.

This code base on lpc code. Ralink RT1310 is oem from 5V Technologies.
RT1310 is ARM926EJS(arm5t).

Tested:

* Buffalo WZR2-G300N

Submitted by:	Hiroki Mori <yamori813@yahoo.co.jp>
Reviewed by:	mizhka
Differential Revision:	https://reviews.freebsd.org/D7238
This commit is contained in:
Adrian Chadd 2017-05-06 06:14:46 +00:00
parent 7e2f67b973
commit 5c99cda025
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=317872
12 changed files with 4256 additions and 0 deletions

80
sys/arm/conf/RT1310 Normal file
View File

@ -0,0 +1,80 @@
#
# Custom kernel for RT1310 boards.
#
# $FreeBSD$
#
ident RT1310
include "std.arm"
hints "RT1310.hints"
# Flattened Device Tree
options FDT
options FDT_DTB_STATIC
makeoptions FDT_DTS_FILE=wzr2-g300n.dts
makeoptions MODULES_OVERRIDE=""
#makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
makeoptions WERROR="-Werror"
options SCHED_4BSD # 4BSD scheduler
options INET # InterNETworking
options FFS # Berkeley Fast Filesystem
options TMPFS # Efficient memory filesystem
options MSDOSFS
options ROOTDEVNAME=\"cd9660:/dev/cfid0s.rootfs.uzip\"
options SYSVSHM # SYSV-style shared memory
options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
options MUTEX_NOINLINE
options RWLOCK_NOINLINE
options NO_FFS_SNAPSHOT
options NO_SWAPPING
# Debugging
options ALT_BREAK_TO_DEBUGGER
options DDB
#options DEADLKRES # Enable the deadlock resolver
#options DIAGNOSTIC
#options INVARIANTS # Enable calls of extra sanity checking
#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
options KDB
options WITNESS # Enable checks to detect deadlocks and cycles
options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
#options WITNESS_KDB
# Pseudo devices
device loop
device md
device pty
device random
# Serial ports
device uart
device uart_ns8250
# Flash
device cfi
device cfid
# Networking
device ether
device mii
device bpf
device fv
# etherswitch
device mdio
device etherswitch
device miiproxy
device ip17x
# GPIO
device gpio
device gpioled
device rt1310gpio

View File

@ -0,0 +1,9 @@
# $FreeBSD$
arm/ralink/rt1310_machdep.c standard
arm/ralink/rt1310_intc.c standard
arm/ralink/rt1310_gpio.c optional rt1310gpio
arm/ralink/rt1310_timer.c standard
arm/ralink/if_fv.c optional fv
kern/kern_clocksource.c standard

1873
sys/arm/ralink/if_fv.c Normal file

File diff suppressed because it is too large Load Diff

452
sys/arm/ralink/if_fvreg.h Normal file
View File

@ -0,0 +1,452 @@
/*-
* Copyright (C) 2007
* Oleksandr Tymoshenko <gonzo@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 SOFTWFV 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 FV 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 SOFTWFV, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*
*/
#ifndef __IF_FVREG_H__
#define __IF_FVREG_H__
struct fv_desc {
uint32_t fv_stat;
uint32_t fv_devcs;
uint32_t fv_addr;
uint32_t fv_link;
};
#define FV_DMASIZE(len) ((len) & ((1 << 11)-1))
#define FV_PKTSIZE(len) ((len & 0xffff0000) >> 16)
#define FV_RX_RING_CNT 128
#define FV_TX_RING_CNT 128
#define FV_TX_RING_SIZE sizeof(struct fv_desc) * FV_TX_RING_CNT
#define FV_RX_RING_SIZE sizeof(struct fv_desc) * FV_RX_RING_CNT
#define FV_RING_ALIGN sizeof(struct fv_desc)
#define FV_RX_ALIGN sizeof(uint32_t)
#define FV_MAXFRAGS 8
#define FV_TX_INTR_THRESH 8
#define FV_TX_RING_ADDR(sc, i) \
((sc)->fv_rdata.fv_tx_ring_paddr + sizeof(struct fv_desc) * (i))
#define FV_RX_RING_ADDR(sc, i) \
((sc)->fv_rdata.fv_rx_ring_paddr + sizeof(struct fv_desc) * (i))
#define FV_INC(x,y) (x) = (((x) + 1) % y)
struct fv_txdesc {
struct mbuf *tx_m;
bus_dmamap_t tx_dmamap;
};
struct fv_rxdesc {
struct mbuf *rx_m;
bus_dmamap_t rx_dmamap;
struct fv_desc *desc;
/* Use this values on error instead of allocating new mbuf */
uint32_t saved_ctl, saved_ca;
};
struct fv_chain_data {
bus_dma_tag_t fv_parent_tag;
bus_dma_tag_t fv_tx_tag;
struct fv_txdesc fv_txdesc[FV_TX_RING_CNT];
bus_dma_tag_t fv_rx_tag;
struct fv_rxdesc fv_rxdesc[FV_RX_RING_CNT];
bus_dma_tag_t fv_tx_ring_tag;
bus_dma_tag_t fv_rx_ring_tag;
bus_dmamap_t fv_tx_ring_map;
bus_dmamap_t fv_rx_ring_map;
bus_dmamap_t fv_rx_sparemap;
int fv_tx_pkts;
int fv_tx_prod;
int fv_tx_cons;
int fv_tx_cnt;
int fv_rx_cons;
bus_dma_tag_t fv_sf_tag;
bus_dmamap_t fv_sf_buff_map;
uint32_t *fv_sf_buff;
};
struct fv_ring_data {
struct fv_desc *fv_rx_ring;
struct fv_desc *fv_tx_ring;
bus_addr_t fv_rx_ring_paddr;
bus_addr_t fv_tx_ring_paddr;
bus_addr_t fv_sf_paddr;
};
struct fv_softc {
struct ifnet *fv_ifp; /* interface info */
bus_space_handle_t fv_bhandle; /* bus space handle */
bus_space_tag_t fv_btag; /* bus space tag */
device_t fv_dev;
uint8_t fv_eaddr[ETHER_ADDR_LEN];
struct resource *fv_res;
int fv_rid;
struct resource *fv_irq;
void *fv_intrhand;
u_int32_t sc_inten; /* copy of CSR_INTEN */
u_int32_t sc_rxint_mask; /* mask of Rx interrupts we want */
u_int32_t sc_txint_mask; /* mask of Tx interrupts we want */
#ifdef MII
device_t fv_miibus;
#else
struct ifmedia fv_ifmedia;
#endif
#ifdef FV_MDIO
device_t fv_miiproxy;
#endif
int fv_if_flags;
bus_dma_tag_t fv_parent_tag;
bus_dma_tag_t fv_tag;
struct mtx fv_mtx;
phandle_t fv_ofw;
struct callout fv_stat_callout;
struct task fv_link_task;
struct fv_chain_data fv_cdata;
struct fv_ring_data fv_rdata;
int fv_link_status;
int fv_detach;
};
#define FV_LOCK(_sc) mtx_lock(&(_sc)->fv_mtx)
#define FV_UNLOCK(_sc) mtx_unlock(&(_sc)->fv_mtx)
#define FV_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->fv_mtx, MA_OWNED)
/*
* register space access macros
*/
#define CSR_WRITE_4(sc, reg, val) \
bus_space_write_4(sc->fv_btag, sc->fv_bhandle, reg, val)
#define CSR_READ_4(sc, reg) \
bus_space_read_4(sc->fv_btag, sc->fv_bhandle, reg)
/* $NetBSD: aereg.h,v 1.2 2008/04/28 20:23:28 martin Exp $ */
/*-
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
* NASA Ames Research Center.
*
* 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 SOFTWFV IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FV DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION 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 SOFTWFV, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Descriptor Status bits common to transmit and receive.
*/
#define ADSTAT_OWN 0x80000000 /* Tulip owns descriptor */
#define ADSTAT_ES 0x00008000 /* Error Summary */
/*
* Descriptor Status bits for Receive Descriptor.
*/
#define ADSTAT_Rx_FF 0x40000000 /* Filtering Fail */
#define ADSTAT_Rx_FL 0x3fff0000 /* Frame Length including CRC */
#define ADSTAT_Rx_DE 0x00004000 /* Descriptor Error */
#define ADSTAT_Rx_LE 0x00001000 /* Length Error */
#define ADSTAT_Rx_RF 0x00000800 /* Runt Frame */
#define ADSTAT_Rx_MF 0x00000400 /* Multicast Frame */
#define ADSTAT_Rx_FS 0x00000200 /* First Descriptor */
#define ADSTAT_Rx_LS 0x00000100 /* Last Descriptor */
#define ADSTAT_Rx_TL 0x00000080 /* Frame Too Long */
#define ADSTAT_Rx_CS 0x00000040 /* Collision Seen */
#define ADSTAT_Rx_RT 0x00000020 /* Frame Type */
#define ADSTAT_Rx_RW 0x00000010 /* Receive Watchdog */
#define ADSTAT_Rx_RE 0x00000008 /* Report on MII Error */
#define ADSTAT_Rx_DB 0x00000004 /* Dribbling Bit */
#define ADSTAT_Rx_CE 0x00000002 /* CRC Error */
#define ADSTAT_Rx_ZER 0x00000001 /* Zero (always 0) */
#define ADSTAT_Rx_LENGTH(x) (((x) & ADSTAT_Rx_FL) >> 16)
/*
* Descriptor Status bits for Transmit Descriptor.
*/
#define ADSTAT_Tx_ES 0x00008000 /* Error Summary */
#define ADSTAT_Tx_TO 0x00004000 /* Transmit Jabber Timeout */
#define ADSTAT_Tx_LO 0x00000800 /* Loss of Carrier */
#define ADSTAT_Tx_NC 0x00000400 /* No Carrier */
#define ADSTAT_Tx_LC 0x00000200 /* Late Collision */
#define ADSTAT_Tx_EC 0x00000100 /* Excessive Collisions */
#define ADSTAT_Tx_HF 0x00000080 /* Heartbeat Fail */
#define ADSTAT_Tx_CC 0x00000078 /* Collision Count */
#define ADSTAT_Tx_ED 0x00000004 /* Excessive Deferral */
#define ADSTAT_Tx_UF 0x00000002 /* Underflow Error */
#define ADSTAT_Tx_DE 0x00000001 /* Deferred */
#define ADSTAT_Tx_COLLISIONS(x) (((x) & ADSTAT_Tx_CC) >> 3)
/*
* Descriptor Control bits common to transmit and receive.
*/
#define ADCTL_SIZE1 0x000007ff /* Size of buffer 1 */
#define ADCTL_SIZE1_SHIFT 0
#define ADCTL_SIZE2 0x003ff800 /* Size of buffer 2 */
#define ADCTL_SIZE2_SHIFT 11
#define ADCTL_ER 0x02000000 /* End of Ring */
#define ADCTL_CH 0x01000000 /* Second Address Chained */
/*
* Descriptor Control bits for Transmit Descriptor.
*/
#define ADCTL_Tx_IC 0x80000000 /* Interrupt on Completion */
#define ADCTL_Tx_LS 0x40000000 /* Last Segment */
#define ADCTL_Tx_FS 0x20000000 /* First Segment */
#define ADCTL_Tx_SETUP 0x08000000 /* Setup frame */
#define ADCTL_Tx_AC 0x04000000 /* Add CRC Disable */
#define ADCTL_Tx_DPD 0x00800000 /* Disabled Padding */
/*
* Control registers.
*/
/* tese are registers only found on this part */
#ifdef NOTUSE
#define CSR_MACCTL 0x0000 /* mac control */
#define CSR_MACHI 0x0004
#define CSR_MACLO 0x0008
#define CSR_HTHI 0x000C /* multicast table high */
#define CSR_HTLO 0x0010 /* multicast table low */
#define CSR_MIIADDR 0x0014 /* mii address */
#define CSR_MIIDATA 0x0018 /* mii data */
#define CSR_FLOWC 0x001C /* flow control */
#define CSR_VL1 0x0020 /* vlan 1 tag */
#endif
/* these are more or less normal Tulip registers */
#define CSR_BUSMODE (0x08*0) /* bus mode */
#define CSR_TXPOLL (0x08*1) /* tx poll demand */
#define CSR_RXPOLL (0x08*2) /* rx poll demand */
#define CSR_RXLIST (0x08*3) /* rx base descriptor address */
#define CSR_TXLIST (0x08*4) /* tx base descriptor address */
#define CSR_STATUS (0x08*5) /* (interrupt) status */
#define CSR_OPMODE (0x08*6) /* operation mode */
#define CSR_INTEN (0x08*7) /* interrupt enable */
#define CSR_MISSED (0x08*8) /* missed frame counter */
#ifdef NOTUSE
#define CSR_HTBA 0x1050 /* host tx buffer address (ro) */
#define CSR_HRBA 0x1054 /* host rx buffer address (ro) */
#endif
#define CSR_MIIMNG (0x08*9) /* MII Management Register */
#define CSR_FULLDUP (0x08*11) /* Full Duplex Register */
/* 21143 like register */
#define FULLDUP_CS 0x80000000 /* Cycle Size */
#define FULLDUP_TT_SHIFT 27 /* Transmit Timer */
#define FULLDUP_NTP_SHIFT 24 /* Number of Transmit Packets */
#define FULLDUP_RT_SHIFT 20 /* Receive Timer */
#define FULLDUP_NRP_SHIFT 17 /* Number of Receive Packets */
#define FULLDUP_CON_MODE 0x00010000 /* Continuous Mode */
#define FULLDUP_TIM_SHIFT 0 /* Timer Value */
/* CSR_MACCTL - Mac Control */
#define MACCTL_RE 0x00000004 /* rx enable */
#define MACCTL_TE 0x00000008 /* tx enable */
#define MACCTL_DC 0x00000020 /* deferral check */
#define MACCTL_PSTR 0x00000100 /* automatic pad strip */
#define MACCTL_DTRY 0x00000400 /* disable retry */
#define MACCTL_DBF 0x00000800 /* disable broadcast frames */
#define MACCTL_LCC 0x00001000 /* late collision control */
#define MACCTL_HASH 0x00002000 /* hash filtering enable */
#define MACCTL_HO 0x00008000 /* disable perfect filtering */
#define MACCTL_PB 0x00010000 /* pass bad frames */
#define MACCTL_IF 0x00020000 /* inverse filtering */
#define MACCTL_PR 0x00040000 /* promiscuous mode */
#define MACCTL_PM 0x00080000 /* pass all multicast */
#define MACCTL_FDX 0x00100000 /* full duplex mode */
#define MACCTL_LOOP 0x00600000 /* loopback mask */
#define MACCTL_LOOP_INT 0x00200000 /* internal loopback */
#define MACCTL_LOOP_EXT 0x00400000 /* external loopback */
#define MACCTL_LOOP_NONE 0x00000000
#define MACCTL_DRO 0x00800000 /* disable receive own */
#define MACCTL_PS 0x08000000 /* port select, 0 = mii */
#define MACCTL_HBD 0x10000000 /* heartbeat disable */
#define MACCTL_BLE 0x40000000 /* mac big endian */
#define MACCTL_RA 0x80000000 /* receive all packets */
/* CSR_MIIADDR - MII Addess */
#define MIIADDR_BUSY 0x00000001 /* mii busy */
#define MIIADDR_WRITE 0x00000002 /* mii write */
#define MIIADDR_REG_MASK 0x000007C0 /* mii register */
#define MIIADDR_REG_SHIFT 6
#define MIIADDR_PHY_MASK 0x0000F800 /* mii phy */
#define MIIADDR_PHY_SHIFT 11
#define MIIADDR_GETREG(x) (((x) & MIIADDR_REG) >> 6)
#define MIIADDR_PUTREG(x) (((x) << 6) & MIIADR_REG)
#define MIIADDR_GETPHY(x) (((x) & MIIADDR_PHY) >> 11)
#define MIIADDR_PUTPHY(x) (((x) << 6) & MIIADR_PHY)
/* CSR_FLOWC - Flow Control */
#define FLOWC_FCB 0x00000001 /* flow control busy */
#define FLOWC_FCE 0x00000002 /* flow control enable */
#define FLOWC_PCF 0x00000004 /* pass control frames */
#define FLOWC_PT 0xffff0000 /* pause time */
/* CSR_BUSMODE - Bus Mode */
#define BUSMODE_SWR 0x00000001 /* software reset */
#define BUSMODE_BAR 0x00000002 /* bus arbitration */
#define BUSMODE_DSL 0x0000007c /* descriptor skip length */
#define BUSMODE_BLE 0x00000080 /* data buf endian */
/* programmable burst length */
#define BUSMODE_PBL_DEFAULT 0x00000000 /* default value */
#define BUSMODE_PBL_1LW 0x00000100 /* 1 longword */
#define BUSMODE_PBL_2LW 0x00000200 /* 2 longwords */
#define BUSMODE_PBL_4LW 0x00000400 /* 4 longwords */
#define BUSMODE_PBL_8LW 0x00000800 /* 8 longwords */
#define BUSMODE_PBL_16LW 0x00001000 /* 16 longwords */
#define BUSMODE_PBL_32LW 0x00002000 /* 32 longwords */
#define BUSMODE_TAP_SHIFT 17 /* Transmit Automatic Polling */
#define BUSMODE_DBO 0x00100000 /* descriptor endian */
#define BUSMODE_ALIGN_16B 0x01000000 /* force oddhw rx buf align */
/* CSR_TXPOLL - Transmit Poll Demand */
#define TXPOLL_TPD 0x00000001 /* transmit poll demand */
/* CSR_RXPOLL - Receive Poll Demand */
#define RXPOLL_RPD 0x00000001 /* receive poll demand */
/* CSR_STATUS - Status */
#define STATUS_TI 0x00000001 /* transmit interrupt */
#define STATUS_TPS 0x00000002 /* transmit process stopped */
#define STATUS_TU 0x00000004 /* transmit buffer unavail */
#define STATUS_TJT 0x00000008 /* transmit jabber timeout */
#define STATUS_UNF 0x00000020 /* transmit underflow */
#define STATUS_RI 0x00000040 /* receive interrupt */
#define STATUS_RU 0x00000080 /* receive buffer unavail */
#define STATUS_RPS 0x00000100 /* receive process stopped */
#define STATUS_ETI 0x00000400 /* early transmit interrupt */
#define STATUS_SE 0x00002000 /* system error */
#define STATUS_ER 0x00004000 /* early receive (21041) */
#define STATUS_AIS 0x00008000 /* abnormal intr summary */
#define STATUS_NIS 0x00010000 /* normal interrupt summary */
#define STATUS_RS 0x000e0000 /* receive process state */
#define STATUS_RS_STOPPED 0x00000000 /* Stopped */
#define STATUS_RS_FETCH 0x00020000 /* Running - fetch receive
descriptor */
#define STATUS_RS_CHECK 0x00040000 /* Running - check for end
of receive */
#define STATUS_RS_WAIT 0x00060000 /* Running - wait for packet */
#define STATUS_RS_SUSPENDED 0x00080000 /* Suspended */
#define STATUS_RS_CLOSE 0x000a0000 /* Running - close receive
descriptor */
#define STATUS_RS_FLUSH 0x000c0000 /* Running - flush current
frame from FIFO */
#define STATUS_RS_QUEUE 0x000e0000 /* Running - queue current
frame from FIFO into
buffer */
#define STATUS_TS 0x00700000 /* transmit process state */
#define STATUS_TS_STOPPED 0x00000000 /* Stopped */
#define STATUS_TS_FETCH 0x00100000 /* Running - fetch transmit
descriptor */
#define STATUS_TS_WAIT 0x00200000 /* Running - wait for end
of transmission */
#define STATUS_TS_READING 0x00300000 /* Running - read buffer from
memory and queue into
FIFO */
#define STATUS_TS_SUSPENDED 0x00600000 /* Suspended */
#define STATUS_TS_CLOSE 0x00700000 /* Running - close transmit
descriptor */
#define STATUS_TX_ABORT 0x00800000 /* Transmit bus abort */
#define STATUS_RX_ABORT 0x01000000 /* Transmit bus abort */
/* CSR_OPMODE - Operation Mode */
#define OPMODE_SR 0x00000002 /* start receive */
#define OPMODE_OSF 0x00000004 /* operate on second frame */
#define OPMODE_PR 0x00000040 /* promiscuous mode */
#define OPMODE_PM 0x00000080 /* pass all multicast */
#define OPMODE_FDX 0x00000200 /* full duplex mode */
#define OPMODE_ST 0x00002000 /* start transmitter */
#define OPMODE_TR 0x0000c000 /* threshold control */
#define OPMODE_TR_32 0x00000000 /* 32 words */
#define OPMODE_TR_64 0x00004000 /* 64 words */
#define OPMODE_TR_128 0x00008000 /* 128 words */
#define OPMODE_TR_256 0x0000c000 /* 256 words */
#define OPMODE_SF 0x00200000 /* store and forward mode */
#define OPMODE_SPEED 0x80000000 /* speed 100M:1 10M:0 */
/* CSR_INTEN - Interrupt Enable */
/* See bits for CSR_STATUS -- Status */
/* CSR_MISSED - Missed Frames */
#define MISSED_MFC 0xffff0000 /* missed packet count */
#define MISSED_FOC 0x0000ffff /* fifo overflow counter */
#define MISSED_GETMFC(x) ((x) & MISSED_MFC)
#define MISSED_GETFOC(x) (((x) & MISSED_FOC) >> 16)
/* setup frame code refer dc code */
#define FV_SFRAME_LEN 192
#define FV_MIN_FRAMELEN 60
/*
* MII Definitions for the 21041 and 21140/21140A/21142
* copy from if_devar.h
*/
#define MII_PREAMBLE (~0)
#define MII_TEST 0xAAAAAAAA
#define MII_RDCMD 0x06
#define MII_WRCMD 0x05
#define MII_DIN 0x00080000
#define MII_RD 0x00040000
#define MII_WR 0x00000000
#define MII_DOUT 0x00020000
#define MII_CLK 0x00010000
#define MII_CLKON MII_CLK
#define MII_CLKOFF MII_CLK
#endif /* __IF_FVREG_H__ */

View File

@ -0,0 +1,480 @@
/*-
* Copyright (c) 2011 Jakub Wojciech Klama <jceel@FreeBSD.org>
* Copyright (c) 2015 Hiroki Mori
* 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.
*
*/
/*
* GPIO on RT1310A consist of 2 ports:
* - PortA with 8 input/output pins
* - PortB with 4 input/output pins
*
* Pins are mapped to logical pin number as follows:
* [0..7] -> GPI_00..GPI_07 (port A)
* [8..11] -> GPI_08..GPI_11 (port B)
*
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bio.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/endian.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/queue.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/time.h>
#include <sys/timetc.h>
#include <sys/watchdog.h>
#include <sys/gpio.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <machine/fdt.h>
#include <dev/gpio/gpiobusvar.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <arm/ralink/rt1310reg.h>
#include <arm/ralink/rt1310var.h>
#include "gpio_if.h"
struct rt1310_gpio_softc
{
device_t lg_dev;
device_t lg_busdev;
struct resource * lg_res;
bus_space_tag_t lg_bst;
bus_space_handle_t lg_bsh;
};
struct rt1310_gpio_pinmap
{
int lp_start_idx;
int lp_pin_count;
int lp_port;
int lp_start_bit;
int lp_flags;
};
static const struct rt1310_gpio_pinmap rt1310_gpio_pins[] = {
{ 0, 8, RT_GPIO_PORTA, 0, GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
{ 8, 4, RT_GPIO_PORTB, 0, GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
{ -1, -1, -1, -1, -1 },
};
#define RT_GPIO_NPINS 12
#define RT_GPIO_PIN_IDX(_map, _idx) \
(_idx - _map->lp_start_idx)
#define RT_GPIO_PIN_BIT(_map, _idx) \
(_map->lp_start_bit + RT_GPIO_PIN_IDX(_map, _idx))
static int rt1310_gpio_probe(device_t);
static int rt1310_gpio_attach(device_t);
static int rt1310_gpio_detach(device_t);
static device_t rt1310_gpio_get_bus(device_t);
static int rt1310_gpio_pin_max(device_t, int *);
static int rt1310_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
static int rt1310_gpio_pin_getflags(device_t, uint32_t, uint32_t *);
static int rt1310_gpio_pin_setflags(device_t, uint32_t, uint32_t);
static int rt1310_gpio_pin_getname(device_t, uint32_t, char *);
static int rt1310_gpio_pin_get(device_t, uint32_t, uint32_t *);
static int rt1310_gpio_pin_set(device_t, uint32_t, uint32_t);
static int rt1310_gpio_pin_toggle(device_t, uint32_t);
static const struct rt1310_gpio_pinmap *rt1310_gpio_get_pinmap(int);
static struct rt1310_gpio_softc *rt1310_gpio_sc = NULL;
#define rt1310_gpio_read_4(_sc, _reg) \
bus_space_read_4(_sc->lg_bst, _sc->lg_bsh, _reg)
#define rt1310_gpio_write_4(_sc, _reg, _val) \
bus_space_write_4(_sc->lg_bst, _sc->lg_bsh, _reg, _val)
static int
rt1310_gpio_probe(device_t dev)
{
phandle_t node;
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (!ofw_bus_is_compatible(dev, "ralink,rt1310-gpio"))
return (ENXIO);
node = ofw_bus_get_node(dev);
if (!OF_hasprop(node, "gpio-controller"))
return (ENXIO);
device_set_desc(dev, "RT1310 GPIO");
return (BUS_PROBE_DEFAULT);
}
static int
rt1310_gpio_attach(device_t dev)
{
struct rt1310_gpio_softc *sc = device_get_softc(dev);
int rid;
sc->lg_dev = dev;
rid = 0;
sc->lg_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (!sc->lg_res) {
device_printf(dev, "cannot allocate memory window\n");
return (ENXIO);
}
sc->lg_bst = rman_get_bustag(sc->lg_res);
sc->lg_bsh = rman_get_bushandle(sc->lg_res);
rt1310_gpio_sc = sc;
sc->lg_busdev = gpiobus_attach_bus(dev);
if (sc->lg_busdev == NULL) {
bus_release_resource(dev, SYS_RES_MEMORY, rid, sc->lg_res);
return (ENXIO);
}
return (0);
}
static int
rt1310_gpio_detach(device_t dev)
{
return (EBUSY);
}
static device_t
rt1310_gpio_get_bus(device_t dev)
{
struct rt1310_gpio_softc *sc;
sc = device_get_softc(dev);
return (sc->lg_busdev);
}
static int
rt1310_gpio_pin_max(device_t dev, int *npins)
{
*npins = RT_GPIO_NPINS - 1;
return (0);
}
static int
rt1310_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
{
const struct rt1310_gpio_pinmap *map;
if (pin > RT_GPIO_NPINS)
return (ENODEV);
map = rt1310_gpio_get_pinmap(pin);
*caps = map->lp_flags;
return (0);
}
static int
rt1310_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
{
struct rt1310_gpio_softc *sc = device_get_softc(dev);
const struct rt1310_gpio_pinmap *map;
uint32_t state;
int dir;
if (pin > RT_GPIO_NPINS)
return (ENODEV);
map = rt1310_gpio_get_pinmap(pin);
/* Check whether it's bidirectional pin */
if ((map->lp_flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) !=
(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) {
*flags = map->lp_flags;
return (0);
}
switch (map->lp_port) {
case RT_GPIO_PORTA:
state = rt1310_gpio_read_4(sc, RT_GPIO_OFF_PADIR);
dir = (state & (1 << RT_GPIO_PIN_BIT(map, pin)));
break;
case RT_GPIO_PORTB:
state = rt1310_gpio_read_4(sc, RT_GPIO_OFF_PBDIR);
dir = (state & (1 << RT_GPIO_PIN_BIT(map, pin)));
break;
default:
panic("unknown GPIO port");
}
*flags = dir ? GPIO_PIN_OUTPUT : GPIO_PIN_INPUT;
return (0);
}
static int
rt1310_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
{
struct rt1310_gpio_softc *sc = device_get_softc(dev);
const struct rt1310_gpio_pinmap *map;
uint32_t dir, state;
uint32_t port;
if (pin > RT_GPIO_NPINS)
return (ENODEV);
map = rt1310_gpio_get_pinmap(pin);
/* Check whether it's bidirectional pin */
if ((map->lp_flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) !=
(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT))
return (ENOTSUP);
if (flags & GPIO_PIN_INPUT)
dir = 0;
if (flags & GPIO_PIN_OUTPUT)
dir = 1;
switch (map->lp_port) {
case RT_GPIO_PORTA:
port = RT_GPIO_OFF_PADIR;
break;
case RT_GPIO_PORTB:
port = RT_GPIO_OFF_PBDIR;
break;
}
state = rt1310_gpio_read_4(sc, port);
if (flags & GPIO_PIN_INPUT) {
state &= ~(1 << RT_GPIO_PIN_IDX(map, pin));
} else {
state |= (1 << RT_GPIO_PIN_IDX(map, pin));
}
rt1310_gpio_write_4(sc, port, state);
return (0);
}
static int
rt1310_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
{
snprintf(name, GPIOMAXNAME - 1, "GPIO_%02d", pin);
return (0);
}
static int
rt1310_gpio_pin_get(device_t dev, uint32_t pin, uint32_t *value)
{
struct rt1310_gpio_softc *sc = device_get_softc(dev);
const struct rt1310_gpio_pinmap *map;
uint32_t state, flags;
int dir;
map = rt1310_gpio_get_pinmap(pin);
if (rt1310_gpio_pin_getflags(dev, pin, &flags))
return (ENXIO);
if (flags & GPIO_PIN_OUTPUT)
dir = 1;
if (flags & GPIO_PIN_INPUT)
dir = 0;
switch (map->lp_port) {
case RT_GPIO_PORTA:
state = rt1310_gpio_read_4(sc, RT_GPIO_OFF_PADR);
*value = !!(state & (1 << RT_GPIO_PIN_BIT(map, pin)));
break;
case RT_GPIO_PORTB:
state = rt1310_gpio_read_4(sc, RT_GPIO_OFF_PBDR);
*value = !!(state & (1 << RT_GPIO_PIN_BIT(map, pin)));
break;
}
return (0);
}
static int
rt1310_gpio_pin_set(device_t dev, uint32_t pin, uint32_t value)
{
struct rt1310_gpio_softc *sc = device_get_softc(dev);
const struct rt1310_gpio_pinmap *map;
uint32_t state, flags;
uint32_t port;
map = rt1310_gpio_get_pinmap(pin);
if (rt1310_gpio_pin_getflags(dev, pin, &flags))
return (ENXIO);
if ((flags & GPIO_PIN_OUTPUT) == 0)
return (EINVAL);
switch (map->lp_port) {
case RT_GPIO_PORTA:
port = RT_GPIO_OFF_PADR;
break;
case RT_GPIO_PORTB:
port = RT_GPIO_OFF_PBDR;
break;
}
state = rt1310_gpio_read_4(sc, port);
if (value == 1) {
state |= (1 << RT_GPIO_PIN_BIT(map, pin));
} else {
state &= ~(1 << RT_GPIO_PIN_BIT(map, pin));
}
rt1310_gpio_write_4(sc, port, state);
return (0);
}
static int
rt1310_gpio_pin_toggle(device_t dev, uint32_t pin)
{
const struct rt1310_gpio_pinmap *map;
uint32_t flags;
map = rt1310_gpio_get_pinmap(pin);
if (rt1310_gpio_pin_getflags(dev, pin, &flags))
return (ENXIO);
if ((flags & GPIO_PIN_OUTPUT) == 0)
return (EINVAL);
panic("not implemented yet");
return (0);
}
static const struct rt1310_gpio_pinmap *
rt1310_gpio_get_pinmap(int pin)
{
const struct rt1310_gpio_pinmap *map;
for (map = &rt1310_gpio_pins[0]; map->lp_start_idx != -1; map++) {
if (pin >= map->lp_start_idx &&
pin < map->lp_start_idx + map->lp_pin_count)
return map;
}
panic("pin number %d out of range", pin);
}
int
rt1310_gpio_set_flags(device_t dev, int pin, int flags)
{
if (rt1310_gpio_sc == NULL)
return (ENXIO);
return rt1310_gpio_pin_setflags(rt1310_gpio_sc->lg_dev, pin, flags);
}
int
rt1310_gpio_set_state(device_t dev, int pin, int state)
{
if (rt1310_gpio_sc == NULL)
return (ENXIO);
return rt1310_gpio_pin_set(rt1310_gpio_sc->lg_dev, pin, state);
}
int
rt1310_gpio_get_state(device_t dev, int pin, int *state)
{
if (rt1310_gpio_sc == NULL)
return (ENXIO);
return rt1310_gpio_pin_get(rt1310_gpio_sc->lg_dev, pin, state);
}
static phandle_t
rt1310_gpio_get_node(device_t bus, device_t dev)
{
/* We only have one child, the GPIO bus, which needs our own node. */
return (ofw_bus_get_node(bus));
}
static device_method_t rt1310_gpio_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, rt1310_gpio_probe),
DEVMETHOD(device_attach, rt1310_gpio_attach),
DEVMETHOD(device_detach, rt1310_gpio_detach),
/* GPIO interface */
DEVMETHOD(gpio_get_bus, rt1310_gpio_get_bus),
DEVMETHOD(gpio_pin_max, rt1310_gpio_pin_max),
DEVMETHOD(gpio_pin_getcaps, rt1310_gpio_pin_getcaps),
DEVMETHOD(gpio_pin_getflags, rt1310_gpio_pin_getflags),
DEVMETHOD(gpio_pin_setflags, rt1310_gpio_pin_setflags),
DEVMETHOD(gpio_pin_getname, rt1310_gpio_pin_getname),
DEVMETHOD(gpio_pin_set, rt1310_gpio_pin_set),
DEVMETHOD(gpio_pin_get, rt1310_gpio_pin_get),
DEVMETHOD(gpio_pin_toggle, rt1310_gpio_pin_toggle),
/* ofw_bus interface */
DEVMETHOD(ofw_bus_get_node, rt1310_gpio_get_node),
{ 0, 0 }
};
static devclass_t rt1310_gpio_devclass;
static driver_t rt1310_gpio_driver = {
"gpio",
rt1310_gpio_methods,
sizeof(struct rt1310_gpio_softc),
};
DRIVER_MODULE(rt1310gpio, simplebus, rt1310_gpio_driver, rt1310_gpio_devclass, 0, 0);
MODULE_VERSION(rt1310gpio, 1);

View File

@ -0,0 +1,441 @@
/*-
* Copyright (c) 2010 Jakub Wojciech Klama <jceel@FreeBSD.org>
* Copyright (c) 2015 Hiroki Mori
* 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 "opt_platform.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/types.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/proc.h>
#include <sys/rman.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <vm/pmap.h>
#include <vm/vm_page.h>
#include <vm/vm_extern.h>
#define _ARM32_BUS_DMA_PRIVATE
#include <machine/bus.h>
#include <machine/intr.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <arm/ralink/rt1310reg.h>
#define INTC_NIRQS 32
#ifdef INTRNG
#include "pic_if.h"
struct rt1310_irqsrc {
struct intr_irqsrc ri_isrc;
u_int ri_irq;
};
#endif
struct rt1310_intc_softc {
device_t dev;
struct resource * ri_res;
bus_space_tag_t ri_bst;
bus_space_handle_t ri_bsh;
#ifdef INTRNG
struct rt1310_irqsrc ri_isrcs[INTC_NIRQS];
#endif
};
static int rt1310_intc_probe(device_t);
static int rt1310_intc_attach(device_t);
#ifndef INTRNG
static void rt1310_intc_eoi(void *);
#else
static int rt1310_pic_attach(struct rt1310_intc_softc *sc);
#endif
static struct rt1310_intc_softc *intc_softc = NULL;
#define intc_read_4(_sc, _reg) \
bus_space_read_4((_sc)->ri_bst, (_sc)->ri_bsh, (_reg))
#define intc_write_4(_sc, _reg, _val) \
bus_space_write_4((_sc)->ri_bst, (_sc)->ri_bsh, (_reg), (_val))
struct rt1310_irqdef {
u_int ri_trig;
u_int ri_prio;
};
struct rt1310_irqdef irqdef[INTC_NIRQS] = {
{RT_INTC_TRIG_HIGH_LVL, 2}, /* 0 */
{RT_INTC_TRIG_HIGH_LVL, 2},
{RT_INTC_TRIG_HIGH_LVL, 2},
{RT_INTC_TRIG_HIGH_LVL, 1},
{RT_INTC_TRIG_HIGH_LVL, 2},
{RT_INTC_TRIG_HIGH_LVL, 1},
{RT_INTC_TRIG_HIGH_LVL, 1},
{RT_INTC_TRIG_HIGH_LVL, 1},
{RT_INTC_TRIG_HIGH_LVL, 1}, /* 8 */
{RT_INTC_TRIG_HIGH_LVL, 1},
{RT_INTC_TRIG_HIGH_LVL, 2},
{RT_INTC_TRIG_LOW_LVL, 2},
{RT_INTC_TRIG_LOW_LVL, 2},
{RT_INTC_TRIG_LOW_LVL, 4},
{RT_INTC_TRIG_HIGH_LVL, 2},
{RT_INTC_TRIG_HIGH_LVL, 2},
{RT_INTC_TRIG_HIGH_LVL, 2}, /* 16 */
{RT_INTC_TRIG_HIGH_LVL, 2},
{RT_INTC_TRIG_LOW_LVL, 2},
{RT_INTC_TRIG_LOW_LVL, 2},
{RT_INTC_TRIG_LOW_LVL, 2},
{RT_INTC_TRIG_LOW_LVL, 2},
{RT_INTC_TRIG_NEG_EDGE, 2},
{RT_INTC_TRIG_HIGH_LVL, 3},
{RT_INTC_TRIG_HIGH_LVL, 2}, /* 24 */
{RT_INTC_TRIG_POS_EDGE, 2},
{RT_INTC_TRIG_POS_EDGE, 2},
{RT_INTC_TRIG_HIGH_LVL, 2},
{RT_INTC_TRIG_HIGH_LVL, 2},
{RT_INTC_TRIG_POS_EDGE, 2},
{RT_INTC_TRIG_POS_EDGE, 3},
{RT_INTC_TRIG_POS_EDGE, 3},
};
static int
rt1310_intc_probe(device_t dev)
{
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (!ofw_bus_is_compatible(dev, "rt,pic"))
return (ENXIO);
#ifdef INTRNG
device_set_desc(dev, "RT1310 INTRNG Interrupt Controller");
#else
device_set_desc(dev, "RT1310 Interrupt Controller");
#endif
return (BUS_PROBE_DEFAULT);
}
static int
rt1310_intc_attach(device_t dev)
{
struct rt1310_intc_softc *sc = device_get_softc(dev);
int rid = 0;
int i;
if (intc_softc)
return (ENXIO);
sc->dev = dev;
sc->ri_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (!sc->ri_res) {
device_printf(dev, "could not alloc resources\n");
return (ENXIO);
}
sc->ri_bst = rman_get_bustag(sc->ri_res);
sc->ri_bsh = rman_get_bushandle(sc->ri_res);
intc_softc = sc;
#ifndef INTRNG
arm_post_filter = rt1310_intc_eoi;
#else
rt1310_pic_attach(sc);
#endif
intc_write_4(sc, RT_INTC_IECR, 0);
intc_write_4(sc, RT_INTC_ICCR, ~0);
for (i = 0; i <= INTC_NIRQS; ++i) {
intc_write_4(sc, RT_INTC_SCR0+i*4,
(irqdef[i].ri_trig << RT_INTC_TRIG_SHIF) |
irqdef[i].ri_prio);
intc_write_4(sc, RT_INTC_SVR0+i*4, i);
}
/* Clear interrupt status registers and disable all interrupts */
intc_write_4(sc, RT_INTC_ICCR, ~0);
intc_write_4(sc, RT_INTC_IMR, 0);
return (0);
}
#ifndef INTRNG
int
arm_get_next_irq(int last)
{
struct rt1310_intc_softc *sc = intc_softc;
uint32_t value;
int i;
value = intc_read_4(sc, RT_INTC_IPR);
for (i = 0; i < 32; i++) {
if (value & (1 << i))
return (i);
}
return (-1);
}
void
arm_mask_irq(uintptr_t nb)
{
struct rt1310_intc_softc *sc = intc_softc;
uint32_t value;
/* Make sure that interrupt isn't active already */
rt1310_intc_eoi((void *)nb);
/* Clear bit in ER register */
value = intc_read_4(sc, RT_INTC_IECR);
value &= ~(1 << nb);
intc_write_4(sc, RT_INTC_IECR, value);
intc_write_4(sc, RT_INTC_IMR, value);
intc_write_4(sc, RT_INTC_ICCR, 1 << nb);
}
void
arm_unmask_irq(uintptr_t nb)
{
struct rt1310_intc_softc *sc = intc_softc;
uint32_t value;
value = intc_read_4(sc, RT_INTC_IECR);
value |= (1 << nb);
intc_write_4(sc, RT_INTC_IMR, value);
intc_write_4(sc, RT_INTC_IECR, value);
}
static void
rt1310_intc_eoi(void *data)
{
struct rt1310_intc_softc *sc = intc_softc;
int nb = (int)data;
intc_write_4(sc, RT_INTC_ICCR, 1 << nb);
if (nb == 0) {
uint32_t value;
value = intc_read_4(sc, RT_INTC_IECR);
value &= ~(1 << nb);
intc_write_4(sc, RT_INTC_IECR, value);
intc_write_4(sc, RT_INTC_IMR, value);
}
}
#else
static void
rt1310_enable_intr(device_t dev, struct intr_irqsrc *isrc)
{
u_int irq;
unsigned int value;
struct rt1310_intc_softc *sc;
sc = intc_softc;
irq = ((struct rt1310_irqsrc *)isrc)->ri_irq;
value = intc_read_4(sc, RT_INTC_IECR);
value |= (1 << irq);
intc_write_4(sc, RT_INTC_IMR, value);
intc_write_4(sc, RT_INTC_IECR, value);
}
static void
rt1310_disable_intr(device_t dev, struct intr_irqsrc *isrc)
{
u_int irq;
unsigned int value;
struct rt1310_intc_softc *sc;
sc = intc_softc;
irq = ((struct rt1310_irqsrc *)isrc)->ri_irq;
/* Clear bit in ER register */
value = intc_read_4(sc, RT_INTC_IECR);
value &= ~(1 << irq);
intc_write_4(sc, RT_INTC_IECR, value);
intc_write_4(sc, RT_INTC_IMR, value);
intc_write_4(sc, RT_INTC_ICCR, 1 << irq);
}
static int
rt1310_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
struct intr_map_data_fdt *daf;
struct rt1310_intc_softc *sc;
if (data->type != INTR_MAP_DATA_FDT)
return (ENOTSUP);
daf = (struct intr_map_data_fdt *)data;
if (daf->ncells != 1 || daf->cells[0] >= INTC_NIRQS)
return (EINVAL);
sc = device_get_softc(dev);
*isrcp = &sc->ri_isrcs[daf->cells[0]].ri_isrc;
return (0);
}
static void
rt1310_pre_ithread(device_t dev, struct intr_irqsrc *isrc)
{
arm_irq_memory_barrier(0);
rt1310_disable_intr(dev, isrc);
}
static void
rt1310_post_ithread(device_t dev, struct intr_irqsrc *isrc)
{
arm_irq_memory_barrier(0);
rt1310_enable_intr(dev, isrc);
}
static void
rt1310_post_filter(device_t dev, struct intr_irqsrc *isrc)
{
u_int irq;
struct rt1310_intc_softc *sc;
arm_irq_memory_barrier(0);
sc = intc_softc;
irq = ((struct rt1310_irqsrc *)isrc)->ri_irq;
intc_write_4(sc, RT_INTC_ICCR, 1 << irq);
}
static int
rt1310_intr(void *arg)
{
uint32_t irq;
struct rt1310_intc_softc *sc = arg;
irq = ffs(intc_read_4(sc, RT_INTC_IPR)) - 1;
if (intr_isrc_dispatch(&sc->ri_isrcs[irq].ri_isrc,
curthread->td_intr_frame) != 0) {
intc_write_4(sc, RT_INTC_ICCR, 1 << irq);
device_printf(sc->dev, "Stray irq %u disabled\n", irq);
}
arm_irq_memory_barrier(0);
return (FILTER_HANDLED);
}
static int
rt1310_pic_attach(struct rt1310_intc_softc *sc)
{
struct intr_pic *pic;
int error;
uint32_t irq;
const char *name;
intptr_t xref;
name = device_get_nameunit(sc->dev);
for (irq = 0; irq < INTC_NIRQS; irq++) {
sc->ri_isrcs[irq].ri_irq = irq;
error = intr_isrc_register(&sc->ri_isrcs[irq].ri_isrc,
sc->dev, 0, "%s,%u", name, irq);
if (error != 0)
return (error);
}
xref = OF_xref_from_node(ofw_bus_get_node(sc->dev));
pic = intr_pic_register(sc->dev, xref);
if (pic == NULL)
return (ENXIO);
return (intr_pic_claim_root(sc->dev, xref, rt1310_intr, sc, 0));
}
#endif
struct fdt_fixup_entry fdt_fixup_table[] = {
{ NULL, NULL }
};
#ifndef INTRNG
static int
fdt_pic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
int *pol)
{
if (!fdt_is_compatible(node, "lpc,pic"))
return (ENXIO);
*interrupt = fdt32_to_cpu(intr[0]);
*trig = INTR_TRIGGER_CONFORM;
*pol = INTR_POLARITY_CONFORM;
return (0);
}
fdt_pic_decode_t fdt_pic_table[] = {
&fdt_pic_decode_ic,
NULL
};
#endif
static device_method_t rt1310_intc_methods[] = {
DEVMETHOD(device_probe, rt1310_intc_probe),
DEVMETHOD(device_attach, rt1310_intc_attach),
#ifdef INTRNG
DEVMETHOD(pic_disable_intr, rt1310_disable_intr),
DEVMETHOD(pic_enable_intr, rt1310_enable_intr),
DEVMETHOD(pic_map_intr, rt1310_map_intr),
DEVMETHOD(pic_post_filter, rt1310_post_filter),
DEVMETHOD(pic_post_ithread, rt1310_post_ithread),
DEVMETHOD(pic_pre_ithread, rt1310_pre_ithread),
#endif
{ 0, 0 }
};
static driver_t rt1310_intc_driver = {
"pic",
rt1310_intc_methods,
sizeof(struct rt1310_intc_softc),
};
static devclass_t rt1310_intc_devclass;
EARLY_DRIVER_MODULE(pic, simplebus, rt1310_intc_driver, rt1310_intc_devclass, 0, 0, BUS_PASS_INTERRUPT);

View File

@ -0,0 +1,176 @@
/*-
* Copyright (c) 1994-1998 Mark Brinicombe.
* Copyright (c) 1994 Brini.
* All rights reserved.
*
* This code is derived from software written for Brini by Mark Brinicombe
*
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Brini.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
*
* from: FreeBSD: sys/arm/lpc/lpc_machdep.c
*/
#include "opt_ddb.h"
#include "opt_platform.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#define _ARM32_BUS_DMA_PRIVATE
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/reboot.h>
#include <sys/devmap.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/bus.h>
#include <machine/fdt.h>
#include <machine/machdep.h>
#include <machine/platform.h>
#include <machine/cpu.h>
#include <arm/ralink/rt1310reg.h>
#include <arm/ralink/rt1310var.h>
#include <dev/fdt/fdt_common.h>
#ifdef EARLY_PRINTF
early_putc_t *early_putc;
#endif
uint32_t rt1310_master_clock;
vm_offset_t
platform_lastaddr(void)
{
return (devmap_lastaddr());
}
void
platform_probe_and_attach(void)
{
}
void
platform_gpio_init(void)
{
/*
* Set initial values of GPIO output ports
*/
}
void
platform_late_init(void)
{
bootverbose = 1;
}
/*
* Add a single static device mapping.
* The values used were taken from the ranges property of the SoC node in the
* dts file when this code was converted to arm_devmap_add_entry().
*/
int
platform_devmap_init(void)
{
devmap_add_entry(0x19C00000, 0xE0000);
devmap_add_entry(0x1e800000, 0x800000);
devmap_add_entry(0x1f000000, 0x400000);
return (0);
}
struct arm32_dma_range *
bus_dma_get_range(void)
{
return (NULL);
}
int
bus_dma_get_range_nb(void)
{
return (0);
}
void
cpu_reset(void)
{
bus_space_tag_t bst;
bus_space_handle_t bsh;
bst = fdtbus_bs_tag;
/* Enable WDT */
/* Instant assert of RESETOUT_N with pulse length 1ms */
bus_space_map(bst, 0x1e8c0000, 0x20000, 0, &bsh);
bus_space_write_4(bst, bsh, 0, 13000);
bus_space_write_4(bst, bsh, 8, (1<<3) | (1<<4) | 7);
bus_space_unmap(bst, bsh, 0x20000);
for (;;)
continue;
}
#ifdef RALINK_BOOT_DEBUG
void bootdebug1(int c);
void bootdebug1(int c)
{
/* direct put uart physical address */
uint8_t* uart_base_addr=(uint8_t*)0x1e840000;
*(uart_base_addr) = c;
}
void bootdebug2(int c);
void bootdebug2(int c)
{
#if defined(SOCDEV_PA) && defined(SOCDEV_VA)
/* direct put uart map address at locore-v4.S */
uint8_t* uart_base_addr=(uint8_t*)0xce840000;
*(uart_base_addr) = c;
#endif
}
void bootdebug3(int c);
void bootdebug3(int c)
{
bus_space_tag_t bst;
bus_space_handle_t bsh;
bst = fdtbus_bs_tag;
bus_space_map(bst, 0x1e840000, 0x20000, 0, &bsh);
bus_space_write_1(bst, bsh, 0, c);
bus_space_unmap(bst, bsh, 0x20000);
}
#endif

View File

@ -0,0 +1,341 @@
/*-
* Copyright (c) 2011 Jakub Wojciech Klama <jceel@FreeBSD.org>
* Copyright (c) 2015 Hiroki Mori
* 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/kernel.h>
#include <sys/module.h>
#include <sys/malloc.h>
#include <sys/rman.h>
#include <sys/timetc.h>
#include <sys/timeet.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/intr.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <arm/ralink/rt1310reg.h>
#include <arm/ralink/rt1310var.h>
struct rt1310_timer_softc {
device_t lt_dev;
struct eventtimer lt_et;
struct resource * lt_res[8];
bus_space_tag_t lt_bst0;
bus_space_handle_t lt_bsh0;
bus_space_tag_t lt_bst1;
bus_space_handle_t lt_bsh1;
bus_space_tag_t lt_bst2;
bus_space_handle_t lt_bsh2;
bus_space_tag_t lt_bst3;
bus_space_handle_t lt_bsh3;
int lt_oneshot;
uint32_t lt_period;
};
static struct resource_spec rt1310_timer_spec[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
{ SYS_RES_MEMORY, 1, RF_ACTIVE },
{ SYS_RES_MEMORY, 2, RF_ACTIVE },
{ SYS_RES_MEMORY, 3, RF_ACTIVE },
{ SYS_RES_IRQ, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 1, RF_ACTIVE },
{ SYS_RES_IRQ, 2, RF_ACTIVE },
{ -1, 0 }
};
static struct rt1310_timer_softc *timer_softc = NULL;
static int rt1310_timer_initialized = 0;
static int rt1310_timer_probe(device_t);
static int rt1310_timer_attach(device_t);
static int rt1310_timer_start(struct eventtimer *,
sbintime_t first, sbintime_t period);
static int rt1310_timer_stop(struct eventtimer *et);
static unsigned rt1310_get_timecount(struct timecounter *);
static int rt1310_hardclock(void *);
#define timer0_read_4(sc, reg) \
bus_space_read_4(sc->lt_bst0, sc->lt_bsh0, reg)
#define timer0_write_4(sc, reg, val) \
bus_space_write_4(sc->lt_bst0, sc->lt_bsh0, reg, val)
#define timer0_clear(sc) \
do { \
timer0_write_4(sc, RT_TIMER_LOAD, 0); \
timer0_write_4(sc, RT_TIMER_VALUE, 0); \
} while(0)
#define timer1_read_4(sc, reg) \
bus_space_read_4(sc->lt_bst1, sc->lt_bsh1, reg)
#define timer1_write_4(sc, reg, val) \
bus_space_write_4(sc->lt_bst1, sc->lt_bsh1, reg, val)
#define timer1_clear(sc) \
do { \
timer1_write_4(sc, RT_TIMER_LOAD, 0); \
timer1_write_4(sc, RT_TIMER_VALUE, 0); \
} while(0)
#define timer2_read_4(sc, reg) \
bus_space_read_4(sc->lt_bst1, sc->lt_bsh2, reg)
#define timer2_write_4(sc, reg, val) \
bus_space_write_4(sc->lt_bst2, sc->lt_bsh2, reg, val)
#define timer3_write_4(sc, reg, val) \
bus_space_write_4(sc->lt_bst3, sc->lt_bsh3, reg, val)
static struct timecounter rt1310_timecounter = {
.tc_get_timecount = rt1310_get_timecount,
.tc_name = "RT1310ATimer1",
.tc_frequency = 0, /* will be filled later */
.tc_counter_mask = ~0u,
.tc_quality = 1000,
};
static int
rt1310_timer_probe(device_t dev)
{
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (!ofw_bus_is_compatible(dev, "rt,timer"))
return (ENXIO);
device_set_desc(dev, "RT1310 timer");
return (BUS_PROBE_DEFAULT);
}
static int
rt1310_timer_attach(device_t dev)
{
void *intrcookie;
struct rt1310_timer_softc *sc = device_get_softc(dev);
phandle_t node;
uint32_t freq;
if (timer_softc)
return (ENXIO);
timer_softc = sc;
if (bus_alloc_resources(dev, rt1310_timer_spec, sc->lt_res)) {
device_printf(dev, "could not allocate resources\n");
return (ENXIO);
}
sc->lt_bst0 = rman_get_bustag(sc->lt_res[0]);
sc->lt_bsh0 = rman_get_bushandle(sc->lt_res[0]);
sc->lt_bst1 = rman_get_bustag(sc->lt_res[1]);
sc->lt_bsh1 = rman_get_bushandle(sc->lt_res[1]);
sc->lt_bst2 = rman_get_bustag(sc->lt_res[2]);
sc->lt_bsh2 = rman_get_bushandle(sc->lt_res[2]);
sc->lt_bst3 = rman_get_bustag(sc->lt_res[3]);
sc->lt_bsh3 = rman_get_bushandle(sc->lt_res[3]);
/* Timer2 interrupt */
if (bus_setup_intr(dev, sc->lt_res[6], INTR_TYPE_CLK,
rt1310_hardclock, NULL, sc, &intrcookie)) {
device_printf(dev, "could not setup interrupt handler\n");
bus_release_resources(dev, rt1310_timer_spec, sc->lt_res);
return (ENXIO);
}
/* Enable timer clock */
/*
rt1310_pwr_write(dev, LPC_CLKPWR_TIMCLK_CTRL1,
LPC_CLKPWR_TIMCLK_CTRL1_TIMER0 |
LPC_CLKPWR_TIMCLK_CTRL1_TIMER1);
*/
/* Get PERIPH_CLK encoded in parent bus 'bus-frequency' property */
node = ofw_bus_get_node(dev);
if (OF_getprop(OF_parent(node), "bus-frequency", &freq,
sizeof(pcell_t)) <= 0) {
bus_release_resources(dev, rt1310_timer_spec, sc->lt_res);
bus_teardown_intr(dev, sc->lt_res[2], intrcookie);
device_printf(dev, "could not obtain base clock frequency\n");
return (ENXIO);
}
freq = fdt32_to_cpu(freq);
/* Set desired frequency in event timer and timecounter */
sc->lt_et.et_frequency = (uint64_t)freq;
rt1310_timecounter.tc_frequency = (uint64_t)freq;
sc->lt_et.et_name = "RT1310ATimer2";
sc->lt_et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT;
sc->lt_et.et_quality = 1000;
sc->lt_et.et_min_period = (0x00000002LLU << 32) / sc->lt_et.et_frequency;
sc->lt_et.et_max_period = (0xfffffffeLLU << 32) / sc->lt_et.et_frequency;
sc->lt_et.et_start = rt1310_timer_start;
sc->lt_et.et_stop = rt1310_timer_stop;
sc->lt_et.et_priv = sc;
et_register(&sc->lt_et);
tc_init(&rt1310_timecounter);
/* Reset and enable timecounter */
timer0_write_4(sc, RT_TIMER_CONTROL, 0);
timer1_write_4(sc, RT_TIMER_CONTROL, 0);
timer2_write_4(sc, RT_TIMER_CONTROL, 0);
timer3_write_4(sc, RT_TIMER_CONTROL, 0);
timer1_write_4(sc, RT_TIMER_LOAD, ~0);
timer1_write_4(sc, RT_TIMER_VALUE, ~0);
timer1_write_4(sc, RT_TIMER_CONTROL,
RT_TIMER_CTRL_ENABLE | RT_TIMER_CTRL_PERIODCAL);
/* DELAY() now can work properly */
rt1310_timer_initialized = 1;
return (0);
}
static int
rt1310_timer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
{
struct rt1310_timer_softc *sc = (struct rt1310_timer_softc *)et->et_priv;
uint32_t ticks;
if (period == 0) {
sc->lt_oneshot = 1;
sc->lt_period = 0;
} else {
sc->lt_oneshot = 0;
sc->lt_period = ((uint32_t)et->et_frequency * period) >> 32;
}
if (first == 0)
ticks = sc->lt_period;
else
ticks = ((uint32_t)et->et_frequency * first) >> 32;
/* Reset timer */
timer2_write_4(sc, RT_TIMER_CONTROL, 0);
/* Start timer */
timer2_write_4(sc, RT_TIMER_LOAD, ticks);
timer2_write_4(sc, RT_TIMER_VALUE, ticks);
timer2_write_4(sc, RT_TIMER_CONTROL,
RT_TIMER_CTRL_ENABLE | RT_TIMER_CTRL_INTCTL);
return (0);
}
static int
rt1310_timer_stop(struct eventtimer *et)
{
struct rt1310_timer_softc *sc = (struct rt1310_timer_softc *)et->et_priv;
timer2_write_4(sc, RT_TIMER_CONTROL, 0);
return (0);
}
static device_method_t rt1310_timer_methods[] = {
DEVMETHOD(device_probe, rt1310_timer_probe),
DEVMETHOD(device_attach, rt1310_timer_attach),
{ 0, 0 }
};
static driver_t rt1310_timer_driver = {
"timer",
rt1310_timer_methods,
sizeof(struct rt1310_timer_softc),
};
static devclass_t rt1310_timer_devclass;
EARLY_DRIVER_MODULE(timer, simplebus, rt1310_timer_driver, rt1310_timer_devclass, 0, 0, BUS_PASS_TIMER);
static int
rt1310_hardclock(void *arg)
{
struct rt1310_timer_softc *sc = (struct rt1310_timer_softc *)arg;
/* Reset pending interrupt */
timer2_write_4(sc, RT_TIMER_CONTROL,
timer2_read_4(sc, RT_TIMER_CONTROL) | 0x08);
timer2_write_4(sc, RT_TIMER_CONTROL,
timer2_read_4(sc, RT_TIMER_CONTROL) & 0x1fb);
/* Start timer again */
if (!sc->lt_oneshot) {
timer2_write_4(sc, RT_TIMER_LOAD, sc->lt_period);
timer2_write_4(sc, RT_TIMER_VALUE, sc->lt_period);
timer2_write_4(sc, RT_TIMER_CONTROL,
RT_TIMER_CTRL_ENABLE | RT_TIMER_CTRL_INTCTL);
}
if (sc->lt_et.et_active)
sc->lt_et.et_event_cb(&sc->lt_et, sc->lt_et.et_arg);
return (FILTER_HANDLED);
}
static unsigned
rt1310_get_timecount(struct timecounter *tc)
{
return ~timer1_read_4(timer_softc, RT_TIMER_VALUE);
}
void
DELAY(int usec)
{
uint32_t counter;
uint32_t first, last;
int val = (rt1310_timecounter.tc_frequency / 1000000 + 1) * usec;
/* Timer is not initialized yet */
if (!rt1310_timer_initialized) {
for (; usec > 0; usec--)
for (counter = 100; counter > 0; counter--)
;
return;
}
first = rt1310_get_timecount(&rt1310_timecounter);
while (val > 0) {
last = rt1310_get_timecount(&rt1310_timecounter);
if (last < first) {
/* Timer rolled over */
last = first;
}
val -= (last - first);
first = last;
}
}

View File

@ -0,0 +1,82 @@
/*-
* Copyright (c) 2011 Jakub Wojciech Klama <jceel@FreeBSD.org>
* Copyright (c) 2015 Hiroki Mori
* 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 _ARM_RALINK_RT1310REG_H
#define _ARM_RALINK_RT1310REG_H
/*
* Interrupt controller
*/
#define RT_INTC_SCR0 0x00
#define RT_INTC_SVR0 0x80
#define RT_INTC_ISR 0x104
#define RT_INTC_IPR 0x108
#define RT_INTC_IMR 0x10c
#define RT_INTC_IECR 0x114
#define RT_INTC_ICCR 0x118
#define RT_INTC_TRIG_LOW_LVL (0)
#define RT_INTC_TRIG_HIGH_LVL (1)
#define RT_INTC_TRIG_NEG_EDGE (2)
#define RT_INTC_TRIG_POS_EDGE (3)
#define RT_INTC_TRIG_SHIF 6
/*
* Timer 0|1|2|3.
*/
#define RT_TIMER_LOAD 0x00
#define RT_TIMER_VALUE 0x04
#define RT_TIMER_CONTROL 0x08
#define RT_TIMER_CTRL_INTCTL (1 << 1)
#define RT_TIMER_CTRL_INTCLR (1 << 2)
#define RT_TIMER_CTRL_INTMASK (1 << 3)
#define RT_TIMER_CTRL_DIV16 (3 << 4)
#define RT_TIMER_CTRL_DIV256 (7 << 4)
#define RT_TIMER_CTRL_PERIODCAL (1 << 7)
#define RT_TIMER_CTRL_ENABLE (1 << 8)
#define RT_TIMER_INTERVAL (5000*150)
/*
* GPIO
*/
#define RT_GPIO_PORTA (0)
#define RT_GPIO_PORTB (1)
#define RT_GPIO_OFF_PADR (0x0)
#define RT_GPIO_OFF_PADIR (0x4)
#define RT_GPIO_OFF_PBDR (0x8)
#define RT_GPIO_OFF_PBDIR (0xC)
#endif /* _ARM_RALINK_RT1310REG_H */

View File

@ -0,0 +1,71 @@
/*-
* Copyright (c) 2011 Jakub Wojciech Klama <jceel@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.
*
* $FreeBSD$
*/
#ifndef _ARM_RT_RTVAR_H
#define _ARM_RT_RTVAR_H
#include <sys/types.h>
#include <sys/bus.h>
#include <machine/bus.h>
/* Clocking and power control */
uint32_t lpc_pwr_read(device_t, int);
void lpc_pwr_write(device_t, int, uint32_t);
/* GPIO */
void rt1310_gpio_init(void);
int rt1310_gpio_set_flags(device_t, int, int);
int rt1310_gpio_set_state(device_t, int, int);
int rt1310_gpio_get_state(device_t, int, int *);
/* DMA */
struct lpc_dmac_channel_config
{
int ldc_fcntl;
int ldc_src_periph;
int ldc_src_width;
int ldc_src_incr;
int ldc_src_burst;
int ldc_dst_periph;
int ldc_dst_width;
int ldc_dst_incr;
int ldc_dst_burst;
void (*ldc_success_handler)(void *);
void (*ldc_error_handler)(void *);
void * ldc_handler_arg;
};
int lpc_dmac_config_channel(device_t, int, struct lpc_dmac_channel_config *);
int lpc_dmac_setup_transfer(device_t, int, bus_addr_t, bus_addr_t, bus_size_t, int);
int lpc_dmac_enable_channel(device_t, int);
int lpc_dmac_disable_channel(device_t, int);
int lpc_dmac_start_burst(device_t, int);
extern uint32_t rt1310_master_clock;
#endif /* _ARM_RT_RTVAR_H */

View File

@ -0,0 +1,159 @@
/*
* Copyright (c) 2011 Jakub Klama <jceel@FreeBSD.org>
* Copyright (c) 2015 Hiroki Mori
*
* 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.
*
* Ralink RT1310A Device Tree Source.
*
* $FreeBSD$
*/
/ {
compatible = "ralink,rt1310a-soc";
#address-cells = <1>;
#size-cells = <1>;
aliases {
serial0 = &serial0;
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
device_type = "cpu";
compatible = "ARM,926EJ-S";
reg = <0x0>;
d-cache-line-size = <32>; // 32 bytes
i-cache-line-size = <32>; // 32 bytes
d-cache-size = <0x4000>; // L1, 16K
i-cache-size = <0x4000>; // L1, 16K
timebase-frequency = <0>;
bus-frequency = <0>;
clock-frequency = <0>;
};
};
memory {
device_type = "memory";
reg = <0x40000000 0x1000000>; // 16M at 0x40000000
};
localbus@1f000000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
ranges = <0x0 0x1f000000 0x400000>;
};
ahb@19C00000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
ranges = <0x0 0x19C00000 0xE0000>;
bus-frequency = <13000000>;
PIC: pic@40000 {
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <1>;
reg = <0x40000 0x20000>;
compatible = "rt,pic";
};
fvmdio@0 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fv,mdio";
reg = <0x80000 0x20000>;
};
enet0:fv_mac0@80000 {
compatible = "fv,ethernet";
reg = <0x80000 0x20000>;
interrupts = <7>;
interrupt-parent = <&PIC>;
};
enet1:fv_mac1@A0000 {
compatible = "fv,ethernet";
reg = <0xA0000 0x20000>;
interrupts = <8>;
interrupt-parent = <&PIC>;
};
};
apb@1E800000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
ranges = <0x0 0x1E800000 0x800000>;
bus-frequency = <75000000>;
timer@000000 {
compatible = "rt,timer";
reg = <0x0 0x10
0x10 0x10
0x20 0x10
0x30 0x10>;
interrupts = <3 4 5>;
interrupt-parent = <&PIC>;
};
rtc@20000 {
compatible = "rt,rtc";
interrupts = <6>;
reg = <0x20000 0x20000>;
};
serial0: serial@40000 {
compatible = "ns16550";
reg = <0x40000 0x20000>;
interrupts = <1>;
reg-shift = <2>;
clock-frequency = <6758400>;
current-speed = <38400>;
interrupt-parent = <&PIC>;
};
gpio0: gpio@A0000 {
compatible = "ralink,rt1310-gpio";
gpio-controller;
#gpio-cells = <2>;
interrupts = <8>;
reg = <0xA0000 0x20000>;
};
};
/*
chosen {
stdin = "serial0";
stdout = "serial0";
};
*/
};

View File

@ -0,0 +1,92 @@
/*
* Copyright (c) 2015 Hiroki Mori
*
* 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.
*
* Buffalo WZR2-G300N Device Tree Source.
*
* $FreeBSD$
*/
/dts-v1/;
#include "rt1310a.dtsi"
/ {
compatible = "WZR2-G300N", "ralink,rt1310a-soc";
model = "WZR2-G300N";
flash@1f000000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "cfi-flash";
reg = <0x1f000000 0x400000>; // 4M at 0x1f000000
partition@0 {
reg = <0x00000000 0x0000e000>;
label = "uboot";
};
partition@1 {
reg = <0x0000e000 0x00002000>;
label = "uboot_env";
};
partition@2 {
reg = <0x00010000 0x000f0000>;
label = "kernel";
};
partition@3 {
reg = <0x00100000 0x002d0000>;
label = "rootfs";
};
partition@4 {
reg = <0x003d0000 0x00010000>;
label = "config";
};
partition@5 {
reg = <0x00010000 0x003c0000>;
label = "upgrade";
};
};
gpio-leds {
compatible = "gpio-leds";
status {
label = "status";
gpios = <&gpio0 4 0>;
};
};
ip17x@0 {
compatible = "icplus,ip17x";
mii-poll = <0>;
};
};
&enet0 {
local-mac-address = [ 00 1a f1 01 1f 23 ];
};
&enet1 {
local-mac-address = [ 00 1a f1 01 1f 24 ];
};