Merging of projects/armv6, part 10

- Support for Texas Instruments SoCs:
	- AM335x
	- OMAP4

- Kernel configs, DTS for Beaglebone and Pandaboard

Submitted by:	Ben Gray, Damjan Marion
This commit is contained in:
Oleksandr Tymoshenko 2012-08-15 06:31:32 +00:00
parent 9dfe4a1fa4
commit e53470fee3
66 changed files with 19775 additions and 0 deletions

126
sys/arm/conf/BEAGLEBONE Normal file
View File

@ -0,0 +1,126 @@
# BEAGLEBONE -- Custom configuration for the BeagleBone ARM development
# platform, check out http://www.beagleboard.org/bone
#
# For more information on this file, please read the handbook section on
# Kernel Configuration Files:
#
# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
#
# The handbook is also available locally in /usr/share/doc/handbook
# if you've installed the doc distribution, otherwise always see the
# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
# latest information.
#
# An exhaustive list of options and more detailed explanations of the
# device lines is also present in the ../../conf/NOTES and NOTES files.
# If you are in doubt as to the purpose or necessity of a line, check first
# in NOTES.
#
# $FreeBSD$
ident BEAGLEBONE
include "../ti/am335x/std.beaglebone"
makeoptions MODULES_OVERRIDE=""
makeoptions WITHOUT_MODULES="ahc"
options HZ=100
options SCHED_4BSD #4BSD scheduler
options INET #InterNETworking
options INET6 #IPv6 communications protocols
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 MSDOSFS #MSDOS Filesystem
options CD9660 #ISO 9660 Filesystem
options PROCFS #Process filesystem (requires PSEUDOFS)
options PSEUDOFS #Pseudo-filesystem framework
options COMPAT_43 #Compatible with BSD 4.3 [KEEP THIS!]
options SCSI_DELAY=5000 #Delay (in ms) before probing SCSI
options KTRACE #ktrace(1) support
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 KBD_INSTALL_CDEV # install a CDEV entry in /dev
options PREEMPTION
# Debugging
makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
options BREAK_TO_DEBUGGER
#options VERBOSE_SYSINIT #Enable verbose sysinit messages
options KDB
options DDB #Enable the kernel debugger
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
# NFS support
#options NFSCL
#options NFSSERVER #Network Filesystem Server
#options NFSCLIENT #Network Filesystem Client
# Uncomment this for NFS root
#options NFS_ROOT #NFS usable as /, requires NFSCLIENT
#options BOOTP_NFSROOT
#options BOOTP_COMPAT
#options BOOTP
#options BOOTP_NFSV3
#options BOOTP_WIRED_TO=cpsw0
# MMC/SD/SDIO card slot support
device mmc # mmc/sd bus
device mmcsd # mmc/sd flash cards
# Boot device is 2nd slice on MMC/SD card
options ROOTDEVNAME=\"ufs:mmcsd0s2\"
# Console and misc
device uart
device uart_ns8250
device pty
device snp
device md
device random # Entropy device
# I2C support
device iicbus
device iic
device ti_i2c
device am335x_pmic # AM335x Power Management IC (TPC65217)
# GPIO
device gpio
# USB support
device usb
options USB_DEBUG
#options USB_REQ_DEBUG
#options USB_VERBOSE
device musb
device umass
device scbus # SCSI bus (required for SCSI)
device da # Direct Access (disks)
# Ethernet
device loop
device ether
device mii
device smscphy
device cpsw
device bpf
# USB ethernet support, requires miibus
device miibus
device axe # ASIX Electronics USB Ethernet
# Flattened Device Tree
options FDT
options FDT_DTB_STATIC
makeoptions FDT_DTS_FILE=beaglebone.dts

144
sys/arm/conf/PANDABOARD Normal file
View File

@ -0,0 +1,144 @@
# PANDABOARD -- Custom configuration for the PandaBoard ARM development
# platform, check out www.pandaboard.org
#
# For more information on this file, please read the handbook section on
# Kernel Configuration Files:
#
# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
#
# The handbook is also available locally in /usr/share/doc/handbook
# if you've installed the doc distribution, otherwise always see the
# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
# latest information.
#
# An exhaustive list of options and more detailed explanations of the
# device lines is also present in the ../../conf/NOTES and NOTES files.
# If you are in doubt as to the purpose or necessity of a line, check first
# in NOTES.
#
# $FreeBSD$
ident PANDABOARD
# This probably wants to move somewhere else. Maybe we can create a basic
# OMAP4340 config, then make a PANDABOARD config that includes the basic one,
# adds the start addresses and custom devices plus pulls in this hints file.
hints "PANDABOARD.hints"
include "../ti/omap4/pandaboard/std.pandaboard"
#To statically compile in device wiring instead of /boot/device.hints
makeoptions MODULES_OVERRIDE=""
makeoptions WITHOUT_MODULES="ahc"
makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
options HZ=100
options SCHED_4BSD #4BSD scheduler
options INET #InterNETworking
#options INET6 #IPv6 communications protocols
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 NFSCLIENT #Network Filesystem Client
device snp
#options NFSCL
#options NFSSERVER #Network Filesystem Server
options NFS_ROOT #NFS usable as /, requires NFSCLIENT
options BREAK_TO_DEBUGGER
options BOOTP_NFSROOT
options BOOTP_COMPAT
options BOOTP
options BOOTP_NFSV3
options BOOTP_WIRED_TO=ue0
options MSDOSFS #MSDOS Filesystem
#options CD9660 #ISO 9660 Filesystem
#options PROCFS #Process filesystem (requires PSEUDOFS)
options PSEUDOFS #Pseudo-filesystem framework
options COMPAT_43 #Compatible with BSD 4.3 [KEEP THIS!]
options SCSI_DELAY=5000 #Delay (in ms) before probing SCSI
options KTRACE #ktrace(1) support
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 KBD_INSTALL_CDEV # install a CDEV entry in /dev
options PREEMPTION
# MMC/SD/SDIO Card slot support
device mmc # mmc/sd bus
device mmcsd # mmc/sd flash cards
# I2C support
device iicbus
device iic
device ti_i2c
device loop
device ether
device mii
device smc
device smcphy
device uart
device uart_ns8250
device gpio
device pty
device pl310 # PL310 L2 cache controller
# Debugging for use in -current
#options VERBOSE_SYSINIT #Enable verbose sysinit messages
options KDB
options DDB #Enable the kernel debugger
#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
device md
# The following enables MFS as root, this seems similar to an initramfs or initrd
# as used in Linux.
# options MD_ROOT
# options MD_ROOT_SIZE=7560
device random # Entropy device
# USB support
device usb
options USB_DEBUG
#options USB_REQ_DEBUG
#options USB_VERBOSE
device ohci
device ehci
device umass
device scbus # SCSI bus (required for SCSI)
device da # Direct Access (disks)
# USB Ethernet support, requires miibus
device miibus
# device axe # ASIX Electronics USB Ethernet
device smsc # SMSC LAN95xx USB Ethernet
# OMAP-specific devices
device ti_sdma
device twl
device twl_vreg
device twl_clks
# Flattened Device Tree
options FDT
options FDT_DTB_STATIC
makeoptions FDT_DTS_FILE=pandaboard.dts
# device vfp # vfp/neon
# options ARM_VFP_SUPPORT # vfp/neon

View File

@ -0,0 +1,61 @@
# $FreeBSD$
# USB ECHI
#
# TI OMAP Power Management and System Companion Device sitting on the I2C bus
# hint.tps65950.0.at="iicbus0"
# hint.tps65950.0.addr=0xd0
#
# Defines the GPIO pin used to detect the Write Protect stat of the MMC/SD card.
#hint.omap_mmc.0.wp_gpio="23"
#
# If 'phy_reset" is set, then the accompaning PHY is reset using one of the
# GPIO pins. If the reset GPIO pin is not -1 then the pin will be toggled when
# the USB driver is loaded.
hint.ehci.0.phy_reset="0"
#
# Sets the PHY mode for the individual ports, the following values are allowed
# - EHCI_HCD_OMAP3_MODE_UNKNOWN 0
# - EHCI_HCD_OMAP3_MODE_PHY 1
# - EHCI_HCD_OMAP3_MODE_TLL 2
hint.ehci.0.phy_mode_0="1"
hint.ehci.0.phy_mode_1="0"
hint.ehci.0.phy_mode_2="0"
#
# If specified the value indicates a pin that is toggled as a heart-beat. The
# heart beat pusle is triggered every 500ms using the system tick timer.
hint.omap_clk.0.heartbeat_gpio="150"
#
# Padconf (pinmux) settings - typically this would be set by the boot-loader
# but can be overridden here. These hints are applied to the H/W when the
# SCM module is initialised.
#
# The format is:
# hint.omap_scm.0.padconf.<padname>=<muxmode:options>
#
# Where the options can be one of the following:
# output, input, input_pullup, input_pulldown
#
# Setup the pin settings for the HS USB Host (PHY mode)
hint.omap4.0.padconf.ag19="usbb1_ulpiphy_stp:output"
hint.omap4.0.padconf.ae18="usbb1_ulpiphy_clk:input_pulldown"
hint.omap4.0.padconf.af19="usbb1_ulpiphy_dir:input_pulldown"
hint.omap4.0.padconf.ae19="usbb1_ulpiphy_nxt:input_pulldown"
hint.omap4.0.padconf.af18="usbb1_ulpiphy_dat0:input_pulldown"
hint.omap4.0.padconf.ag18="usbb1_ulpiphy_dat1:input_pulldown"
hint.omap4.0.padconf.ae17="usbb1_ulpiphy_dat2:input_pulldown"
hint.omap4.0.padconf.af17="usbb1_ulpiphy_dat3:input_pulldown"
hint.omap4.0.padconf.ah17="usbb1_ulpiphy_dat4:input_pulldown"
hint.omap4.0.padconf.ae16="usbb1_ulpiphy_dat5:input_pulldown"
hint.omap4.0.padconf.af16="usbb1_ulpiphy_dat6:input_pulldown"
hint.omap4.0.padconf.ag16="usbb1_ulpiphy_dat7:input_pulldown"

179
sys/arm/ti/aintc.c Normal file
View File

@ -0,0 +1,179 @@
/*-
* Copyright (c) 2012 Damjan Marion <dmarion@Freebsd.org>
* All rights reserved.
*
* Based on OMAP3 INTC code by Ben Gray
*
* 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/ktr.h>
#include <sys/module.h>
#include <sys/rman.h>
#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>
#define INTC_REVISION 0x00
#define INTC_SYSCONFIG 0x10
#define INTC_SYSSTATUS 0x14
#define INTC_SIR_IRQ 0x40
#define INTC_CONTROL 0x48
#define INTC_THRESHOLD 0x68
#define INTC_MIR_CLEAR(x) (0x88 + ((x) * 0x20))
#define INTC_MIR_SET(x) (0x8C + ((x) * 0x20))
#define INTC_ISR_SET(x) (0x90 + ((x) * 0x20))
#define INTC_ISR_CLEAR(x) (0x94 + ((x) * 0x20))
struct ti_aintc_softc {
device_t sc_dev;
struct resource * aintc_res[3];
bus_space_tag_t aintc_bst;
bus_space_handle_t aintc_bsh;
uint8_t ver;
};
static struct resource_spec ti_aintc_spec[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
{ -1, 0 }
};
static struct ti_aintc_softc *ti_aintc_sc = NULL;
#define aintc_read_4(reg) \
bus_space_read_4(ti_aintc_sc->aintc_bst, ti_aintc_sc->aintc_bsh, reg)
#define aintc_write_4(reg, val) \
bus_space_write_4(ti_aintc_sc->aintc_bst, ti_aintc_sc->aintc_bsh, reg, val)
static int
ti_aintc_probe(device_t dev)
{
if (!ofw_bus_is_compatible(dev, "ti,aintc"))
return (ENXIO);
device_set_desc(dev, "TI AINTC Interrupt Controller");
return (BUS_PROBE_DEFAULT);
}
static int
ti_aintc_attach(device_t dev)
{
struct ti_aintc_softc *sc = device_get_softc(dev);
uint32_t x;
sc->sc_dev = dev;
if (ti_aintc_sc)
return (ENXIO);
if (bus_alloc_resources(dev, ti_aintc_spec, sc->aintc_res)) {
device_printf(dev, "could not allocate resources\n");
return (ENXIO);
}
sc->aintc_bst = rman_get_bustag(sc->aintc_res[0]);
sc->aintc_bsh = rman_get_bushandle(sc->aintc_res[0]);
ti_aintc_sc = sc;
x = aintc_read_4(INTC_REVISION);
device_printf(dev, "Revision %u.%u\n",(x >> 4) & 0xF, x & 0xF);
/* SoftReset */
aintc_write_4(INTC_SYSCONFIG, 2);
/* Wait for reset to complete */
while(!(aintc_read_4(INTC_SYSSTATUS) & 1));
/*Set Priority Threshold */
aintc_write_4(INTC_THRESHOLD, 0xFF);
return (0);
}
static device_method_t ti_aintc_methods[] = {
DEVMETHOD(device_probe, ti_aintc_probe),
DEVMETHOD(device_attach, ti_aintc_attach),
{ 0, 0 }
};
static driver_t ti_aintc_driver = {
"aintc",
ti_aintc_methods,
sizeof(struct ti_aintc_softc),
};
static devclass_t ti_aintc_devclass;
DRIVER_MODULE(aintc, simplebus, ti_aintc_driver, ti_aintc_devclass, 0, 0);
int
arm_get_next_irq(int last_irq)
{
uint32_t active_irq;
if (last_irq != -1) {
aintc_write_4(INTC_ISR_CLEAR(last_irq >> 5),
1UL << (last_irq & 0x1F));
aintc_write_4(INTC_CONTROL,1);
}
/* Get the next active interrupt */
active_irq = aintc_read_4(INTC_SIR_IRQ);
/* Check for spurious interrupt */
if ((active_irq & 0xffffff80)) {
device_printf(ti_aintc_sc->sc_dev,
"Spurious interrupt detected (0x%08x)\n", active_irq);
return -1;
}
if (active_irq != last_irq)
return active_irq;
else
return -1;
}
void
arm_mask_irq(uintptr_t nb)
{
aintc_write_4(INTC_MIR_SET(nb >> 5), (1UL << (nb & 0x1F)));
}
void
arm_unmask_irq(uintptr_t nb)
{
aintc_write_4(INTC_MIR_CLEAR(nb >> 5), (1UL << (nb & 0x1F)));
}

View File

@ -0,0 +1,385 @@
/*-
* Copyright (c) 2012 Damjan Marion <dmarion@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.
*/
#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/timeet.h>
#include <sys/timetc.h>
#include <sys/watchdog.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/frame.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 <machine/bus.h>
#include <machine/fdt.h>
#include <arm/ti/ti_prcm.h>
#define AM335X_NUM_TIMERS 8
#define DMTIMER_TIDR 0x00 /* Identification Register */
#define DMTIMER_TIOCP_CFG 0x10 /* Timer OCP Configuration Reg */
#define DMTIMER_IQR_EOI 0x20 /* Timer IRQ End-Of-Interrupt Reg */
#define DMTIMER_IRQSTATUS_RAW 0x24 /* Timer IRQSTATUS Raw Reg */
#define DMTIMER_IRQSTATUS 0x28 /* Timer IRQSTATUS Reg */
#define DMTIMER_IRQENABLE_SET 0x2c /* Timer IRQSTATUS Set Reg */
#define DMTIMER_IRQENABLE_CLR 0x30 /* Timer IRQSTATUS Clear Reg */
#define DMTIMER_IRQWAKEEN 0x34 /* Timer IRQ Wakeup Enable Reg */
#define DMTIMER_TCLR 0x38 /* Timer Control Register */
#define DMTIMER_TCRR 0x3C /* Timer Counter Register */
#define DMTIMER_TLDR 0x40 /* Timer Load Reg */
#define DMTIMER_TTGR 0x44 /* Timer Trigger Reg */
#define DMTIMER_TWPS 0x48 /* Timer Write Posted Status Reg */
#define DMTIMER_TMAR 0x4C /* Timer Match Reg */
#define DMTIMER_TCAR1 0x50 /* Timer Capture Reg */
#define DMTIMER_TSICR 0x54 /* Timer Synchr. Interface Control Reg */
#define DMTIMER_TCAR2 0x48 /* Timer Capture Reg */
struct am335x_dmtimer_softc {
struct resource * tmr_mem_res[AM335X_NUM_TIMERS];
struct resource * tmr_irq_res[AM335X_NUM_TIMERS];
uint32_t sysclk_freq;
struct am335x_dmtimer {
bus_space_tag_t bst;
bus_space_handle_t bsh;
struct eventtimer et;
} t[AM335X_NUM_TIMERS];
};
static struct resource_spec am335x_dmtimer_mem_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_MEMORY, 4, RF_ACTIVE },
{ SYS_RES_MEMORY, 5, RF_ACTIVE },
{ SYS_RES_MEMORY, 6, RF_ACTIVE },
{ SYS_RES_MEMORY, 7, RF_ACTIVE },
{ -1, 0, 0 }
};
static struct resource_spec am335x_dmtimer_irq_spec[] = {
{ SYS_RES_IRQ, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 1, RF_ACTIVE },
{ SYS_RES_IRQ, 2, RF_ACTIVE },
{ SYS_RES_IRQ, 3, RF_ACTIVE },
{ SYS_RES_IRQ, 4, RF_ACTIVE },
{ SYS_RES_IRQ, 5, RF_ACTIVE },
{ SYS_RES_IRQ, 6, RF_ACTIVE },
{ SYS_RES_IRQ, 7, RF_ACTIVE },
{ -1, 0, 0 }
};
static struct am335x_dmtimer *am335x_dmtimer_tc_tmr = NULL;
/* Read/Write macros for Timer used as timecounter */
#define am335x_dmtimer_tc_read_4(reg) \
bus_space_read_4(am335x_dmtimer_tc_tmr->bst, \
am335x_dmtimer_tc_tmr->bsh, reg)
#define am335x_dmtimer_tc_write_4(reg, val) \
bus_space_write_4(am335x_dmtimer_tc_tmr->bst, \
am335x_dmtimer_tc_tmr->bsh, reg, val)
/* Read/Write macros for Timer used as eventtimer */
#define am335x_dmtimer_et_read_4(reg) \
bus_space_read_4(tmr->bst, tmr->bsh, reg)
#define am335x_dmtimer_et_write_4(reg, val) \
bus_space_write_4(tmr->bst, tmr->bsh, reg, val)
static unsigned am335x_dmtimer_tc_get_timecount(struct timecounter *);
static struct timecounter am335x_dmtimer_tc = {
.tc_name = "AM335x Timecouter",
.tc_get_timecount = am335x_dmtimer_tc_get_timecount,
.tc_poll_pps = NULL,
.tc_counter_mask = ~0u,
.tc_frequency = 0,
.tc_quality = 1000,
};
static unsigned
am335x_dmtimer_tc_get_timecount(struct timecounter *tc)
{
return am335x_dmtimer_tc_read_4(DMTIMER_TCRR);
}
static int
am335x_dmtimer_start(struct eventtimer *et, struct bintime *first,
struct bintime *period)
{
struct am335x_dmtimer *tmr = (struct am335x_dmtimer *)et->et_priv;
uint32_t load, count;
uint32_t tclr = 0;
if (period != NULL) {
load = (et->et_frequency * (period->frac >> 32)) >> 32;
if (period->sec > 0)
load += et->et_frequency * period->sec;
tclr |= 2; /* autoreload bit */
panic("periodic timer not implemented\n");
} else {
load = 0;
}
if (first != NULL) {
count = (tmr->et.et_frequency * (first->frac >> 32)) >> 32;
if (first->sec != 0)
count += tmr->et.et_frequency * first->sec;
} else {
count = load;
}
/* Reset Timer */
am335x_dmtimer_et_write_4(DMTIMER_TSICR, 2);
/* Wait for reset to complete */
while (am335x_dmtimer_et_read_4(DMTIMER_TIOCP_CFG) & 1);
/* set load value */
am335x_dmtimer_et_write_4(DMTIMER_TLDR, 0xFFFFFFFE - load);
/* set counter value */
am335x_dmtimer_et_write_4(DMTIMER_TCRR, 0xFFFFFFFE - count);
/* enable overflow interrupt */
am335x_dmtimer_et_write_4(DMTIMER_IRQENABLE_SET, 2);
/* start timer(ST) */
tclr |= 1;
am335x_dmtimer_et_write_4(DMTIMER_TCLR, tclr);
return (0);
}
static int
am335x_dmtimer_stop(struct eventtimer *et)
{
struct am335x_dmtimer *tmr = (struct am335x_dmtimer *)et->et_priv;
/* Disable all interrupts */
am335x_dmtimer_et_write_4(DMTIMER_IRQENABLE_CLR, 7);
/* Stop Timer */
am335x_dmtimer_et_write_4(DMTIMER_TCLR, 0);
return (0);
}
static int
am335x_dmtimer_intr(void *arg)
{
struct am335x_dmtimer *tmr = (struct am335x_dmtimer *)arg;
/* Ack interrupt */
am335x_dmtimer_et_write_4(DMTIMER_IRQSTATUS, 7);
if (tmr->et.et_active)
tmr->et.et_event_cb(&tmr->et, tmr->et.et_arg);
return (FILTER_HANDLED);
}
static int
am335x_dmtimer_probe(device_t dev)
{
struct am335x_dmtimer_softc *sc;
sc = (struct am335x_dmtimer_softc *)device_get_softc(dev);
if (ofw_bus_is_compatible(dev, "ti,am335x-dmtimer")) {
device_set_desc(dev, "AM335x DMTimer");
return(BUS_PROBE_DEFAULT);
}
return (ENXIO);
}
static int
am335x_dmtimer_attach(device_t dev)
{
struct am335x_dmtimer_softc *sc = device_get_softc(dev);
void *ihl;
int err;
int i;
if (am335x_dmtimer_tc_tmr != NULL)
return (EINVAL);
/* Get the base clock frequency */
err = ti_prcm_clk_get_source_freq(SYS_CLK, &sc->sysclk_freq);
if (err) {
device_printf(dev, "Error: could not get sysclk frequency\n");
return (ENXIO);
}
/* Request the memory resources */
err = bus_alloc_resources(dev, am335x_dmtimer_mem_spec,
sc->tmr_mem_res);
if (err) {
device_printf(dev, "Error: could not allocate mem resources\n");
return (ENXIO);
}
/* Request the IRQ resources */
err = bus_alloc_resources(dev, am335x_dmtimer_irq_spec,
sc->tmr_irq_res);
if (err) {
device_printf(dev, "Error: could not allocate irq resources\n");
return (ENXIO);
}
for(i=0;i<AM335X_NUM_TIMERS;i++) {
sc->t[i].bst = rman_get_bustag(sc->tmr_mem_res[i]);
sc->t[i].bsh = rman_get_bushandle(sc->tmr_mem_res[i]);
}
/* Configure DMTimer2 and DMTimer3 source and enable them */
err = ti_prcm_clk_set_source(DMTIMER2_CLK, SYSCLK_CLK);
err |= ti_prcm_clk_enable(DMTIMER2_CLK);
err |= ti_prcm_clk_set_source(DMTIMER3_CLK, SYSCLK_CLK);
err |= ti_prcm_clk_enable(DMTIMER3_CLK);
if (err) {
device_printf(dev, "Error: could not setup timer clock\n");
return (ENXIO);
}
/* Take DMTimer2 for TC */
am335x_dmtimer_tc_tmr = &sc->t[2];
/* Reset Timer */
am335x_dmtimer_tc_write_4(DMTIMER_TSICR, 2);
/* Wait for reset to complete */
while (am335x_dmtimer_tc_read_4(DMTIMER_TIOCP_CFG) & 1);
/* set load value */
am335x_dmtimer_tc_write_4(DMTIMER_TLDR, 0);
/* set counter value */
am335x_dmtimer_tc_write_4(DMTIMER_TCRR, 0);
/* Set Timer autoreload(AR) and start timer(ST) */
am335x_dmtimer_tc_write_4(DMTIMER_TCLR, 3);
am335x_dmtimer_tc.tc_frequency = sc->sysclk_freq;
tc_init(&am335x_dmtimer_tc);
/* Register DMTimer3 as ET */
/* Setup and enable the timer */
if (bus_setup_intr(dev, sc->tmr_irq_res[3], INTR_TYPE_CLK,
am335x_dmtimer_intr, NULL, &sc->t[3], &ihl) != 0) {
bus_release_resources(dev, am335x_dmtimer_irq_spec,
sc->tmr_irq_res);
device_printf(dev, "Unable to setup the clock irq handler.\n");
return (ENXIO);
}
sc->t[3].et.et_name = "AM335x Eventtimer0";
sc->t[3].et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT;
sc->t[3].et.et_quality = 1000;
sc->t[3].et.et_frequency = sc->sysclk_freq;
sc->t[3].et.et_min_period.sec = 0;
sc->t[3].et.et_min_period.frac =
((0x00000002LLU << 32) / sc->t[3].et.et_frequency) << 32;
sc->t[3].et.et_max_period.sec = 0xfffffff0U / sc->t[3].et.et_frequency;
sc->t[3].et.et_max_period.frac =
((0xfffffffeLLU << 32) / sc->t[3].et.et_frequency) << 32;
sc->t[3].et.et_start = am335x_dmtimer_start;
sc->t[3].et.et_stop = am335x_dmtimer_stop;
sc->t[3].et.et_priv = &sc->t[3];
et_register(&sc->t[3].et);
return (0);
}
static device_method_t am335x_dmtimer_methods[] = {
DEVMETHOD(device_probe, am335x_dmtimer_probe),
DEVMETHOD(device_attach, am335x_dmtimer_attach),
{ 0, 0 }
};
static driver_t am335x_dmtimer_driver = {
"am335x_dmtimer",
am335x_dmtimer_methods,
sizeof(struct am335x_dmtimer_softc),
};
static devclass_t am335x_dmtimer_devclass;
DRIVER_MODULE(am335x_dmtimer, simplebus, am335x_dmtimer_driver, am335x_dmtimer_devclass, 0, 0);
MODULE_DEPEND(am335x_dmtimer, am335x_prcm, 1, 1, 1);
void
cpu_initclocks(void)
{
cpu_initclocks_bsp();
}
void
DELAY(int usec)
{
int32_t counts;
uint32_t first, last;
if (am335x_dmtimer_tc_tmr == NULL) {
for (; usec > 0; usec--)
for (counts = 200; counts > 0; counts--)
/* Prevent gcc from optimizing out the loop */
cpufunc_nullop();
return;
}
/* Get the number of times to count */
counts = usec * ((am335x_dmtimer_tc.tc_frequency / 1000000) + 1);;
first = am335x_dmtimer_tc_read_4(DMTIMER_TCRR);
while (counts > 0) {
last = am335x_dmtimer_tc_read_4(DMTIMER_TCRR);
if (last>first) {
counts -= (int32_t)(last - first);
} else {
counts -= (int32_t)((0xFFFFFFFF - first) + last);
}
first = last;
}
}

View File

@ -0,0 +1,176 @@
/*-
* Copyright (c) 2012 Damjan Marion <dmarion@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.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* TPS65217 PMIC companion chip for AM335x SoC sitting on I2C bus
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/clock.h>
#include <sys/time.h>
#include <sys/bus.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <dev/iicbus/iicbus.h>
#include <dev/iicbus/iiconf.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include "iicbus_if.h"
#define TPS65217A 0x7
#define TPS65217B 0xF
/* TPS65217 Reisters */
#define TPS65217_CHIPID_REG 0x00
#define TPS65217_STATUS_REG 0x0A
#define MAX_IIC_DATA_SIZE 2
struct am335x_pmic_softc {
device_t sc_dev;
uint32_t sc_addr;
struct intr_config_hook enum_hook;
};
static int
am335x_pmic_read(device_t dev, uint8_t addr, uint8_t *data, uint8_t size)
{
struct am335x_pmic_softc *sc = device_get_softc(dev);
struct iic_msg msg[] = {
{ sc->sc_addr, IIC_M_WR, 1, &addr },
{ sc->sc_addr, IIC_M_RD, size, data },
};
return (iicbus_transfer(dev, msg, 2));
}
#ifdef notyet
static int
am335x_pmic_write(device_t dev, uint8_t address, uint8_t *data, uint8_t size)
{
uint8_t buffer[MAX_IIC_DATA_SIZE + 1];
struct am335x_pmic_softc *sc = device_get_softc(dev);
struct iic_msg msg[] = {
{ sc->sc_addr, IIC_M_WR, size + 1, buffer },
};
if (size > MAX_IIC_DATA_SIZE)
return (ENOMEM);
buffer[0] = address;
memcpy(buffer + 1, data, size);
return (iicbus_transfer(dev, msg, 1));
}
#endif
static int
am335x_pmic_probe(device_t dev)
{
struct am335x_pmic_softc *sc;
if (!ofw_bus_is_compatible(dev, "ti,am335x-pmic"))
return (ENXIO);
sc = device_get_softc(dev);
sc->sc_dev = dev;
sc->sc_addr = iicbus_get_addr(dev);
device_set_desc(dev, "TI TPS65217 Power Management IC");
return (0);
}
static void
am335x_pmic_start(void *xdev)
{
struct am335x_pmic_softc *sc;
device_t dev = (device_t)xdev;
uint8_t reg;
char name[20];
char pwr[4][11] = {"Unknown", "USB", "AC", "USB and AC"};
sc = device_get_softc(dev);
am335x_pmic_read(dev, TPS65217_CHIPID_REG, &reg, 1);
switch (reg>>4) {
case TPS65217A:
sprintf(name, "TPS65217A ver 1.%u", reg & 0xF);
break;
case TPS65217B:
sprintf(name, "TPS65217B ver 1.%u", reg & 0xF);
break;
default:
sprintf(name, "Unknown PMIC");
}
am335x_pmic_read(dev, TPS65217_STATUS_REG, &reg, 1);
device_printf(dev, "%s powered by %s\n", name, pwr[(reg>>2)&0x03]);
config_intrhook_disestablish(&sc->enum_hook);
}
static int
am335x_pmic_attach(device_t dev)
{
struct am335x_pmic_softc *sc;
sc = device_get_softc(dev);
sc->enum_hook.ich_func = am335x_pmic_start;
sc->enum_hook.ich_arg = dev;
if (config_intrhook_establish(&sc->enum_hook) != 0)
return (ENOMEM);
return (0);
}
static device_method_t am335x_pmic_methods[] = {
DEVMETHOD(device_probe, am335x_pmic_probe),
DEVMETHOD(device_attach, am335x_pmic_attach),
{0, 0},
};
static driver_t am335x_pmic_driver = {
"am335x_pmic",
am335x_pmic_methods,
sizeof(struct am335x_pmic_softc),
};
static devclass_t am335x_pmic_devclass;
DRIVER_MODULE(am335x_pmic, iicbus, am335x_pmic_driver, am335x_pmic_devclass, 0, 0);
MODULE_VERSION(am335x_pmic, 1);
MODULE_DEPEND(am335x_pmic, iicbus, 1, 1, 1);

View File

@ -0,0 +1,568 @@
/*-
* Copyright (c) 2012 Damjan Marion <dmarion@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.
*/
#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/timeet.h>
#include <sys/timetc.h>
#include <sys/watchdog.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/frame.h>
#include <machine/intr.h>
#include <arm/ti/tivar.h>
#include <arm/ti/ti_scm.h>
#include <arm/ti/ti_prcm.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 <machine/bus.h>
#include <machine/fdt.h>
#define CM_PER 0
#define CM_PER_L4LS_CLKSTCTRL (CM_PER + 0x000)
#define CM_PER_L3S_CLKSTCTRL (CM_PER + 0x004)
#define CM_PER_L3_CLKSTCTRL (CM_PER + 0x00C)
#define CM_PER_CPGMAC0_CLKCTRL (CM_PER + 0x014)
#define CM_PER_USB0_CLKCTRL (CM_PER + 0x01C)
#define CM_PER_TPTC0_CLKCTRL (CM_PER + 0x024)
#define CM_PER_MMC0_CLKCTRL (CM_PER + 0x03C)
#define CM_PER_I2C2_CLKCTRL (CM_PER + 0x044)
#define CM_PER_I2C1_CLKCTRL (CM_PER + 0x048)
#define CM_PER_TIMER7_CLKCTRL (CM_PER + 0x07C)
#define CM_PER_TIMER2_CLKCTRL (CM_PER + 0x080)
#define CM_PER_TIMER3_CLKCTRL (CM_PER + 0x084)
#define CM_PER_TIMER4_CLKCTRL (CM_PER + 0x088)
#define CM_PER_GPIO1_CLKCTRL (CM_PER + 0x0AC)
#define CM_PER_GPIO2_CLKCTRL (CM_PER + 0x0B0)
#define CM_PER_GPIO3_CLKCTRL (CM_PER + 0x0B4)
#define CM_PER_TPCC_CLKCTRL (CM_PER + 0x0BC)
#define CM_PER_L3_INSTR_CLKCTRL (CM_PER + 0x0DC)
#define CM_PER_L3_CLKCTRL (CM_PER + 0x0E0)
#define CM_PER_TIMER5_CLKCTRL (CM_PER + 0x0EC)
#define CM_PER_TIMER6_CLKCTRL (CM_PER + 0x0F0)
#define CM_PER_MMC1_CLKCTRL (CM_PER + 0x0F4)
#define CM_PER_MMC2_CLKCTRL (CM_PER + 0x0F8)
#define CM_PER_TPTC1_CLKCTRL (CM_PER + 0x0FC)
#define CM_PER_TPTC2_CLKCTRL (CM_PER + 0x100)
#define CM_PER_OCPWP_L3_CLKSTCTRL (CM_PER + 0x12C)
#define CM_PER_OCPWP_CLKCTRL (CM_PER + 0x130)
#define CM_PER_CPSW_CLKSTCTRL (CM_PER + 0x144)
#define CM_WKUP 0x400
#define CM_WKUP_CLKSTCTRL (CM_WKUP + 0x000)
#define CM_WKUP_CONTROL_CLKCTRL (CM_WKUP + 0x004)
#define CM_WKUP_GPIO0_CLKCTRL (CM_WKUP + 0x008)
#define CM_WKUP_CM_L3_AON_CLKSTCTRL (CM_WKUP + 0x01C)
#define CM_WKUP_CM_CLKSEL_DPLL_MPU (CM_WKUP + 0x02C)
#define CM_WKUP_CM_CLKDCOLDO_DPLL_PER (CM_WKUP + 0x07C)
#define CM_WKUP_I2C0_CLKCTRL (CM_WKUP + 0x0B8)
#define CM_DPLL 0x500
#define CLKSEL_TIMER7_CLK (CM_DPLL + 0x004)
#define CLKSEL_TIMER2_CLK (CM_DPLL + 0x008)
#define CLKSEL_TIMER3_CLK (CM_DPLL + 0x00C)
#define CLKSEL_TIMER4_CLK (CM_DPLL + 0x010)
#define CLKSEL_TIMER5_CLK (CM_DPLL + 0x018)
#define CLKSEL_TIMER6_CLK (CM_DPLL + 0x01C)
#define PRM_DEVICE_OFFSET 0xF00
#define PRM_RSTCTRL (PRM_DEVICE_OFFSET + 0x00)
struct am335x_prcm_softc {
struct resource * res[2];
bus_space_tag_t bst;
bus_space_handle_t bsh;
};
static struct resource_spec am335x_prcm_spec[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
{ -1, 0 }
};
static struct am335x_prcm_softc *am335x_prcm_sc = NULL;
static int am335x_clk_generic_activate(struct ti_clock_dev *clkdev);
static int am335x_clk_gpio_activate(struct ti_clock_dev *clkdev);
static int am335x_clk_generic_deactivate(struct ti_clock_dev *clkdev);
static int am335x_clk_generic_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
static int am335x_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
static int am335x_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
static int am335x_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
static void am335x_prcm_reset(void);
static int am335x_clk_cpsw_activate(struct ti_clock_dev *clkdev);
static int am335x_clk_musb0_activate(struct ti_clock_dev *clkdev);
#define AM335X_GENERIC_CLOCK_DEV(i) \
{ .id = (i), \
.clk_activate = am335x_clk_generic_activate, \
.clk_deactivate = am335x_clk_generic_deactivate, \
.clk_set_source = am335x_clk_generic_set_source, \
.clk_accessible = NULL, \
.clk_get_source_freq = NULL \
}
#define AM335X_GPIO_CLOCK_DEV(i) \
{ .id = (i), \
.clk_activate = am335x_clk_gpio_activate, \
.clk_deactivate = am335x_clk_generic_deactivate, \
.clk_set_source = am335x_clk_generic_set_source, \
.clk_accessible = NULL, \
.clk_get_source_freq = NULL \
}
#define AM335X_MMCHS_CLOCK_DEV(i) \
{ .id = (i), \
.clk_activate = am335x_clk_generic_activate, \
.clk_deactivate = am335x_clk_generic_deactivate, \
.clk_set_source = am335x_clk_generic_set_source, \
.clk_accessible = NULL, \
.clk_get_source_freq = am335x_clk_hsmmc_get_source_freq \
}
struct ti_clock_dev ti_clk_devmap[] = {
/* System clocks */
{ .id = SYS_CLK,
.clk_activate = NULL,
.clk_deactivate = NULL,
.clk_set_source = NULL,
.clk_accessible = NULL,
.clk_get_source_freq = am335x_clk_get_sysclk_freq,
},
/* MPU (ARM) core clocks */
{ .id = MPU_CLK,
.clk_activate = NULL,
.clk_deactivate = NULL,
.clk_set_source = NULL,
.clk_accessible = NULL,
.clk_get_source_freq = am335x_clk_get_arm_fclk_freq,
},
/* CPSW Ethernet Switch core clocks */
{ .id = CPSW_CLK,
.clk_activate = am335x_clk_cpsw_activate,
.clk_deactivate = NULL,
.clk_set_source = NULL,
.clk_accessible = NULL,
.clk_get_source_freq = NULL,
},
/* Mentor USB HS controller core clocks */
{ .id = MUSB0_CLK,
.clk_activate = am335x_clk_musb0_activate,
.clk_deactivate = NULL,
.clk_set_source = NULL,
.clk_accessible = NULL,
.clk_get_source_freq = NULL,
},
/* DMTimer */
AM335X_GENERIC_CLOCK_DEV(DMTIMER2_CLK),
AM335X_GENERIC_CLOCK_DEV(DMTIMER3_CLK),
AM335X_GENERIC_CLOCK_DEV(DMTIMER4_CLK),
AM335X_GENERIC_CLOCK_DEV(DMTIMER5_CLK),
AM335X_GENERIC_CLOCK_DEV(DMTIMER6_CLK),
AM335X_GENERIC_CLOCK_DEV(DMTIMER7_CLK),
/* GPIO */
AM335X_GPIO_CLOCK_DEV(GPIO0_CLK),
AM335X_GPIO_CLOCK_DEV(GPIO1_CLK),
AM335X_GPIO_CLOCK_DEV(GPIO2_CLK),
AM335X_GPIO_CLOCK_DEV(GPIO3_CLK),
/* I2C */
AM335X_GENERIC_CLOCK_DEV(I2C0_CLK),
AM335X_GENERIC_CLOCK_DEV(I2C1_CLK),
AM335X_GENERIC_CLOCK_DEV(I2C2_CLK),
/* EDMA */
AM335X_GENERIC_CLOCK_DEV(EDMA_TPCC_CLK),
AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC0_CLK),
AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC1_CLK),
AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC2_CLK),
/* MMCHS */
AM335X_MMCHS_CLOCK_DEV(MMC0_CLK),
AM335X_MMCHS_CLOCK_DEV(MMC1_CLK),
AM335X_MMCHS_CLOCK_DEV(MMC2_CLK),
{ INVALID_CLK_IDENT, NULL, NULL, NULL, NULL }
};
struct am335x_clk_details {
clk_ident_t id;
uint32_t clkctrl_reg;
uint32_t clksel_reg;
};
#define _CLK_DETAIL(i, c, s) \
{ .id = (i), \
.clkctrl_reg = (c), \
.clksel_reg = (s), \
}
static struct am335x_clk_details g_am335x_clk_details[] = {
/* DMTimer modules */
_CLK_DETAIL(DMTIMER2_CLK, CM_PER_TIMER2_CLKCTRL, CLKSEL_TIMER2_CLK),
_CLK_DETAIL(DMTIMER3_CLK, CM_PER_TIMER3_CLKCTRL, CLKSEL_TIMER3_CLK),
_CLK_DETAIL(DMTIMER4_CLK, CM_PER_TIMER4_CLKCTRL, CLKSEL_TIMER4_CLK),
_CLK_DETAIL(DMTIMER5_CLK, CM_PER_TIMER5_CLKCTRL, CLKSEL_TIMER5_CLK),
_CLK_DETAIL(DMTIMER6_CLK, CM_PER_TIMER6_CLKCTRL, CLKSEL_TIMER6_CLK),
_CLK_DETAIL(DMTIMER7_CLK, CM_PER_TIMER7_CLKCTRL, CLKSEL_TIMER7_CLK),
/* GPIO modules */
_CLK_DETAIL(GPIO0_CLK, CM_WKUP_GPIO0_CLKCTRL, 0),
_CLK_DETAIL(GPIO1_CLK, CM_PER_GPIO1_CLKCTRL, 0),
_CLK_DETAIL(GPIO2_CLK, CM_PER_GPIO2_CLKCTRL, 0),
_CLK_DETAIL(GPIO3_CLK, CM_PER_GPIO3_CLKCTRL, 0),
/* I2C modules */
_CLK_DETAIL(I2C0_CLK, CM_WKUP_I2C0_CLKCTRL, 0),
_CLK_DETAIL(I2C1_CLK, CM_PER_I2C1_CLKCTRL, 0),
_CLK_DETAIL(I2C2_CLK, CM_PER_I2C2_CLKCTRL, 0),
/* EDMA modules */
_CLK_DETAIL(EDMA_TPCC_CLK, CM_PER_TPCC_CLKCTRL, 0),
_CLK_DETAIL(EDMA_TPTC0_CLK, CM_PER_TPTC0_CLKCTRL, 0),
_CLK_DETAIL(EDMA_TPTC1_CLK, CM_PER_TPTC1_CLKCTRL, 0),
_CLK_DETAIL(EDMA_TPTC2_CLK, CM_PER_TPTC2_CLKCTRL, 0),
/* MMCHS modules*/
_CLK_DETAIL(MMC0_CLK, CM_PER_MMC0_CLKCTRL, 0),
_CLK_DETAIL(MMC1_CLK, CM_PER_MMC1_CLKCTRL, 0),
_CLK_DETAIL(MMC2_CLK, CM_PER_MMC1_CLKCTRL, 0),
{ INVALID_CLK_IDENT, 0},
};
/* Read/Write macros */
#define prcm_read_4(reg) \
bus_space_read_4(am335x_prcm_sc->bst, am335x_prcm_sc->bsh, reg)
#define prcm_write_4(reg, val) \
bus_space_write_4(am335x_prcm_sc->bst, am335x_prcm_sc->bsh, reg, val)
void am335x_prcm_setup_dmtimer(int);
static int
am335x_prcm_probe(device_t dev)
{
if (ofw_bus_is_compatible(dev, "am335x,prcm")) {
device_set_desc(dev, "AM335x Power and Clock Management");
return(BUS_PROBE_DEFAULT);
}
return (ENXIO);
}
static int
am335x_prcm_attach(device_t dev)
{
struct am335x_prcm_softc *sc = device_get_softc(dev);
unsigned int sysclk, fclk;
if (am335x_prcm_sc)
return (ENXIO);
if (bus_alloc_resources(dev, am335x_prcm_spec, sc->res)) {
device_printf(dev, "could not allocate resources\n");
return (ENXIO);
}
sc->bst = rman_get_bustag(sc->res[0]);
sc->bsh = rman_get_bushandle(sc->res[0]);
am335x_prcm_sc = sc;
ti_cpu_reset = am335x_prcm_reset;
am335x_clk_get_sysclk_freq(NULL, &sysclk);
am335x_clk_get_arm_fclk_freq(NULL, &fclk);
device_printf(dev, "Clocks: System %u.%01u MHz, CPU %u MHz\n",
sysclk/1000000, (sysclk % 1000000)/100000, fclk/1000000);
return (0);
}
static device_method_t am335x_prcm_methods[] = {
DEVMETHOD(device_probe, am335x_prcm_probe),
DEVMETHOD(device_attach, am335x_prcm_attach),
{ 0, 0 }
};
static driver_t am335x_prcm_driver = {
"am335x_prcm",
am335x_prcm_methods,
sizeof(struct am335x_prcm_softc),
};
static devclass_t am335x_prcm_devclass;
DRIVER_MODULE(am335x_prcm, simplebus, am335x_prcm_driver,
am335x_prcm_devclass, 0, 0);
MODULE_DEPEND(am335x_prcm, ti_scm, 1, 1, 1);
static struct am335x_clk_details*
am335x_clk_details(clk_ident_t id)
{
struct am335x_clk_details *walker;
for (walker = g_am335x_clk_details; walker->id != INVALID_CLK_IDENT; walker++) {
if (id == walker->id)
return (walker);
}
return NULL;
}
static int
am335x_clk_generic_activate(struct ti_clock_dev *clkdev)
{
struct am335x_prcm_softc *sc = am335x_prcm_sc;
struct am335x_clk_details* clk_details;
if (sc == NULL)
return ENXIO;
clk_details = am335x_clk_details(clkdev->id);
if (clk_details == NULL)
return (ENXIO);
/* set *_CLKCTRL register MODULEMODE[1:0] to enable(2) */
prcm_write_4(clk_details->clkctrl_reg, 2);
while ((prcm_read_4(clk_details->clkctrl_reg) & 0x3) != 2)
DELAY(10);
return (0);
}
static int
am335x_clk_gpio_activate(struct ti_clock_dev *clkdev)
{
struct am335x_prcm_softc *sc = am335x_prcm_sc;
struct am335x_clk_details* clk_details;
if (sc == NULL)
return ENXIO;
clk_details = am335x_clk_details(clkdev->id);
if (clk_details == NULL)
return (ENXIO);
/* set *_CLKCTRL register MODULEMODE[1:0] to enable(2) */
/* set *_CLKCTRL register OPTFCLKEN_GPIO_1_G DBCLK[18] to FCLK_EN(1) */
prcm_write_4(clk_details->clkctrl_reg, 2 | (1 << 18));
while ((prcm_read_4(clk_details->clkctrl_reg) &
(3 | (1 << 18) )) != (2 | (1 << 18)))
DELAY(10);
return (0);
}
static int
am335x_clk_generic_deactivate(struct ti_clock_dev *clkdev)
{
struct am335x_prcm_softc *sc = am335x_prcm_sc;
struct am335x_clk_details* clk_details;
if (sc == NULL)
return ENXIO;
clk_details = am335x_clk_details(clkdev->id);
if (clk_details == NULL)
return (ENXIO);
/* set *_CLKCTRL register MODULEMODE[1:0] to disable(0) */
prcm_write_4(clk_details->clkctrl_reg, 0);
while ((prcm_read_4(clk_details->clkctrl_reg) & 0x3) != 0)
DELAY(10);
return (0);
}
static int
am335x_clk_generic_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc)
{
struct am335x_prcm_softc *sc = am335x_prcm_sc;
struct am335x_clk_details* clk_details;
uint32_t reg;
if (sc == NULL)
return ENXIO;
clk_details = am335x_clk_details(clkdev->id);
if (clk_details == NULL)
return (ENXIO);
switch (clksrc) {
case EXT_CLK:
reg = 0; /* SEL2: TCLKIN clock */
break;
case SYSCLK_CLK:
reg = 1; /* SEL1: CLK_M_OSC clock */
break;
case F32KHZ_CLK:
reg = 2; /* SEL3: CLK_32KHZ clock */
break;
default:
return (ENXIO);
}
prcm_write_4(clk_details->clksel_reg, reg);
while ((prcm_read_4(clk_details->clksel_reg) & 0x3) != reg)
DELAY(10);
return (0);
}
static int
am335x_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq)
{
*freq = 96000000;
return (0);
}
static int
am335x_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq)
{
uint32_t ctrl_status;
/* Read the input clock freq from the control module */
/* control_status reg (0x40) */
if (ti_scm_reg_read_4(0x40, &ctrl_status))
return ENXIO;
switch ((ctrl_status>>22) & 0x3) {
case 0x0:
/* 19.2Mhz */
*freq = 19200000;
break;
case 0x1:
/* 24Mhz */
*freq = 24000000;
break;
case 0x2:
/* 25Mhz */
*freq = 25000000;
break;
case 0x3:
/* 26Mhz */
*freq = 26000000;
break;
}
return (0);
}
static int
am335x_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq)
{
uint32_t reg;
uint32_t sysclk;
#define DPLL_BYP_CLKSEL(reg) ((reg>>23) & 1)
#define DPLL_DIV(reg) ((reg & 0x7f)+1)
#define DPLL_MULT(reg) ((reg>>8) & 0x7FF)
reg = prcm_read_4(CM_WKUP_CM_CLKSEL_DPLL_MPU);
/*Check if we are running in bypass */
if (DPLL_BYP_CLKSEL(reg))
return ENXIO;
am335x_clk_get_sysclk_freq(NULL, &sysclk);
*freq = DPLL_MULT(reg) * (sysclk / DPLL_DIV(reg));
return(0);
}
static void
am335x_prcm_reset(void)
{
prcm_write_4(PRM_RSTCTRL, (1<<1));
}
static int
am335x_clk_cpsw_activate(struct ti_clock_dev *clkdev)
{
struct am335x_prcm_softc *sc = am335x_prcm_sc;
if (sc == NULL)
return ENXIO;
/* set MODULENAME to ENABLE */
prcm_write_4(CM_PER_CPGMAC0_CLKCTRL, 2);
/* wait for IDLEST to become Func(0) */
while(prcm_read_4(CM_PER_CPGMAC0_CLKCTRL) & (3<<16));
/*set CLKTRCTRL to SW_WKUP(2) */
prcm_write_4(CM_PER_CPSW_CLKSTCTRL, 2);
/* wait for 125 MHz OCP clock to become active */
while((prcm_read_4(CM_PER_CPSW_CLKSTCTRL) & (1<<4)) == 0);
return(0);
}
static int
am335x_clk_musb0_activate(struct ti_clock_dev *clkdev)
{
struct am335x_prcm_softc *sc = am335x_prcm_sc;
if (sc == NULL)
return ENXIO;
/* set ST_DPLL_CLKDCOLDO(9) to CLK_GATED(1) */
/* set DPLL_CLKDCOLDO_GATE_CTRL(8) to CLK_ENABLE(1)*/
prcm_write_4(CM_WKUP_CM_CLKDCOLDO_DPLL_PER, 0x300);
/*set MODULEMODE to ENABLE(2) */
prcm_write_4(CM_PER_USB0_CLKCTRL, 2);
/* wait for MODULEMODE to become ENABLE(2) */
while ((prcm_read_4(CM_PER_USB0_CLKCTRL) & 0x3) != 2)
DELAY(10);
/* wait for IDLEST to become Func(0) */
while(prcm_read_4(CM_PER_USB0_CLKCTRL) & (3<<16))
DELAY(10);
return(0);
}

View File

@ -0,0 +1,41 @@
/*-
* Copyright (c) 2012 Damjan Marion <dmarion@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 _AM335X_REG_H_
#define _AM335X_REG_H_
#define AM335X_L4_WKUP_BASE 0x44C00000
#define AM335X_L4_WKUP_SIZE 0x400000
#define AM335X_CONTROL_BASE AM335X_L4_WKUP_BASE + 0x210000
#define AM335X_CONTROL_SIZE 0x2000
#define AM335X_CONTROL_DEVICE_ID 0x0600
#define AM335X_CONTROL_DEV_FEATURE 0x0604
#endif

View File

@ -0,0 +1,373 @@
/*-
* Copyright (c) 2012 Damjan Marion <dmarion@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.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/frame.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <sys/gpio.h>
#include <arm/ti/tivar.h>
#include <arm/ti/ti_scm.h>
#define _PIN(r, b, gp, gm, m0, m1, m2, m3, m4, m5, m6, m7) \
{ .reg_off = r, \
.gpio_pin = gp, \
.gpio_mode = gm, \
.ballname = b, \
.muxmodes[0] = m0, \
.muxmodes[1] = m1, \
.muxmodes[2] = m2, \
.muxmodes[3] = m3, \
.muxmodes[4] = m4, \
.muxmodes[5] = m5, \
.muxmodes[6] = m6, \
.muxmodes[7] = m7, \
}
#define SLEWCTRL (0x01 << 6) /* faster(0) or slower(1) slew rate. */
#define RXACTIVE (0x01 << 5) /* Input enable value for the Pad */
#define PULLTYPESEL (0x01 << 4) /* Pad pullup/pulldown type selection */
#define PULLUDEN (0x01 << 3) /* Pullup/pulldown disabled */
#define PADCONF_OUTPUT (0)
#define PADCONF_OUTPUT_PULLUP (PULLTYPESEL)
#define PADCONF_INPUT (RXACTIVE | PULLUDEN)
#define PADCONF_INPUT_PULLUP (RXACTIVE | PULLTYPESEL)
#define PADCONF_INPUT_PULLDOWN (RXACTIVE)
#define PADCONF_INPUT_PULLUP_SLOW (PADCONF_INPUT_PULLUP | SLEWCTRL)
const struct ti_scm_padstate ti_padstate_devmap[] = {
{"output", PADCONF_OUTPUT },
{"output_pullup", PADCONF_OUTPUT_PULLUP },
{"input", PADCONF_INPUT },
{"input_pulldown", PADCONF_INPUT_PULLDOWN },
{"input_pullup", PADCONF_INPUT_PULLUP },
{"i2c", PADCONF_INPUT_PULLUP_SLOW },
{ .state = NULL }
};
const struct ti_scm_padconf ti_padconf_devmap[] = {
_PIN(0x800, "GPMC_AD0", 32, 7,"gpmc_ad0", "mmc1_dat0", NULL, NULL, NULL, NULL, NULL, "gpio1_0"),
_PIN(0x804, "GPMC_AD1", 33, 7,"gpmc_ad1", "mmc1_dat1", NULL, NULL, NULL, NULL, NULL, "gpio1_1"),
_PIN(0x808, "GPMC_AD2", 34, 7,"gpmc_ad2", "mmc1_dat2", NULL, NULL, NULL, NULL, NULL, "gpio1_2"),
_PIN(0x80C, "GPMC_AD3", 35, 7,"gpmc_ad3", "mmc1_dat3", NULL, NULL, NULL, NULL, NULL, "gpio1_3"),
_PIN(0x810, "GPMC_AD4", 36, 7,"gpmc_ad4", "mmc1_dat4", NULL, NULL, NULL, NULL, NULL, "gpio1_4"),
_PIN(0x814, "GPMC_AD5", 37, 7,"gpmc_ad5", "mmc1_dat5", NULL, NULL, NULL, NULL, NULL, "gpio1_5"),
_PIN(0x818, "GPMC_AD6", 38, 7,"gpmc_ad6", "mmc1_dat6", NULL, NULL, NULL, NULL, NULL, "gpio1_6"),
_PIN(0x81C, "GPMC_AD7", 39, 7,"gpmc_ad7", "mmc1_dat7", NULL, NULL, NULL, NULL, NULL, "gpio1_7"),
#if 0 /* Incomplete Entries - fill with data from table 2-7 in datasheet */
_PIN(0x820, "gpmc_ad8", 0, 0, "gpmc_ad8", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x824, "gpmc_ad9", 0, 0, "gpmc_ad9", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x828, "gpmc_ad10", 0, 0, "gpmc_ad10", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x82C, "gpmc_ad11", 0, 0, "gpmc_ad11", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x830, "gpmc_ad12", 0, 0, "gpmc_ad12", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x834, "gpmc_ad13", 0, 0, "gpmc_ad13", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x838, "gpmc_ad14", 0, 0, "gpmc_ad14", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x83C, "gpmc_ad15", 0, 0, "gpmc_ad15", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x840, "gpmc_a0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x844, "gpmc_a1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x848, "gpmc_a2", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x84C, "gpmc_a3", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x850, "gpmc_a4", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
#endif
_PIN(0x854, "GPMC_A5", 53, 7, "gpmc_a5", "gmii2_txd0", "rgmii2_td0", "rmii2_txd0", "gpmc_a21", "pr1_mii1_rxd3", "eQEP1B_in", "gpio1_21"),
_PIN(0x858, "GPMC_A6", 54, 7, "gpmc_a6", "gmii2_txclk", "rgmii2_tclk", "mmc2_dat4", "gpmc_a22", "pr1_mii1_rxd2", "eQEP1_index", "gpio1_22"),
_PIN(0x85C, "GPMC_A7", 55, 7, "gpmc_a7", "gmii2_rxclk", "rgmii2_rclk", "mmc2_dat5", "gpmc_a23", "pr1_mii1_rxd1", "eQEP1_strobe", "gpio1_23"),
_PIN(0x860, "GPMC_A8", 56, 7, "gpmc_a8", "gmii2_rxd3", "rgmii2_rd3", "mmc2_dat6", "gpmc_a24", "pr1_mii1_rxd0", "mcasp0_aclkx", "gpio1_24"),
#if 0
_PIN(0x864, "gpmc_a9", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x868, "gpmc_a10", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x86C, "gpmc_a11", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x870, "gpmc_wait0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x874, "gpmc_wpn", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x878, "gpmc_be1n", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x87c, "gpmc_csn0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x880, "gpmc_csn1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x884, "gpmc_csn2", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x888, "gpmc_csn3", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x88c, "gpmc_clk", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x890, "gpmc_advn_ale", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x894, "gpmc_oen_ren", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x898, "gpmc_wen", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x89c, "gpmc_be0n_cle", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x8a0, "lcd_data0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x8a4, "lcd_data1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x8a8, "lcd_data2", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x8ac, "lcd_data3", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x8b0, "lcd_data4", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x8b4, "lcd_data5", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x8b8, "lcd_data6", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x8bc, "lcd_data7", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x8c0, "lcd_data8", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x8c4, "lcd_data9", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x8c8, "lcd_data10", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x8cc, "lcd_data11", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x8d0, "lcd_data12", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x8d4, "lcd_data13", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x8d8, "lcd_data14", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x8dc, "lcd_data15", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x8e0, "lcd_vsync", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x8e4, "lcd_hsync", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x8e8, "lcd_pclk", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x8ec, "lcd_ac_bias_en", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
#endif
_PIN(0x8f0, "MMC0_DAT3", 90, 7, "mmc0_dat3", "gpmc_a20", "uart4_ctsn", "timer5", "uart1_dcdn", "pr1_pru0_pru_r30_8", "pr1_pru0_pru_r31_8", "gpio2_26"),
_PIN(0x8f4, "MMC0_DAT2", 91, 7, "mmc0_dat2", "gpmc_a21", "uart4_rtsn", "timer6", "uart1_dsrn", "pr1_pru0_pru_r30_9", "pr1_pru0_pru_r31_9", "gpio2_27"),
_PIN(0x8f8, "MMC0_DAT1", 92, 7, "mmc0_dat1", "gpmc_a22", "uart5_ctsn", "uart3_rxd", "uart1_dtrn", "pr1_pru0_pru_r30_10", "pr1_pru0_pru_r31_10", "gpio2_28"),
_PIN(0x8fc, "MMC0_DAT0", 93, 7, "mmc0_dat0", "gpmc_a23", "uart5_rtsn", "uart3_txd", "uart1_rin", "pr1_pru0_pru_r30_11", "pr1_pru0_pru_r31_11", "gpio2_29"),
_PIN(0x900, "MMC0_CLK", 94, 7, "mmc0_clk", "gpmc_a24", "uart3_ctsn", "uart2_rxd", "dcan1_tx", "pr1_pru0_pru_r30_12", "pr1_pru0_pru_r31_12", "gpio2_30"),
_PIN(0x904, "MMC0_CMD", 95, 7, "mmc0_cmd", "gpmc_a25", "uart3_rtsn", "uart2_txd", "dcan1_rx", "pr1_pru0_pru_r30_13", "pr1_pru0_pru_r31_13", "gpio2_31"),
_PIN(0x908, "MII1_COL", 96, 7, "gmii1_col", "rmii2_refclk", "spi1_sclk", "uart5_rxd", "mcasp1_axr2", "mmc2_dat3", "mcasp0_axr2", "gpio3_0"),
_PIN(0x90c, "MII1_CRS", 97, 7, "gmii1_crs", "rmii1_crs_dv", "spi1_d0", "I2C1_SDA", "mcasp1_aclkx", "uart5_ctsn", "uart2_rxd", "gpio3_1"),
_PIN(0x910, "MII1_RX_ER", 98, 7, "gmii1_rxerr", "rmii1_rxerr", "spi1_d1", "I2C1_SCL", "mcasp1_fsx", "uart5_rtsn", "uart2_txd", "gpio3_2"),
_PIN(0x914, "MII1_TX_EN", 99, 7, "gmii1_txen", "rmii1_txen", "rgmii1_tctl", "timer4", "mcasp1_axr0", "eQEP0_index", "mmc2_cmd", "gpio3_3"),
_PIN(0x918, "MII1_RX_DV", 100, 7, "gmii1_rxdv", "cd_memory_clk", "rgmii1_rctl", "uart5_txd", "mcasp1_aclkx", "mmc2_dat0", "mcasp0_aclkr", "gpio3_4"),
_PIN(0x91c, "MII1_TXD3", 16, 7, "gmii1_txd3", "dcan0_tx", "rgmii1_td3", "uart4_rxd", "mcasp1_fsx", "mmc2_dat1", "mcasp0_fsr", "gpio0_16"),
_PIN(0x920, "MII1_TXD2", 17, 7, "gmii1_txd2", "dcan0_rx", "rgmii1_td2", "uart4_txd", "mcasp1_axr0", "mmc2_dat2", "mcasp0_ahclkx", "gpio0_17"),
_PIN(0x924, "MII1_TXD1", 21, 7, "gmii1_txd1", "rmii1_txd1", "rgmii1_td1", "mcasp1_fsr", "mcasp1_axr1", "eQEP0A_in", "mmc1_cmd", "gpio0_21"),
_PIN(0x928, "MII1_TXD0", 28, 7, "gmii1_txd0", "rmii1_txd0", "rgmii1_td0", "mcasp1_axr2", "mcasp1_aclkr", "eQEP0B_in", "mmc1_clk", "gpio0_28"),
_PIN(0x92c, "MII1_TX_CLK", 105, 7, "gmii1_txclk", "uart2_rxd", "rgmii1_tclk", "mmc0_dat7", "mmc1_dat0", "uart1_dcdn", "mcasp0_aclkx", "gpio3_9"),
_PIN(0x930, "MII1_RX_CLK", 106, 7, "gmii1_rxclk", "uart2_txd", "rgmii1_rclk", "mmc0_dat6", "mmc1_dat1", "uart1_dsrn", "mcasp0_fsx", "gpio3_10"),
_PIN(0x934, "MII1_RXD3", 82, 7, "gmii1_rxd3", "uart3_rxd", "rgmii1_rd3", "mmc0_dat5", "mmc1_dat2", "uart1_dtrn", "mcasp0_axr0", "gpio2_18"),
_PIN(0x938, "MII1_RXD2", 83, 7, "gmii1_rxd2", "uart3_txd", "rgmii1_rd2", "mmc0_dat4", "mmc1_dat3", "uart1_rin", "mcasp0_axr1", "gpio2_19"),
_PIN(0x93c, "MII1_RXD1", 84, 7, "gmii1_rxd1", "rmii1_rxd1", "rgmii1_rd1", "mcasp1_axr3", "mcasp1_fsr", "eQEP0_strobe", "mmc2_clk", "gpio2_20"),
_PIN(0x940, "MII1_RXD0", 85, 7, "gmii1_rxd0", "rmii1_rxd0", "rgmii1_rd0", "mcasp1_ahclkx", "mcasp1_ahclkr", "mcasp1_aclkr", "mcasp0_axr3", "gpio2_21"),
_PIN(0x944, "RMII1_REF_CLK", 29, 7, "rmii1_refclk", "xdma_event_intr2", "spi1_cs0", "uart5_txd", "mcasp1_axr3", "mmc0_pow", "mcasp1_ahclkx", "gpio0_29"),
_PIN(0x948, "MDIO", 0, 7, "mdio_data", "timer6", "uart5_rxd", "uart3_ctsn", "mmc0_sdcd","mmc1_cmd", "mmc2_cmd","gpio0_0"),
_PIN(0x94c, "MDC", 1, 7, "mdio_clk", "timer5", "uart5_txd", "uart3_rtsn", "mmc0_sdwp", "mmc1_clk", "mmc2_clk", "gpio0_1"),
#if 0 /* Incomplete Entries - fill with data from table 2-7 in datasheet */
_PIN(0x950, "spi0_sclk", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x954, "spi0_d0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
#endif
_PIN(0x958, "spi0_d1", 4, 7, "spi0_d1", "mmc1_sdwp", "I2C1_SDA", "ehrpwm0_tripzone_input", "pr1_uart0_rxd", "pr1_edio_data_in0", "pr1_edio_data_out0", "gpio0_4"),
_PIN(0x95c, "spi0_cs0", 5, 7, "spi0_cs0", "mmc2_sdwp", "I2C1_SCL", "ehrpwm0_synci", "pr1_uart0_txd", "pr1_edio_data_in1", "pr1_edio_data_out1", "gpio0_5"),
#if 0
_PIN(0x960, "spi0_cs1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x964, "ecap0_in_pwm0_out",0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x968, "uart0_ctsn", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x96c, "uart0_rtsn", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x970, "uart0_rxd", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x974, "uart0_txd", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
#endif
_PIN(0x978, "uart1_ctsn", 12, 7, "uart1_ctsn", "timer6_mux1", "dcan0_tx", "I2C2_SDA", "spi1_cs0", "pr1_uart0_cts_n", "pr1_edc_latch0_in", "gpio0_12"),
_PIN(0x97c, "uart1_rtsn", 13, 7, "uart1_rtsn", "timer5_mux1", "dcan0_rx", "I2C2_SCL", "spi1_cs1", "pr1_uart0_rts_n ", "pr1_edc_latch1_in", "gpio0_13"),
#if 0
_PIN(0x980, "uart1_rxd", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x984, "uart1_txd", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
#endif
_PIN(0x988, "I2C0_SDA", 101, 7, "I2C0_SDA", "timer4", "uart2_ctsn", "eCAP2_in_PWM2_out", NULL, NULL, NULL, "gpio3_5"),
_PIN(0x98c, "I2C0_SCL", 102, 7, "I2C0_SCL", "timer7", "uart2_rtsn", "eCAP1_in_PWM1_out", NULL, NULL, NULL, "gpio3_6"),
#if 0
_PIN(0x990, "mcasp0_aclkx", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x994, "mcasp0_fsx", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x998, "mcasp0_axr0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x99c, "mcasp0_ahclkr", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9a0, "mcasp0_aclkr", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9a4, "mcasp0_fsr", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9a8, "mcasp0_axr1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9ac, "mcasp0_ahclkx", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9b0, "xdma_event_intr0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9b4, "xdma_event_intr1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9b8, "nresetin_out", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9bc, "porz", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9c0, "nnmi", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9c4, "osc0_in", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9c8, "osc0_out", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9cc, "osc0_vss", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9d0, "tms", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9d4, "tdi", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9d8, "tdo", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9dc, "tck", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9e0, "ntrst", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9e4, "emu0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9e8, "emu1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9ec, "osc1_in", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9f0, "osc1_out", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9f4, "osc1_vss", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9f8, "rtc_porz", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9fc, "pmic_power_en", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa00, "ext_wakeup", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa04, "enz_kaldo_1p8v", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
#endif
_PIN(0xa08, "USB0_DM", 0, 0, "USB0_DM", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa0c, "USB0_DP", 0, 0, "USB0_DP", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa10, "USB0_CE", 0, 0, "USB0_CE", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa14, "USB0_ID", 0, 0, "USB0_ID", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa18, "USB0_VBUS", 0, 0, "USB0_VBUS", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa1c, "USB0_DRVVBUS", 18, 7, "USB0_DRVVBUS", NULL, NULL, NULL, NULL, NULL, NULL, "gpio0_18"),
_PIN(0xa20, "USB1_DM", 0, 0, "USB1_DM", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa24, "USB1_DP", 0, 0, "USB1_DP", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa28, "USB1_CE", 0, 0, "USB1_CE", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa2c, "USB1_ID", 0, 0, "USB1_ID", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa30, "USB1_VBUS", 0, 0, "USB1_VBUS", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa34, "USB1_DRVVBUS", 109, 7, "USB1_DRVVBUS", NULL, NULL, NULL, NULL, NULL, NULL, "gpio3_13"),
#if 0
_PIN(0xa38, "ddr_resetn", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa3c, "ddr_csn0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa40, "ddr_cke", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa44, "ddr_ck", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa48, "ddr_nck", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa4c, "ddr_casn", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa50, "ddr_rasn", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa54, "ddr_wen", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa58, "ddr_ba0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa5c, "ddr_ba1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa60, "ddr_ba2", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa64, "ddr_a0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa68, "ddr_a1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa6c, "ddr_a2", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa70, "ddr_a3", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa74, "ddr_a4", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa78, "ddr_a5", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa7c, "ddr_a6", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa80, "ddr_a7", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa84, "ddr_a8", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa88, "ddr_a9", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa8c, "ddr_a10", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa90, "ddr_a11", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa94, "ddr_a12", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa98, "ddr_a13", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa9c, "ddr_a14", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xaa0, "ddr_a15", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xaa4, "ddr_odt", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xaa8, "ddr_d0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xaac, "ddr_d1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xab0, "ddr_d2", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xab4, "ddr_d3", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xab8, "ddr_d4", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xabc, "ddr_d5", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xac0, "ddr_d6", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xac4, "ddr_d7", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xac8, "ddr_d8", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xacc, "ddr_d9", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xad0, "ddr_d10", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xad4, "ddr_d11", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xad8, "ddr_d12", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xadc, "ddr_d13", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xae0, "ddr_d14", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xae4, "ddr_d15", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xae8, "ddr_dqm0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xaec, "ddr_dqm1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xaf0, "ddr_dqs0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xaf4, "ddr_dqsn0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xaf8, "ddr_dqs1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xafc, "ddr_dqsn1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb00, "ddr_vref", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb04, "ddr_vtp", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb08, "ddr_strben0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb0c, "ddr_strben1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb2c, "ain0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb28, "ain1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb24, "ain2", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb20, "ain3", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb1c, "ain4", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb18, "ain5", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb14, "ain6", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb10, "ain7", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb30, "vrefp", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb34, "vrefn", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb38, "avdd", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb3c, "avss", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb40, "iforce", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb44, "vsense", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb48, "testout", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
#endif
{ .ballname = NULL },
};
const struct ti_scm_device ti_scm_dev = {
.padconf_muxmode_mask = 0x7,
.padconf_sate_mask = 0x78,
.padstate = (struct ti_scm_padstate *) &ti_padstate_devmap,
.padconf = (struct ti_scm_padconf *) &ti_padconf_devmap,
};
int
ti_scm_padconf_set_gpioflags(uint32_t gpio, uint32_t flags)
{
unsigned int state = 0;
if (flags & GPIO_PIN_OUTPUT) {
if (flags & GPIO_PIN_PULLUP)
state = PADCONF_OUTPUT_PULLUP;
else
state = PADCONF_OUTPUT;
} else if (flags & GPIO_PIN_INPUT) {
if (flags & GPIO_PIN_PULLUP)
state = PADCONF_INPUT_PULLUP;
else if (flags & GPIO_PIN_PULLDOWN)
state = PADCONF_INPUT_PULLDOWN;
else
state = PADCONF_INPUT;
}
return ti_scm_padconf_set_gpiomode(gpio, state);
}
void
ti_scm_padconf_get_gpioflags(uint32_t gpio, uint32_t *flags)
{
unsigned int state;
if (ti_scm_padconf_get_gpiomode(gpio, &state) != 0)
*flags = 0;
else {
switch (state) {
case PADCONF_OUTPUT:
*flags = GPIO_PIN_OUTPUT;
break;
case PADCONF_OUTPUT_PULLUP:
*flags = GPIO_PIN_OUTPUT | GPIO_PIN_PULLUP;
break;
case PADCONF_INPUT:
*flags = GPIO_PIN_INPUT;
break;
case PADCONF_INPUT_PULLUP:
*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLUP;
break;
case PADCONF_INPUT_PULLDOWN:
*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLDOWN;
break;
default:
*flags = 0;
break;
}
}
}

View File

@ -0,0 +1,9 @@
#$FreeBSD$
arm/ti/aintc.c standard
arm/ti/am335x/am335x_prcm.c standard
arm/ti/am335x/am335x_dmtimer.c standard
arm/ti/am335x/am335x_scm_padconf.c standard
arm/ti/ti_edma3.c standard
arm/ti/ti_mmchs.c optional mmc
arm/ti/cpsw/if_cpsw.c optional cpsw

View File

@ -0,0 +1,3 @@
#$FreeBSD$
arm/ti/am335x/am335x_pmic.c optional am335x_pmic

View File

@ -0,0 +1,21 @@
# AM335x generic configuration
#$FreeBSD$
files "../ti/am335x/files.am335x"
include "../ti/std.ti"
makeoption ARM_LITTLE_ENDIAN
# Physical memory starts at 0x80000000. We assume images are loaded at
# 0x80200000, e.g. from u-boot with 'fatload mmc 0 0x80200000 kernel.bin'
#
#
options PHYSADDR=0x80000000
options KERNPHYSADDR=0x80200000
makeoptions KERNPHYSADDR=0x80200000
options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm
makeoptions KERNVIRTADDR=0xc0200000
options STARTUP_PAGETABLE_ADDR=0x80000000
options SOC_TI_AM335X
options ARM_L2_PIPT

View File

@ -0,0 +1,4 @@
# $FreeBSD$
files "../ti/am335x/files.beaglebone"
include "../ti/am335x/std.am335x"

113
sys/arm/ti/bus_space.c Normal file
View File

@ -0,0 +1,113 @@
/*-
* Copyright (C) 2012 FreeBSD Foundation
* 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. Neither the name of MARVELL nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY 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 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/malloc.h>
#include <machine/bus.h>
/* Prototypes for all the bus_space structure functions */
bs_protos(generic);
bs_protos(generic_armv4);
struct bus_space _base_tag = {
/* cookie */
.bs_cookie = (void *) 0,
/* mapping/unmapping */
.bs_map = generic_bs_map,
.bs_unmap = generic_bs_unmap,
.bs_subregion = generic_bs_subregion,
/* allocation/deallocation */
.bs_alloc = generic_bs_alloc,
.bs_free = generic_bs_free,
/* barrier */
.bs_barrier = generic_bs_barrier,
/* read (single) */
.bs_r_1 = generic_bs_r_1,
.bs_r_2 = generic_armv4_bs_r_2,
.bs_r_4 = generic_bs_r_4,
.bs_r_8 = NULL,
/* read multiple */
.bs_rm_1 = generic_bs_rm_1,
.bs_rm_2 = generic_armv4_bs_rm_2,
.bs_rm_4 = generic_bs_rm_4,
.bs_rm_8 = NULL,
/* read region */
.bs_rr_1 = generic_bs_rr_1,
.bs_rr_2 = generic_armv4_bs_rr_2,
.bs_rr_4 = generic_bs_rr_4,
.bs_rr_8 = NULL,
/* write (single) */
.bs_w_1 = generic_bs_w_1,
.bs_w_2 = generic_armv4_bs_w_2,
.bs_w_4 = generic_bs_w_4,
.bs_w_8 = NULL,
/* write multiple */
.bs_wm_1 = generic_bs_wm_1,
.bs_wm_2 = generic_armv4_bs_wm_2,
.bs_wm_4 = generic_bs_wm_4,
.bs_wm_8 = NULL,
/* write region */
.bs_wr_1 = generic_bs_wr_1,
.bs_wr_2 = generic_armv4_bs_wr_2,
.bs_wr_4 = generic_bs_wr_4,
.bs_wr_8 = NULL,
/* set multiple */
/* XXX not implemented */
/* set region */
.bs_sr_1 = NULL,
.bs_sr_2 = generic_armv4_bs_sr_2,
.bs_sr_4 = generic_bs_sr_4,
.bs_sr_8 = NULL,
/* copy */
.bs_c_1 = NULL,
.bs_c_2 = generic_armv4_bs_c_2,
.bs_c_4 = NULL,
.bs_c_8 = NULL,
};
bus_space_tag_t fdtbus_bs_tag = &_base_tag;

98
sys/arm/ti/common.c Normal file
View File

@ -0,0 +1,98 @@
/*-
* Copyright (C) 2008-2011 MARVELL INTERNATIONAL LTD.
* All rights reserved.
*
* Developed by Semihalf.
*
* 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. Neither the name of MARVELL nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY 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 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 "opt_global.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/kdb.h>
#include <sys/reboot.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
#include <machine/bus.h>
#include <machine/fdt.h>
#include <machine/vmparam.h>
struct fdt_fixup_entry fdt_fixup_table[] = {
{ NULL, NULL }
};
#ifdef SOC_OMAP4
static int
fdt_gic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
int *pol)
{
if (!fdt_is_compatible(node, "arm,gic"))
return (ENXIO);
*interrupt = fdt32_to_cpu(intr[0]);
*trig = INTR_TRIGGER_CONFORM;
*pol = INTR_POLARITY_CONFORM;
return (0);
}
#endif
#ifdef SOC_TI_AM335X
static int
fdt_aintc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
int *pol)
{
if (!fdt_is_compatible(node, "ti,aintc"))
return (ENXIO);
*interrupt = fdt32_to_cpu(intr[0]);
*trig = INTR_TRIGGER_CONFORM;
*pol = INTR_POLARITY_CONFORM;
return (0);
}
#endif
fdt_pic_decode_t fdt_pic_table[] = {
#ifdef SOC_OMAP4
&fdt_gic_decode_ic,
#endif
#ifdef SOC_TI_AM335X
&fdt_aintc_decode_ic,
#endif
NULL
};

1251
sys/arm/ti/cpsw/if_cpsw.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,107 @@
/*-
* Copyright (c) 2012 Damjan Marion <dmarion@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 _IF_CPSWREG_H
#define _IF_CPSWREG_H
#define CPSW_SS_OFFSET 0x0000
#define CPSW_SS_IDVER (CPSW_SS_OFFSET + 0x00)
#define CPSW_SS_SOFT_RESET (CPSW_SS_OFFSET + 0x08)
#define CPSW_SS_STAT_PORT_EN (CPSW_SS_OFFSET + 0x0C)
#define CPSW_SS_PTYPE (CPSW_SS_OFFSET + 0x10)
#define CPSW_PORT_OFFSET 0x0100
#define CPSW_PORT_P_TX_PRI_MAP(p) (CPSW_PORT_OFFSET + 0x118 + ((p-1) * 0x100))
#define CPSW_PORT_P0_CPDMA_TX_PRI_MAP (CPSW_PORT_OFFSET + 0x01C)
#define CPSW_PORT_P0_CPDMA_RX_CH_MAP (CPSW_PORT_OFFSET + 0x020)
#define CPSW_PORT_P_SA_LO(p) (CPSW_PORT_OFFSET + 0x120 + ((p-1) * 0x100))
#define CPSW_PORT_P_SA_HI(p) (CPSW_PORT_OFFSET + 0x124 + ((p-1) * 0x100))
#define CPSW_CPDMA_OFFSET 0x0800
#define CPSW_CPDMA_TX_CONTROL (CPSW_CPDMA_OFFSET + 0x04)
#define CPSW_CPDMA_RX_CONTROL (CPSW_CPDMA_OFFSET + 0x14)
#define CPSW_CPDMA_SOFT_RESET (CPSW_CPDMA_OFFSET + 0x1c)
#define CPSW_CPDMA_DMACONTROL (CPSW_CPDMA_OFFSET + 0x20)
#define CPSW_CPDMA_DMASTATUS (CPSW_CPDMA_OFFSET + 0x24)
#define CPSW_CPDMA_RX_BUFFER_OFFSET (CPSW_CPDMA_OFFSET + 0x28)
#define CPSW_CPDMA_TX_INTSTAT_RAW (CPSW_CPDMA_OFFSET + 0x80)
#define CPSW_CPDMA_TX_INTSTAT_MASKED (CPSW_CPDMA_OFFSET + 0x84)
#define CPSW_CPDMA_TX_INTMASK_SET (CPSW_CPDMA_OFFSET + 0x88)
#define CPSW_CPDMA_TX_INTMASK_CLEAR (CPSW_CPDMA_OFFSET + 0x8C)
#define CPSW_CPDMA_CPDMA_EOI_VECTOR (CPSW_CPDMA_OFFSET + 0x94)
#define CPSW_CPDMA_RX_INTSTAT_RAW (CPSW_CPDMA_OFFSET + 0xA0)
#define CPSW_CPDMA_RX_INTSTAT_MASKED (CPSW_CPDMA_OFFSET + 0xA4)
#define CPSW_CPDMA_RX_INTMASK_SET (CPSW_CPDMA_OFFSET + 0xA8)
#define CPSW_CPDMA_RX_INTMASK_CLEAR (CPSW_CPDMA_OFFSET + 0xAc)
#define CPSW_CPDMA_DMA_INTSTAT_RAW (CPSW_CPDMA_OFFSET + 0xB0)
#define CPSW_CPDMA_DMA_INTSTAT_MASKED (CPSW_CPDMA_OFFSET + 0xB4)
#define CPSW_CPDMA_DMA_INTMASK_SET (CPSW_CPDMA_OFFSET + 0xB8)
#define CPSW_CPDMA_DMA_INTMASK_CLEAR (CPSW_CPDMA_OFFSET + 0xBC)
#define CPSW_CPDMA_RX_FREEBUFFER(p) (CPSW_CPDMA_OFFSET + 0x0e0 + ((p) * 0x04))
#define CPSW_CPDMA_TX_HDP(p) (CPSW_CPDMA_OFFSET + 0x200 + ((p) * 0x04))
#define CPSW_CPDMA_RX_HDP(p) (CPSW_CPDMA_OFFSET + 0x220 + ((p) * 0x04))
#define CPSW_CPDMA_TX_CP(p) (CPSW_CPDMA_OFFSET + 0x240 + ((p) * 0x04))
#define CPSW_CPDMA_RX_CP(p) (CPSW_CPDMA_OFFSET + 0x260 + ((p) * 0x04))
#define CPSW_CPTS_OFFSET 0x0C00
#define CPSW_ALE_OFFSET 0x0D00
#define CPSW_ALE_CONTROL (CPSW_ALE_OFFSET + 0x08)
#define CPSW_ALE_TBLCTL (CPSW_ALE_OFFSET + 0x20)
#define CPSW_ALE_TBLW2 (CPSW_ALE_OFFSET + 0x34)
#define CPSW_ALE_TBLW1 (CPSW_ALE_OFFSET + 0x38)
#define CPSW_ALE_TBLW0 (CPSW_ALE_OFFSET + 0x3C)
#define CPSW_ALE_PORTCTL(p) (CPSW_ALE_OFFSET + 0x40 + ((p) * 0x04))
#define CPSW_SL_OFFSET 0x0D80
#define CPSW_SL_MACCONTROL(p) (CPSW_SL_OFFSET + (0x40 * (p)) + 0x04)
#define CPSW_SL_SOFT_RESET(p) (CPSW_SL_OFFSET + (0x40 * (p)) + 0x0C)
#define CPSW_SL_RX_MAXLEN(p) (CPSW_SL_OFFSET + (0x40 * (p)) + 0x10)
#define CPSW_SL_RX_PRI_MAP(p) (CPSW_SL_OFFSET + (0x40 * (p)) + 0x24)
#define MDIO_OFFSET 0x1000
#define MDIOCONTROL (MDIO_OFFSET + 0x04)
#define MDIOUSERACCESS0 (MDIO_OFFSET + 0x80)
#define MDIOUSERPHYSEL0 (MDIO_OFFSET + 0x84)
#define CPSW_WR_OFFSET 0x1200
#define CPSW_WR_SOFT_RESET (CPSW_WR_OFFSET + 0x04)
#define CPSW_WR_CONTROL (CPSW_WR_OFFSET + 0x08)
#define CPSW_WR_INT_CONTROL (CPSW_WR_OFFSET + 0x0c)
#define CPSW_WR_C_RX_THRESH_EN(p) (CPSW_WR_OFFSET + (0x10 * (p)) + 0x10)
#define CPSW_WR_C_RX_EN(p) (CPSW_WR_OFFSET + (0x10 * (p)) + 0x14)
#define CPSW_WR_C_TX_EN(p) (CPSW_WR_OFFSET + (0x10 * (p)) + 0x18)
#define CPSW_WR_C_MISC_EN(p) (CPSW_WR_OFFSET + (0x10 * (p)) + 0x1C)
#define CPSW_WR_C_RX_THRESH_STAT(p) (CPSW_WR_OFFSET + (0x10 * (p)) + 0x40)
#define CPSW_WR_C_RX_STAT(p) (CPSW_WR_OFFSET + (0x10 * (p)) + 0x44)
#define CPSW_WR_C_TX_STAT(p) (CPSW_WR_OFFSET + (0x10 * (p)) + 0x48)
#define CPSW_WR_C_MISC_STAT(p) (CPSW_WR_OFFSET + (0x10 * (p)) + 0x4C)
#define CPSW_CPPI_RAM_OFFSET 0x2000
#endif /*_IF_CPSWREG_H */

View File

@ -0,0 +1,124 @@
/*-
* Copyright (c) 2012 Damjan Marion <dmarion@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 _IF_CPSWVAR_H
#define _IF_CPSWVAR_H
#define CPSW_INTR_COUNT 4
/* MII BUS */
#define CPSW_MIIBUS_RETRIES 5
#define CPSW_MIIBUS_DELAY 1000
#define CPSW_MAX_TX_BUFFERS 128
#define CPSW_MAX_RX_BUFFERS 128
#define CPSW_MAX_ALE_ENTRIES 1024
struct cpsw_softc {
struct ifnet *ifp;
phandle_t node;
device_t dev;
uint8_t mac_addr[ETHER_ADDR_LEN];
device_t miibus;
struct mii_data *mii;
struct mtx tx_lock; /* transmitter lock */
struct mtx rx_lock; /* receiver lock */
struct resource *res[1 + CPSW_INTR_COUNT]; /* resources */
void *ih_cookie[CPSW_INTR_COUNT]; /* interrupt handlers cookies */
uint32_t cpsw_if_flags;
int cpsw_media_status;
struct callout wd_callout;
int wd_timer;
/* buffers */
bus_dma_tag_t mbuf_dtag;
bus_dmamap_t tx_dmamap[CPSW_MAX_TX_BUFFERS];
bus_dmamap_t rx_dmamap[CPSW_MAX_RX_BUFFERS];
struct mbuf *tx_mbuf[CPSW_MAX_TX_BUFFERS];
struct mbuf *rx_mbuf[CPSW_MAX_RX_BUFFERS];
int txbd_head;
int txbd_queue_size;
int rxbd_head;
int rxbd_tail;
int tmp;
int eoq;
int tc[CPSW_MAX_TX_BUFFERS];
int tc_unload[CPSW_MAX_TX_BUFFERS];
struct cpsw_softc *phy_sc;
};
#define CPDMA_BD_SOP (1<<15)
#define CPDMA_BD_EOP (1<<14)
#define CPDMA_BD_OWNER (1<<13)
#define CPDMA_BD_EOQ (1<<12)
#define CPDMA_BD_PKT_ERR_MASK (3<< 4)
struct cpsw_cpdma_bd {
volatile uint32_t next;
volatile uint32_t bufptr;
volatile uint16_t buflen;
volatile uint16_t bufoff;
volatile uint16_t pktlen;
volatile uint16_t flags;
};
/* Read/Write macros */
#define cpsw_read_4(reg) bus_read_4(sc->res[0], reg)
#define cpsw_write_4(reg, val) bus_write_4(sc->res[0], reg, val)
#define cpsw_cpdma_txbd_offset(i) \
(CPSW_CPPI_RAM_OFFSET + ((i)*16))
#define cpsw_cpdma_txbd_paddr(i) (cpsw_cpdma_txbd_offset(i) + \
vtophys(rman_get_start(sc->res[0])))
#define cpsw_cpdma_read_txbd(i, val) \
bus_read_region_4(sc->res[0], cpsw_cpdma_txbd_offset(i), (uint32_t *) val, 4)
#define cpsw_cpdma_write_txbd(i, val) \
bus_write_region_4(sc->res[0], cpsw_cpdma_txbd_offset(i), (uint32_t *) val, 4)
#define cpsw_cpdma_write_txbd_next(i, val) \
bus_write_4(sc->res[0], cpsw_cpdma_txbd_offset(i), val)
#define cpsw_cpdma_read_txbd_flags(i) \
bus_read_2(sc->res[0], cpsw_cpdma_txbd_offset(i)+14)
#define cpsw_cpdma_rxbd_offset(i) \
(CPSW_CPPI_RAM_OFFSET + ((CPSW_MAX_TX_BUFFERS + (i))*16))
#define cpsw_cpdma_rxbd_paddr(i) (cpsw_cpdma_rxbd_offset(i) + \
vtophys(rman_get_start(sc->res[0])))
#define cpsw_cpdma_read_rxbd(i, val) \
bus_read_region_4(sc->res[0], cpsw_cpdma_rxbd_offset(i), (uint32_t *) val, 4)
#define cpsw_cpdma_write_rxbd(i, val) \
bus_write_region_4(sc->res[0], cpsw_cpdma_rxbd_offset(i), (uint32_t *) val, 4)
#define cpsw_cpdma_write_rxbd_next(i, val) \
bus_write_4(sc->res[0], cpsw_cpdma_rxbd_offset(i), val)
#define cpsw_cpdma_read_rxbd_flags(i) \
bus_read_2(sc->res[0], cpsw_cpdma_rxbd_offset(i)+14)
#endif /*_IF_CPSWVAR_H */

25
sys/arm/ti/files.ti Normal file
View File

@ -0,0 +1,25 @@
#$FreeBSD$
kern/kern_clocksource.c standard
arm/arm/bus_space_generic.c standard
arm/arm/bus_space_asm_generic.S standard
arm/arm/cpufunc_asm_armv5.S standard
arm/arm/cpufunc_asm_arm10.S standard
arm/arm/cpufunc_asm_arm11.S standard
arm/arm/cpufunc_asm_armv7.S standard
arm/arm/irq_dispatch.S standard
arm/ti/bus_space.c standard
arm/ti/common.c standard
arm/ti/ti_cpuid.c standard
arm/ti/ti_machdep.c standard
arm/ti/ti_prcm.c standard
arm/ti/ti_scm.c standard
arm/ti/ti_gpio.c optional gpio
arm/ti/ti_i2c.c optional ti_i2c
dev/ofw/ofw_iicbus.c optional iicbus
dev/uart/uart_dev_ns8250.c optional uart

View File

@ -0,0 +1,780 @@
/*-
* Copyright (c) 2011
* Ben Gray <ben.r.gray@gmail.com>.
* 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 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 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$
*/
/*
* Texas Instruments - OMAP3xxx series processors
*
* Reference:
* OMAP35x Applications Processor
* Technical Reference Manual
* (omap35xx_techref.pdf)
*
*
* Note:
* The devices are mapped into address above 0xD000_0000 as the kernel space
* memory is at 0xC000_0000 and above. The first 256MB after this is reserved
* for the size of the kernel, everything above that is reserved for SoC
* devices.
*
*/
#ifndef _OMAP35XX_REG_H_
#define _OMAP35XX_REG_H_
#ifndef _LOCORE
#include <sys/types.h> /* for uint32_t */
#endif
#define OMAP35XX_SDRAM0_START 0x80000000UL
#define OMAP35XX_SDRAM1_START 0xA0000000UL
#define OMAP35XX_SDRAM_BANKS 2
#define OMAP35XX_SDRAM_BANK_SIZE 0x20000000UL
/* Physical/Virtual address for SDRAM controller */
#define OMAP35XX_SMS_VBASE 0x6C000000UL
#define OMAP35XX_SMS_HWBASE 0x6C000000UL
#define OMAP35XX_SMS_SIZE 0x01000000UL
#define OMAP35XX_SDRC_VBASE 0x6D000000UL
#define OMAP35XX_SDRC_HWBASE 0x6D000000UL
#define OMAP35XX_SDRC_SIZE 0x01000000UL
/* Physical/Virtual address for I/O space */
#define OMAP35XX_L3_VBASE 0xD0000000UL
#define OMAP35XX_L3_HWBASE 0x68000000UL
#define OMAP35XX_L3_SIZE 0x01000000UL
#define OMAP35XX_L4_CORE_VBASE 0xE8000000UL
#define OMAP35XX_L4_CORE_HWBASE 0x48000000UL
#define OMAP35XX_L4_CORE_SIZE 0x01000000UL
#define OMAP35XX_L4_WAKEUP_VBASE 0xE8300000UL
#define OMAP35XX_L4_WAKEUP_HWBASE 0x48300000UL
#define OMAP35XX_L4_WAKEUP_SIZE 0x00040000UL
#define OMAP35XX_L4_PERIPH_VBASE 0xE9000000UL
#define OMAP35XX_L4_PERIPH_HWBASE 0x49000000UL
#define OMAP35XX_L4_PERIPH_SIZE 0x00100000UL
/*
* L4-CORE Physical/Virtual addresss offsets
*/
#define OMAP35XX_SCM_OFFSET 0x00002000UL
#define OMAP35XX_CM_OFFSET 0x00004000UL
#define OMAP35XX_SDMA_OFFSET 0x00056000UL
#define OMAP35XX_I2C3_OFFSET 0x00060000UL
#define OMAP35XX_USB_TLL_OFFSET 0x00062000UL
#define OMAP35XX_USB_UHH_OFFSET 0x00064000UL
#define OMAP35XX_USB_EHCI_OFFSET 0x00064800UL
#define OMAP35XX_UART1_OFFSET 0x0006A000UL
#define OMAP35XX_UART2_OFFSET 0x0006C000UL
#define OMAP35XX_I2C1_OFFSET 0x00070000UL
#define OMAP35XX_I2C2_OFFSET 0x00072000UL
#define OMAP35XX_MCBSP1_OFFSET 0x00074000UL
#define OMAP35XX_GPTIMER10_OFFSET 0x00086000UL
#define OMAP35XX_GPTIMER11_OFFSET 0x00088000UL
#define OMAP35XX_MCBSP5_OFFSET 0x00096000UL
#define OMAP35XX_MMU1_OFFSET 0x000BD400UL
#define OMAP35XX_INTCPS_OFFSET 0x00200000UL
/*
* L4-WAKEUP Physical/Virtual addresss offsets
*/
#define OMAP35XX_PRM_OFFSET 0x00006000UL
#define OMAP35XX_GPIO1_OFFSET 0x00010000UL
#define OMAP35XX_GPTIMER1_OFFSET 0x00018000UL
/*
* L4-PERIPH Physical/Virtual addresss offsets
*/
#define OMAP35XX_UART3_OFFSET 0x00020000UL
#define OMAP35XX_MCBSP2_OFFSET 0x00022000UL
#define OMAP35XX_MCBSP3_OFFSET 0x00024000UL
#define OMAP35XX_MCBSP4_OFFSET 0x00026000UL
#define OMAP35XX_SIDETONE_MCBSP2_OFFSET 0x00028000UL
#define OMAP35XX_SIDETONE_MCBSP3_OFFSET 0x0002A000UL
#define OMAP35XX_GPTIMER2_OFFSET 0x00032000UL
#define OMAP35XX_GPTIMER3_OFFSET 0x00034000UL
#define OMAP35XX_GPTIMER4_OFFSET 0x00036000UL
#define OMAP35XX_GPTIMER5_OFFSET 0x00038000UL
#define OMAP35XX_GPTIMER6_OFFSET 0x0003A000UL
#define OMAP35XX_GPTIMER7_OFFSET 0x0003C000UL
#define OMAP35XX_GPTIMER8_OFFSET 0x0003E000UL
#define OMAP35XX_GPTIMER9_OFFSET 0x00040000UL
#define OMAP35XX_GPIO2_OFFSET 0x00050000UL
#define OMAP35XX_GPIO3_OFFSET 0x00052000UL
#define OMAP35XX_GPIO4_OFFSET 0x00054000UL
#define OMAP35XX_GPIO5_OFFSET 0x00056000UL
#define OMAP35XX_GPIO6_OFFSET 0x00058000UL
/*
* System Control Module
*/
#define OMAP35XX_SCM_HWBASE (OMAP35XX_L4_CORE_HWBASE + OMAP35XX_SCM_OFFSET)
#define OMAP35XX_SCM_VBASE (OMAP35XX_L4_CORE_VBASE + OMAP35XX_SCM_OFFSET)
#define OMAP35XX_SCM_SIZE 0x00001000UL
#define OMAP35XX_SCM_REVISION 0x00000000UL
#define OMAP35XX_SCM_SYSCONFIG 0x00000010UL
#define OMAP35XX_SCM_PADCONFS_BASE 0x00000030UL
#define OMAP35XX_SCM_DEVCONF0 0x00000274UL
#define OMAP35XX_SCM_MEM_DFTRW0 0x00000278UL
/*
*
*/
#define OMAP35XX_CM_HWBASE (OMAP35XX_L4_CORE_HWBASE + OMAP35XX_CM_OFFSET)
#define OMAP35XX_CM_VBASE (OMAP35XX_L4_CORE_VBASE + OMAP35XX_CM_OFFSET)
#define OMAP35XX_CM_SIZE 0x00001500UL
#define OMAP35XX_CM_CORE_OFFSET 0x00000A00UL
#define OMAP35XX_CM_CORE_SIZE 0x00000100UL
#define OMAP35XX_CM_FCLKEN1_CORE (OMAP35XX_CM_CORE_OFFSET + 0x0000UL)
#define OMAP35XX_CM_FCLKEN3_CORE (OMAP35XX_CM_CORE_OFFSET + 0x0008UL)
#define OMAP35XX_CM_ICLKEN1_CORE (OMAP35XX_CM_CORE_OFFSET + 0x0010UL)
#define OMAP35XX_CM_ICLKEN2_CORE (OMAP35XX_CM_CORE_OFFSET + 0x0014UL)
#define OMAP35XX_CM_ICLKEN3_CORE (OMAP35XX_CM_CORE_OFFSET + 0x0018UL)
#define OMAP35XX_CM_IDLEST1_CORE (OMAP35XX_CM_CORE_OFFSET + 0x0020UL)
#define OMAP35XX_CM_IDLEST2_CORE (OMAP35XX_CM_CORE_OFFSET + 0x0024UL)
#define OMAP35XX_CM_IDLEST3_CORE (OMAP35XX_CM_CORE_OFFSET + 0x0028UL)
#define OMAP35XX_CM_AUTOIDLE1_CORE (OMAP35XX_CM_CORE_OFFSET + 0x0030UL)
#define OMAP35XX_CM_AUTOIDLE2_CORE (OMAP35XX_CM_CORE_OFFSET + 0x0034UL)
#define OMAP35XX_CM_AUTOIDLE3_CORE (OMAP35XX_CM_CORE_OFFSET + 0x0038UL)
#define OMAP35XX_CM_CLKSEL_CORE (OMAP35XX_CM_CORE_OFFSET + 0x0040UL)
#define OMAP35XX_CM_CLKSTCTRL_CORE (OMAP35XX_CM_CORE_OFFSET + 0x0048UL)
#define OMAP35XX_CM_CLKSTST_CORE (OMAP35XX_CM_CORE_OFFSET + 0x004CUL)
#define OMAP35XX_CM_WKUP_OFFSET 0x00000C00UL
#define OMAP35XX_CM_WKUP_SIZE 0x00000100UL
#define OMAP35XX_CM_FCLKEN_WKUP (OMAP35XX_CM_WKUP_OFFSET + 0x0000UL)
#define OMAP35XX_CM_ICLKEN_WKUP (OMAP35XX_CM_WKUP_OFFSET + 0x0010UL)
#define OMAP35XX_CM_IDLEST_WKUP (OMAP35XX_CM_WKUP_OFFSET + 0x0020UL)
#define OMAP35XX_CM_AUTOIDLE_WKUP (OMAP35XX_CM_WKUP_OFFSET + 0x0030UL)
#define OMAP35XX_CM_CLKSEL_WKUP (OMAP35XX_CM_WKUP_OFFSET + 0x0040UL)
#define OMAP35XX_CM_PLL_OFFSET 0x00000D00UL
#define OMAP35XX_CM_PLL_SIZE 0x00000100UL
#define OMAP35XX_CM_CLKEN_PLL (OMAP35XX_CM_PLL_OFFSET + 0x0000UL)
#define OMAP35XX_CM_CLKEN2_PLL (OMAP35XX_CM_PLL_OFFSET + 0x0004UL)
#define OMAP35XX_CM_IDLEST_CKGEN (OMAP35XX_CM_PLL_OFFSET + 0x0020UL)
#define OMAP35XX_CM_IDLEST2_CKGEN (OMAP35XX_CM_PLL_OFFSET + 0x0024UL)
#define OMAP35XX_CM_AUTOIDLE_PLL (OMAP35XX_CM_PLL_OFFSET + 0x0030UL)
#define OMAP35XX_CM_AUTOIDLE2_PLL (OMAP35XX_CM_PLL_OFFSET + 0x0034UL)
#define OMAP35XX_CM_CLKSEL1_PLL (OMAP35XX_CM_PLL_OFFSET + 0x0040UL)
#define OMAP35XX_CM_CLKSEL2_PLL (OMAP35XX_CM_PLL_OFFSET + 0x0044UL)
#define OMAP35XX_CM_CLKSEL3_PLL (OMAP35XX_CM_PLL_OFFSET + 0x0048UL)
#define OMAP35XX_CM_CLKSEL4_PLL (OMAP35XX_CM_PLL_OFFSET + 0x004CUL)
#define OMAP35XX_CM_CLKSEL5_PLL (OMAP35XX_CM_PLL_OFFSET + 0x0050UL)
#define OMAP35XX_CM_CLKOUT_CTRL (OMAP35XX_CM_PLL_OFFSET + 0x0070UL)
#define OMAP35XX_CM_PER_OFFSET 0x00001000UL
#define OMAP35XX_CM_PER_SIZE 0x00000100UL
#define OMAP35XX_CM_FCLKEN_PER (OMAP35XX_CM_PER_OFFSET + 0x0000UL)
#define OMAP35XX_CM_ICLKEN_PER (OMAP35XX_CM_PER_OFFSET + 0x0010UL)
#define OMAP35XX_CM_IDLEST_PER (OMAP35XX_CM_PER_OFFSET + 0x0020UL)
#define OMAP35XX_CM_AUTOIDLE_PER (OMAP35XX_CM_PER_OFFSET + 0x0030UL)
#define OMAP35XX_CM_CLKSEL_PER (OMAP35XX_CM_PER_OFFSET + 0x0040UL)
#define OMAP35XX_CM_SLEEPDEP_PER (OMAP35XX_CM_PER_OFFSET + 0x0044UL)
#define OMAP35XX_CM_CLKSTCTRL_PER (OMAP35XX_CM_PER_OFFSET + 0x0048UL)
#define OMAP35XX_CM_CLKSTST_PER (OMAP35XX_CM_PER_OFFSET + 0x004CUL)
#define OMAP35XX_CM_USBHOST_OFFSET 0x00001400UL
#define OMAP35XX_CM_USBHOST_SIZE 0x00000100UL
#define OMAP35XX_CM_FCLKEN_USBHOST (OMAP35XX_CM_USBHOST_OFFSET + 0x0000UL)
#define OMAP35XX_CM_ICLKEN_USBHOST (OMAP35XX_CM_USBHOST_OFFSET + 0x0010UL)
#define OMAP35XX_CM_IDLEST_USBHOST (OMAP35XX_CM_USBHOST_OFFSET + 0x0020UL)
#define OMAP35XX_CM_AUTOIDLE_USBHOST (OMAP35XX_CM_USBHOST_OFFSET + 0x0030UL)
#define OMAP35XX_CM_SLEEPDEP_USBHOST (OMAP35XX_CM_USBHOST_OFFSET + 0x0044UL)
#define OMAP35XX_CM_CLKSTCTRL_USBHOST (OMAP35XX_CM_USBHOST_OFFSET + 0x0048UL)
#define OMAP35XX_CM_CLKSTST_USBHOST (OMAP35XX_CM_USBHOST_OFFSET + 0x004CUL)
/*
*
*/
#define OMAP35XX_PRM_HWBASE (OMAP35XX_L4_WAKEUP_HWBASE + OMAP35XX_PRM_OFFSET)
#define OMAP35XX_PRM_VBASE (OMAP35XX_L4_WAKEUP_VBASE + OMAP35XX_PRM_OFFSET)
#define OMAP35XX_PRM_SIZE 0x00001600UL
#define OMAP35XX_PRM_CLKCTRL_OFFSET 0x00000D00UL
#define OMAP35XX_PRM_CLKCTRL_SIZE 0x00000100UL
#define OMAP35XX_PRM_CLKSEL (OMAP35XX_PRM_CLKCTRL_OFFSET + 0x0040UL)
#define OMAP35XX_PRM_CLKOUT_CTRL (OMAP35XX_PRM_CLKCTRL_OFFSET + 0x0070UL)
#define OMAP35XX_PRM_GLOBAL_OFFSET 0x00001200UL
#define OMAP35XX_PRM_GLOBAL_SIZE 0x00000100UL
#define OMAP35XX_PRM_CLKSRC_CTRL (OMAP35XX_PRM_GLOBAL_OFFSET + 0x0070UL)
/*
* Uarts
*/
#define OMAP35XX_UART1_HWBASE (OMAP35XX_L4_CORE_HWBASE + OMAP35XX_UART1_OFFSET)
#define OMAP35XX_UART1_VBASE (OMAP35XX_L4_CORE_VBASE + OMAP35XX_UART1_OFFSET)
#define OMAP35XX_UART1_SIZE 0x00001000UL
#define OMAP35XX_UART2_HWBASE (OMAP35XX_L4_CORE_HWBASE + OMAP35XX_UART2_OFFSET)
#define OMAP35XX_UART2_VBASE (OMAP35XX_L4_CORE_VBASE + OMAP35XX_UART2_OFFSET)
#define OMAP35XX_UART2_SIZE 0x00001000UL
#define OMAP35XX_UART3_HWBASE (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_UART3_OFFSET)
#define OMAP35XX_UART3_VBASE (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_UART3_OFFSET)
#define OMAP35XX_UART3_SIZE 0x00001000UL
/*
* I2C Modules
*/
#define OMAP35XX_I2C1_HWBASE (OMAP35XX_L4_CORE_HWBASE + OMAP35XX_I2C1_OFFSET)
#define OMAP35XX_I2C1_VBASE (OMAP35XX_L4_CORE_VBASE + OMAP35XX_I2C1_OFFSET)
#define OMAP35XX_I2C1_SIZE 0x00000080UL
#define OMAP35XX_I2C2_HWBASE (OMAP35XX_L4_CORE_HWBASE + OMAP35XX_I2C2_OFFSET)
#define OMAP35XX_I2C2_VBASE (OMAP35XX_L4_CORE_VBASE + OMAP35XX_I2C2_OFFSET)
#define OMAP35XX_I2C2_SIZE 0x00000080UL
#define OMAP35XX_I2C3_HWBASE (OMAP35XX_L4_CORE_HWBASE + OMAP35XX_I2C3_OFFSET)
#define OMAP35XX_I2C3_VBASE (OMAP35XX_L4_CORE_VBASE + OMAP35XX_I2C3_OFFSET)
#define OMAP35XX_I2C3_SIZE 0x00000080UL
#define OMAP35XX_I2C_IE 0x04
#define OMAP35XX_I2C_STAT 0x08
#define OMAP35XX_I2C_WE 0x0C
#define OMAP35XX_I2C_SYSS 0x10
#define OMAP35XX_I2C_BUF 0x14
#define OMAP35XX_I2C_CNT 0x18
#define OMAP35XX_I2C_DATA 0x1C
#define OMAP35XX_I2C_SYSC 0x20
#define OMAP35XX_I2C_CON 0x24
#define OMAP35XX_I2C_OA0 0x28
#define OMAP35XX_I2C_SA 0x2C
#define OMAP35XX_I2C_PSC 0x30
#define OMAP35XX_I2C_SCLL 0x34
#define OMAP35XX_I2C_SCLH 0x38
#define OMAP35XX_I2C_SYSTEST 0x3C
#define OMAP35XX_I2C_BUFSTAT 0x40
#define OMAP35XX_I2C_OA1 0x44
#define OMAP35XX_I2C_OA2 0x48
#define OMAP35XX_I2C_OA3 0x4C
#define OMAP35XX_I2C_ACTOA 0x50
#define OMAP35XX_I2C_SBLOCK 0x54
/*
* McBSP Modules
*/
#define OMAP35XX_MCBSP1_HWBASE (OMAP35XX_L4_CORE_HWBASE + OMAP35XX_MCBSP1_OFFSET)
#define OMAP35XX_MCBSP1_VBASE (OMAP35XX_L4_CORE_VBASE + OMAP35XX_MCBSP1_OFFSET)
#define OMAP35XX_MCBSP1_SIZE 0x00001000UL
#define OMAP35XX_MCBSP2_HWBASE (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_MCBSP2_OFFSET)
#define OMAP35XX_MCBSP2_VBASE (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_MCBSP2_OFFSET)
#define OMAP35XX_MCBSP2_SIZE 0x00001000UL
#define OMAP35XX_MCBSP3_HWBASE (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_MCBSP3_OFFSET)
#define OMAP35XX_MCBSP3_VBASE (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_MCBSP3_OFFSET)
#define OMAP35XX_MCBSP3_SIZE 0x00001000UL
#define OMAP35XX_MCBSP4_HWBASE (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_MCBSP4_OFFSET)
#define OMAP35XX_MCBSP4_VBASE (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_MCBSP4_OFFSET)
#define OMAP35XX_MCBSP4_SIZE 0x00001000UL
#define OMAP35XX_MCBSP5_HWBASE (OMAP35XX_L4_CORE_HWBASE + OMAP35XX_MCBSP5_OFFSET)
#define OMAP35XX_MCBSP5_VBASE (OMAP35XX_L4_CORE_VBASE + OMAP35XX_MCBSP5_OFFSET)
#define OMAP35XX_MCBSP5_SIZE 0x00001000UL
#define OMAP35XX_MCBSP_DRR 0x0000
#define OMAP35XX_MCBSP_DXR 0x0008
#define OMAP35XX_MCBSP_SPCR2 0x0010
#define OMAP35XX_MCBSP_SPCR1 0x0014
#define OMAP35XX_MCBSP_RCR2 0x0018
#define OMAP35XX_MCBSP_RCR1 0x001C
#define OMAP35XX_MCBSP_XCR2 0x0020
#define OMAP35XX_MCBSP_XCR1 0x0024
#define OMAP35XX_MCBSP_SRGR2 0x0028
#define OMAP35XX_MCBSP_SRGR1 0x002C
#define OMAP35XX_MCBSP_MCR2 0x0030
#define OMAP35XX_MCBSP_MCR1 0x0034
#define OMAP35XX_MCBSP_RCERA 0x0038
#define OMAP35XX_MCBSP_RCERB 0x003C
#define OMAP35XX_MCBSP_XCERA 0x0040
#define OMAP35XX_MCBSP_XCERB 0x0044
#define OMAP35XX_MCBSP_PCR 0x0048
#define OMAP35XX_MCBSP_RCERC 0x004C
#define OMAP35XX_MCBSP_RCERD 0x0050
#define OMAP35XX_MCBSP_XCERC 0x0054
#define OMAP35XX_MCBSP_XCERD 0x0058
#define OMAP35XX_MCBSP_RCERE 0x005C
#define OMAP35XX_MCBSP_RCERF 0x0060
#define OMAP35XX_MCBSP_XCERE 0x0064
#define OMAP35XX_MCBSP_XCERF 0x0068
#define OMAP35XX_MCBSP_RCERG 0x006C
#define OMAP35XX_MCBSP_RCERH 0x0070
#define OMAP35XX_MCBSP_XCERG 0x0074
#define OMAP35XX_MCBSP_XCERH 0x0078
#define OMAP35XX_MCBSP_RINTCLR 0x0080
#define OMAP35XX_MCBSP_XINTCLR 0x0084
#define OMAP35XX_MCBSP_ROVFLCLR 0x0088
#define OMAP35XX_MCBSP_SYSCONFIG 0x008C
#define OMAP35XX_MCBSP_THRSH2 0x0090
#define OMAP35XX_MCBSP_THRSH1 0x0094
#define OMAP35XX_MCBSP_IRQSTATUS 0x00A0
#define OMAP35XX_MCBSP_IRQENABLE 0x00A4
#define OMAP35XX_MCBSP_WAKEUPEN 0x00A8
#define OMAP35XX_MCBSP_XCCR 0x00AC
#define OMAP35XX_MCBSP_RCCR 0x00B0
#define OMAP35XX_MCBSP_XBUFFSTAT 0x00B4
#define OMAP35XX_MCBSP_RBUFFSTAT 0x00B8
#define OMAP35XX_MCBSP_SSELCR 0x00BC
#define OMAP35XX_MCBSP_STATUS 0x00C0
/*
* USB TTL Module
*/
#define OMAP35XX_USBTLL_HWBASE (OMAP35XX_L4_CORE_HWBASE + OMAP35XX_USBTLL_OFFSET)
#define OMAP35XX_USBTLL_VBASE (OMAP35XX_L4_CORE_VBASE + OMAP35XX_USBTLL_OFFSET)
#define OMAP35XX_USBTLL_SIZE 0x00001000UL
#define OMAP35XX_USBTLL_REVISION 0x0000
#define OMAP35XX_USBTLL_SYSCONFIG 0x0010
#define OMAP35XX_USBTLL_SYSSTATUS 0x0014
#define OMAP35XX_USBTLL_IRQSTATUS 0x0018
#define OMAP35XX_USBTLL_IRQENABLE 0x001C
#define OMAP35XX_USBTLL_TLL_SHARED_CONF 0x0030
#define OMAP35XX_USBTLL_TLL_CHANNEL_CONF(i) (0x0040 + (0x04 * (i)))
#define OMAP35XX_USBTLL_ULPI_VENDOR_ID_LO(i) (0x0800 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_VENDOR_ID_HI(i) (0x0801 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_PRODUCT_ID_LO(i) (0x0802 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_PRODUCT_ID_HI(i) (0x0803 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_FUNCTION_CTRL(i) (0x0804 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_FUNCTION_CTRL_SET(i) (0x0805 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_FUNCTION_CTRL_CLR(i) (0x0806 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_INTERFACE_CTRL(i) (0x0807 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_INTERFACE_CTRL_SET(i) (0x0808 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_INTERFACE_CTRL_CLR(i) (0x0809 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_OTG_CTRL(i) (0x080A + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_OTG_CTRL_SET(i) (0x080B + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_OTG_CTRL_CLR(i) (0x080C + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_USB_INT_EN_RISE(i) (0x080D + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_USB_INT_EN_RISE_SET(i) (0x080E + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_USB_INT_EN_RISE_CLR(i) (0x080F + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_USB_INT_EN_FALL(i) (0x0810 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_USB_INT_EN_FALL_SET(i) (0x0811 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_USB_INT_EN_FALL_CLR(i) (0x0812 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_USB_INT_STATUS(i) (0x0813 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_USB_INT_LATCH(i) (0x0814 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_DEBUG(i) (0x0815 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_SCRATCH_REGISTER(i) (0x0816 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_SCRATCH_REGISTER_SET(i) (0x0817 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_SCRATCH_REGISTER_CLR(i) (0x0818 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_EXTENDED_SET_ACCESS(i) (0x082F + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_UTMI_VCONTROL_EN(i) (0x0830 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_UTMI_VCONTROL_EN_SET(i) (0x0831 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_UTMI_VCONTROL_EN_CLR(i) (0x0832 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_UTMI_VCONTROL_STATUS(i) (0x0833 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_UTMI_VCONTROL_LATCH(i) (0x0834 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_UTMI_VSTATUS(i) (0x0835 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_UTMI_VSTATUS_SET(i) (0x0836 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_UTMI_VSTATUS_CLR(i) (0x0837 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_USB_INT_LATCH_NOCLR(i) (0x0838 + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_VENDOR_INT_EN(i) (0x083B + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_VENDOR_INT_EN_SET(i) (0x083C + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_VENDOR_INT_EN_CLR(i) (0x083D + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_VENDOR_INT_STATUS(i) (0x083E + (0x100 * (i)))
#define OMAP35XX_USBTLL_ULPI_VENDOR_INT_LATCH(i) (0x083F + (0x100 * (i)))
/*
* USB Host Module
*/
#define OMAP35XX_USB_TLL_HWBASE (OMAP35XX_L4_CORE_HWBASE + OMAP35XX_USB_TLL_OFFSET)
#define OMAP35XX_USB_TLL_VBASE (OMAP35XX_L4_CORE_VBASE + OMAP35XX_USB_TLL_OFFSET)
#define OMAP35XX_USB_TLL_SIZE 0x00001000UL
#define OMAP35XX_USB_EHCI_HWBASE (OMAP35XX_L4_CORE_HWBASE + OMAP35XX_USB_EHCI_OFFSET)
#define OMAP35XX_USB_EHCI_VBASE (OMAP35XX_L4_CORE_VBASE + OMAP35XX_USB_EHCI_OFFSET)
#define OMAP35XX_USB_EHCI_SIZE 0x00000400UL
#define OMAP35XX_USB_UHH_HWBASE (OMAP35XX_L4_CORE_HWBASE + OMAP35XX_USB_UHH_OFFSET)
#define OMAP35XX_USB_UHH_VBASE (OMAP35XX_L4_CORE_VBASE + OMAP35XX_USB_UHH_OFFSET)
#define OMAP35XX_USB_UHH_SIZE 0x00000400UL
/*
* SDRAM Controler (SDRC)
* PA 0x6D00_0000
*/
#define OMAP35XX_SDRC_SYSCONFIG (OMAP35XX_SDRC_VBASE + 0x10)
#define OMAP35XX_SDRC_SYSSTATUS (OMAP35XX_SDRC_VBASE + 0x14)
#define OMAP35XX_SDRC_CS_CFG (OMAP35XX_SDRC_VBASE + 0x40)
#define OMAP35XX_SDRC_SHARING (OMAP35XX_SDRC_VBASE + 0x44)
#define OMAP35XX_SDRC_ERR_ADDR (OMAP35XX_SDRC_VBASE + 0x48)
#define OMAP35XX_SDRC_ERR_TYPE (OMAP35XX_SDRC_VBASE + 0x4C)
#define OMAP35XX_SDRC_DLLA_CTRL (OMAP35XX_SDRC_VBASE + 0x60)
#define OMAP35XX_SDRC_DLLA_STATUS (OMAP35XX_SDRC_VBASE + 0x64)
#define OMAP35XX_SDRC_POWER_REG (OMAP35XX_SDRC_VBASE + 0x70)
#define OMAP35XX_SDRC_MCFG(p) (OMAP35XX_SDRC_VBASE + 0x80 + (0x30 * (p)))
#define OMAP35XX_SDRC_MR(p) (OMAP35XX_SDRC_VBASE + 0x84 + (0x30 * (p)))
#define OMAP35XX_SDRC_EMR2(p) (OMAP35XX_SDRC_VBASE + 0x8C + (0x30 * (p)))
#define OMAP35XX_SDRC_ACTIM_CTRLA(p) (OMAP35XX_SDRC_VBASE + 0x9C + (0x28 * (p)))
#define OMAP35XX_SDRC_ACTIM_CTRLB(p) (OMAP35XX_SDRC_VBASE + 0xA0 + (0x28 * (p)))
#define OMAP35XX_SDRC_RFR_CTRL(p) (OMAP35XX_SDRC_VBASE + 0xA4 + (0x30 * (p)))
#define OMAP35XX_SDRC_MANUAL(p) (OMAP35XX_SDRC_VBASE + 0xA8 + (0x30 * (p)))
/*
* SDMA Offset
* PA 0x4805 6000
*/
#define OMAP35XX_SDMA_HWBASE (OMAP35XX_L4_CORE_HWBASE + OMAP35XX_SDMA_OFFSET)
#define OMAP35XX_SDMA_VBASE (OMAP35XX_L4_CORE_VBASE + OMAP35XX_SDMA_OFFSET)
#define OMAP35XX_SDMA_SIZE 0x00001000UL
/*
* Interrupt Controller Unit.
* PA 0x4820_0000
*/
#define OMAP35XX_INTCPS_HWBASE (OMAP35XX_L4_CORE_HWBASE + OMAP35XX_INTCPS_OFFSET)
#define OMAP35XX_INTCPS_VBASE (OMAP35XX_L4_CORE_VBASE + OMAP35XX_INTCPS_OFFSET)
#define OMAP35XX_INTCPS_SIZE 0x00001000UL
#define OMAP35XX_INTCPS_SYSCONFIG (OMAP35XX_INTCPS_VBASE + 0x10)
#define OMAP35XX_INTCPS_SYSSTATUS (OMAP35XX_INTCPS_VBASE + 0x14)
#define OMAP35XX_INTCPS_SIR_IRQ (OMAP35XX_INTCPS_VBASE + 0x40)
#define OMAP35XX_INTCPS_SIR_FIQ (OMAP35XX_INTCPS_VBASE + 0x44)
#define OMAP35XX_INTCPS_CONTROL (OMAP35XX_INTCPS_VBASE + 0x48)
#define OMAP35XX_INTCPS_PROTECTION (OMAP35XX_INTCPS_VBASE + 0x4C)
#define OMAP35XX_INTCPS_IDLE (OMAP35XX_INTCPS_VBASE + 0x50)
#define OMAP35XX_INTCPS_IRQ_PRIORITY (OMAP35XX_INTCPS_VBASE + 0x60)
#define OMAP35XX_INTCPS_FIQ_PRIORITY (OMAP35XX_INTCPS_VBASE + 0x64)
#define OMAP35XX_INTCPS_THRESHOLD (OMAP35XX_INTCPS_VBASE + 0x68)
#define OMAP35XX_INTCPS_ITR(n) (OMAP35XX_INTCPS_VBASE + 0x80 + (0x20 * (n)))
#define OMAP35XX_INTCPS_MIR(n) (OMAP35XX_INTCPS_VBASE + 0x84 + (0x20 * (n)))
#define OMAP35XX_INTCPS_MIR_CLEAR(n) (OMAP35XX_INTCPS_VBASE + 0x88 + (0x20 * (n)))
#define OMAP35XX_INTCPS_MIR_SET(n) (OMAP35XX_INTCPS_VBASE + 0x8C + (0x20 * (n)))
#define OMAP35XX_INTCPS_ISR_SET(n) (OMAP35XX_INTCPS_VBASE + 0x90 + (0x20 * (n)))
#define OMAP35XX_INTCPS_ISR_CLEAR(n) (OMAP35XX_INTCPS_VBASE + 0x94 + (0x20 * (n)))
#define OMAP35XX_INTCPS_PENDING_IRQ(n) (OMAP35XX_INTCPS_VBASE + 0x98 + (0x20 * (n)))
#define OMAP35XX_INTCPS_PENDING_FIQ(n) (OMAP35XX_INTCPS_VBASE + 0x9C + (0x20 * (n)))
#define OMAP35XX_INTCPS_ILR(m) (OMAP35XX_INTCPS_VBASE + 0x100 + (0x4 * (m)))
#define OMAP35XX_IRQ_EMUINT 0 /* MPU emulation(2) */
#define OMAP35XX_IRQ_COMMTX 1 /* MPU emulation(2) */
#define OMAP35XX_IRQ_COMMRX 2 /* MPU emulation(2) */
#define OMAP35XX_IRQ_BENCH 3 /* MPU emulation(2) */
#define OMAP35XX_IRQ_MCBSP2_ST 4 /* Sidetone MCBSP2 overflow */
#define OMAP35XX_IRQ_MCBSP3_ST 5 /* Sidetone MCBSP3 overflow */
#define OMAP35XX_IRQ_SSM_ABORT 6 /* MPU subsystem secure state-machine abort (2) */
#define OMAP35XX_IRQ_SYS_NIRQ 7 /* External source (active low) */
#define OMAP35XX_IRQ_RESERVED8 8 /* RESERVED */
#define OMAP35XX_IRQ_SMX_DBG 9 /* SMX error for debug */
#define OMAP35XX_IRQ_SMX_APP 10 /* SMX error for application */
#define OMAP35XX_IRQ_PRCM_MPU 11 /* PRCM module IRQ */
#define OMAP35XX_IRQ_SDMA0 12 /* System DMA request 0(3) */
#define OMAP35XX_IRQ_SDMA1 13 /* System DMA request 1(3) */
#define OMAP35XX_IRQ_SDMA2 14 /* System DMA request 2 */
#define OMAP35XX_IRQ_SDMA3 15 /* System DMA request 3 */
#define OMAP35XX_IRQ_MCBSP1 16 /* McBSP module 1 IRQ (3) */
#define OMAP35XX_IRQ_MCBSP2 17 /* McBSP module 2 IRQ (3) */
#define OMAP35XX_IRQ_SR1 18 /* SmartReflex™ 1 */
#define OMAP35XX_IRQ_SR2 19 /* SmartReflex™ 2 */
#define OMAP35XX_IRQ_GPMC 20 /* General-purpose memory controller module */
#define OMAP35XX_IRQ_SGX 21 /* 2D/3D graphics module */
#define OMAP35XX_IRQ_MCBSP3 22 /* McBSP module 3(3) */
#define OMAP35XX_IRQ_MCBSP4 23 /* McBSP module 4(3) */
#define OMAP35XX_IRQ_CAM0 24 /* Camera interface request 0 */
#define OMAP35XX_IRQ_DSS 25 /* Display subsystem module(3) */
#define OMAP35XX_IRQ_MAIL_U0 26 /* Mailbox user 0 request */
#define OMAP35XX_IRQ_MCBSP5_IRQ1 27 /* McBSP module 5 (3) */
#define OMAP35XX_IRQ_IVA2_MMU 28 /* IVA2 MMU */
#define OMAP35XX_IRQ_GPIO1_MPU 29 /* GPIO module 1(3) */
#define OMAP35XX_IRQ_GPIO2_MPU 30 /* GPIO module 2(3) */
#define OMAP35XX_IRQ_GPIO3_MPU 31 /* GPIO module 3(3) */
#define OMAP35XX_IRQ_GPIO4_MPU 32 /* GPIO module 4(3) */
#define OMAP35XX_IRQ_GPIO5_MPU 33 /* GPIO module 5(3) */
#define OMAP35XX_IRQ_GPIO6_MPU 34 /* GPIO module 6(3) */
#define OMAP35XX_IRQ_USIM 35 /* USIM interrupt (HS devices only) (4) */
#define OMAP35XX_IRQ_WDT3 36 /* Watchdog timer module 3 overflow */
#define OMAP35XX_IRQ_GPT1 37 /* General-purpose timer module 1 */
#define OMAP35XX_IRQ_GPT2 38 /* General-purpose timer module 2 */
#define OMAP35XX_IRQ_GPT3 39 /* General-purpose timer module 3 */
#define OMAP35XX_IRQ_GPT4 40 /* General-purpose timer module 4 */
#define OMAP35XX_IRQ_GPT5 41 /* General-purpose timer module 5(3) */
#define OMAP35XX_IRQ_GPT6 42 /* General-purpose timer module 6(3) */
#define OMAP35XX_IRQ_GPT7 43 /* General-purpose timer module 7(3) */
#define OMAP35XX_IRQ_GPT8 44 /* General-purpose timer module 8(3) */
#define OMAP35XX_IRQ_GPT9 45 /* General-purpose timer module 9 */
#define OMAP35XX_IRQ_GPT10 46 /* General-purpose timer module 10 */
#define OMAP35XX_IRQ_GPT11 47 /* General-purpose timer module 11 */
#define OMAP35XX_IRQ_SPI4 48 /* McSPI module 4 */
#define OMAP35XX_IRQ_SHA1MD5_2 49 /* SHA-1/MD5 crypto-accelerator 2 (HS devices only)(4) */
#define OMAP35XX_IRQ_FPKA_IRQREADY_N 50 /* PKA crypto-accelerator (HS devices only) (4) */
#define OMAP35XX_IRQ_SHA2MD5 51 /* SHA-2/MD5 crypto-accelerator 1 (HS devices only) (4) */
#define OMAP35XX_IRQ_RNG 52 /* RNG module (HS devices only) (4) */
#define OMAP35XX_IRQ_MG 53 /* MG function (3) */
#define OMAP35XX_IRQ_MCBSP4_TX 54 /* McBSP module 4 transmit(3) */
#define OMAP35XX_IRQ_MCBSP4_RX 55 /* McBSP module 4 receive(3) */
#define OMAP35XX_IRQ_I2C1 56 /* I2C module 1 */
#define OMAP35XX_IRQ_I2C2 57 /* I2C module 2 */
#define OMAP35XX_IRQ_HDQ 58 /* HDQ / One-wire */
#define OMAP35XX_IRQ_MCBSP1_TX 59 /* McBSP module 1 transmit(3) */
#define OMAP35XX_IRQ_MCBSP1_RX 60 /* McBSP module 1 receive(3) */
#define OMAP35XX_IRQ_I2C3 61 /* I2C module 3 */
#define OMAP35XX_IRQ_McBSP2_TX 62 /* McBSP module 2 transmit(3) */
#define OMAP35XX_IRQ_McBSP2_RX 63 /* McBSP module 2 receive(3) */
#define OMAP35XX_IRQ_FPKA_IRQRERROR_N 64 /* PKA crypto-accelerator (HS devices only) (4) */
#define OMAP35XX_IRQ_SPI1 65 /* McSPI module 1 */
#define OMAP35XX_IRQ_SPI2 66 /* McSPI module 2 */
#define OMAP35XX_IRQ_RESERVED67 67 /* RESERVED */
#define OMAP35XX_IRQ_RESERVED68 68 /* RESERVED */
#define OMAP35XX_IRQ_RESERVED69 69 /* RESERVED */
#define OMAP35XX_IRQ_RESERVED70 70 /* RESERVED */
#define OMAP35XX_IRQ_RESERVED71 71 /* RESERVED */
#define OMAP35XX_IRQ_UART1 72 /* UART module 1 */
#define OMAP35XX_IRQ_UART2 73 /* UART module 2 */
#define OMAP35XX_IRQ_UART3 74 /* UART module 3 (also infrared)(3) */
#define OMAP35XX_IRQ_PBIAS 75 /* Merged interrupt for PBIASlite1 and 2 */
#define OMAP35XX_IRQ_OHCI 76 /* OHCI controller HSUSB MP Host Interrupt */
#define OMAP35XX_IRQ_EHCI 77 /* EHCI controller HSUSB MP Host Interrupt */
#define OMAP35XX_IRQ_TLL 78 /* HSUSB MP TLL Interrupt */
#define OMAP35XX_IRQ_PARTHASH 79 /* SHA2/MD5 crypto-accelerator 1 (HS devices only) (4) */
#define OMAP35XX_IRQ_RESERVED80 80 /* Reserved */
#define OMAP35XX_IRQ_MCBSP5_TX 81 /* McBSP module 5 transmit(3) */
#define OMAP35XX_IRQ_MCBSP5_RX 82 /* McBSP module 5 receive(3) */
#define OMAP35XX_IRQ_MMC1 83 /* MMC/SD module 1 */
#define OMAP35XX_IRQ_MS 84 /* MS-PRO™ module */
#define OMAP35XX_IRQ_RESERVED85 85 /* Reserved */
#define OMAP35XX_IRQ_MMC2 86 /* MMC/SD module 2 */
#define OMAP35XX_IRQ_MPU_ICR 87 /* MPU ICR */
#define OMAP35XX_IRQ_RESERVED 88 /* RESERVED */
#define OMAP35XX_IRQ_MCBSP3_TX 89 /* McBSP module 3 transmit(3) */
#define OMAP35XX_IRQ_MCBSP3_RX 90 /* McBSP module 3 receive(3) */
#define OMAP35XX_IRQ_SPI3 91 /* McSPI module 3 */
#define OMAP35XX_IRQ_HSUSB_MC_NINT 92 /* High-Speed USB OTG controller */
#define OMAP35XX_IRQ_HSUSB_DMA_NINT 93 /* High-Speed USB OTG DMA controller */
#define OMAP35XX_IRQ_MMC3 94 /* MMC/SD module 3 */
#define OMAP35XX_IRQ_GPT12 95 /* General-purpose timer module 12 */
/*
* General Purpose Timers
*/
#define OMAP35XX_GPTIMER1_VBASE (OMAP35XX_L4_WAKEUP_VBASE + OMAP35XX_GPTIMER1_OFFSET)
#define OMAP35XX_GPTIMER1_HWBASE (OMAP35XX_L4_WAKEUP_HWBASE + OMAP35XX_GPTIMER1_OFFSET)
#define OMAP35XX_GPTIMER2_VBASE (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_GPTIMER2_OFFSET)
#define OMAP35XX_GPTIMER2_HWBASE (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPTIMER2_OFFSET)
#define OMAP35XX_GPTIMER3_VBASE (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_GPTIMER3_OFFSET)
#define OMAP35XX_GPTIMER3_HWBASE (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPTIMER3_OFFSET)
#define OMAP35XX_GPTIMER4_VBASE (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_GPTIMER4_OFFSET)
#define OMAP35XX_GPTIMER4_HWBASE (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPTIMER4_OFFSET)
#define OMAP35XX_GPTIMER5_VBASE (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_GPTIMER5_OFFSET)
#define OMAP35XX_GPTIMER5_HWBASE (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPTIMER5_OFFSET)
#define OMAP35XX_GPTIMER6_VBASE (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_GPTIMER6_OFFSET)
#define OMAP35XX_GPTIMER6_HWBASE (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPTIMER6_OFFSET)
#define OMAP35XX_GPTIMER7_VBASE (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_GPTIMER7_OFFSET)
#define OMAP35XX_GPTIMER7_HWBASE (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPTIMER7_OFFSET)
#define OMAP35XX_GPTIMER8_VBASE (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_GPTIMER8_OFFSET)
#define OMAP35XX_GPTIMER8_HWBASE (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPTIMER8_OFFSET)
#define OMAP35XX_GPTIMER9_VBASE (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_GPTIMER9_OFFSET)
#define OMAP35XX_GPTIMER9_HWBASE (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPTIMER9_OFFSET)
#define OMAP35XX_GPTIMER10_VBASE (OMAP35XX_L4_CORE_VBASE + OMAP35XX_GPTIMER10_OFFSET)
#define OMAP35XX_GPTIMER10_HWBASE (OMAP35XX_L4_CORE_HWBASE + OMAP35XX_GPTIMER10_OFFSET)
#define OMAP35XX_GPTIMER11_VBASE (OMAP35XX_L4_CORE_VBASE + OMAP35XX_GPTIMER11_OFFSET)
#define OMAP35XX_GPTIMER11_HWBASE (OMAP35XX_L4_CORE_HWBASE + OMAP35XX_GPTIMER11_OFFSET)
#define OMAP35XX_GPTIMER12_VBASE 0x48304000UL /* GPTIMER12 */
#define OMAP35XX_GPTIMER_SIZE 0x00001000UL
/* Timer register offsets */
#define OMAP35XX_GPTIMER_TIOCP_CFG 0x010
#define OMAP35XX_GPTIMER_TISTAT 0x014
#define OMAP35XX_GPTIMER_TISR 0x018
#define OMAP35XX_GPTIMER_TIER 0x01C
#define OMAP35XX_GPTIMER_TWER 0x020
#define OMAP35XX_GPTIMER_TCLR 0x024
#define OMAP35XX_GPTIMER_TCRR 0x028
#define OMAP35XX_GPTIMER_TLDR 0x02C
#define OMAP35XX_GPTIMER_TTGR 0x030
#define OMAP35XX_GPTIMER_TWPS 0x034
#define OMAP35XX_GPTIMER_TMAR 0x038
#define OMAP35XX_GPTIMER_TCAR1 0x03C
#define OMAP35XX_GPTIMER_TSICR 0x040
#define OMAP35XX_GPTIMER_TCAR2 0x044
#define OMAP35XX_GPTIMER_TPIR 0x048
#define OMAP35XX_GPTIMER_TNIR 0x04C
#define OMAP35XX_GPTIMER_TCVR 0x050
#define OMAP35XX_GPTIMER_TOCR 0x054
#define OMAP35XX_GPTIMER_TOWR 0x058
/* Bit values */
#define MAT_IT_FLAG 0x01
#define OVF_IT_FLAG 0x02
#define TCAR_IT_FLAG 0x04
/*
* GPIO - General Purpose IO
*/
/* Base addresses for the GPIO modules */
#define OMAP35XX_GPIO1_HWBASE (OMAP35XX_L4_WAKEUP_HWBASE + OMAP35XX_GPIO1_OFFSET)
#define OMAP35XX_GPIO1_VBASE (OMAP35XX_L4_WAKEUP_VBASE + OMAP35XX_GPIO1_OFFSET)
#define OMAP35XX_GPIO1_SIZE 0x00001000UL
#define OMAP35XX_GPIO2_HWBASE (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPIO2_OFFSET)
#define OMAP35XX_GPIO2_VBASE (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_GPIO2_OFFSET)
#define OMAP35XX_GPIO2_SIZE 0x00001000UL
#define OMAP35XX_GPIO3_HWBASE (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPIO3_OFFSET)
#define OMAP35XX_GPIO3_VBASE (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_GPIO3_OFFSET)
#define OMAP35XX_GPIO3_SIZE 0x00001000UL
#define OMAP35XX_GPIO4_HWBASE (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPIO4_OFFSET)
#define OMAP35XX_GPIO4_VBASE (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_GPIO4_OFFSET)
#define OMAP35XX_GPIO4_SIZE 0x00001000UL
#define OMAP35XX_GPIO5_HWBASE (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPIO5_OFFSET)
#define OMAP35XX_GPIO5_VBASE (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_GPIO5_OFFSET)
#define OMAP35XX_GPIO5_SIZE 0x00001000UL
#define OMAP35XX_GPIO6_HWBASE (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPIO6_OFFSET)
#define OMAP35XX_GPIO6_VBASE (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_GPIO6_OFFSET)
#define OMAP35XX_GPIO6_SIZE 0x00001000UL
/* Register offsets within the banks above */
#define OMAP35XX_GPIO_SYSCONFIG 0x010
#define OMAP35XX_GPIO_SYSSTATUS 0x014
#define OMAP35XX_GPIO_IRQSTATUS1 0x018
#define OMAP35XX_GPIO_IRQENABLE1 0x01C
#define OMAP35XX_GPIO_WAKEUPENABLE 0x020
#define OMAP35XX_GPIO_IRQSTATUS2 0x028
#define OMAP35XX_GPIO_IRQENABLE2 0x02C
#define OMAP35XX_GPIO_CTRL 0x030
#define OMAP35XX_GPIO_OE 0x034
#define OMAP35XX_GPIO_DATAIN 0x038
#define OMAP35XX_GPIO_DATAOUT 0x03C
#define OMAP35XX_GPIO_LEVELDETECT0 0x040
#define OMAP35XX_GPIO_LEVELDETECT1 0x044
#define OMAP35XX_GPIO_RISINGDETECT 0x048
#define OMAP35XX_GPIO_FALLINGDETECT 0x04C
#define OMAP35XX_GPIO_DEBOUNCENABLE 0x050
#define OMAP35XX_GPIO_DEBOUNCINGTIME 0x054
#define OMAP35XX_GPIO_CLEARIRQENABLE1 0x060
#define OMAP35XX_GPIO_SETIRQENABLE1 0x064
#define OMAP35XX_GPIO_CLEARIRQENABLE2 0x070
#define OMAP35XX_GPIO_SETIRQENABLE2 0x074
#define OMAP35XX_GPIO_CLEARWKUENA 0x080
#define OMAP35XX_GPIO_SETWKUENA 0x084
#define OMAP35XX_GPIO_CLEARDATAOUT 0x090
#define OMAP35XX_GPIO_SETDATAOUT 0x094
/*
* MMC/SD/SDIO
*/
/* Base addresses for the MMC/SD/SDIO modules */
#define OMAP35XX_MMCHS1_HWBASE (OMAP35XX_L4_CORE_HWBASE + 0x0009C000)
#define OMAP35XX_MMCHS1_VBASE (OMAP35XX_L4_CORE_VBASE + 0x0009C000)
#define OMAP35XX_MMCHS2_HWBASE (OMAP35XX_L4_CORE_HWBASE + 0x000B4000)
#define OMAP35XX_MMCHS2_VBASE (OMAP35XX_L4_CORE_VBASE + 0x000B4000)
#define OMAP35XX_MMCHS3_HWBASE (OMAP35XX_L4_CORE_HWBASE + 0x000AD000)
#define OMAP35XX_MMCHS3_VBASE (OMAP35XX_L4_CORE_VBASE + 0x000AD000)
#define OMAP35XX_MMCHS_SIZE 0x00000200UL
/* Register offsets within each of the MMC/SD/SDIO controllers */
#define OMAP35XX_MMCHS_SYSCONFIG 0x010
#define OMAP35XX_MMCHS_SYSSTATUS 0x014
#define OMAP35XX_MMCHS_CSRE 0x024
#define OMAP35XX_MMCHS_SYSTEST 0x028
#define OMAP35XX_MMCHS_CON 0x02C
#define OMAP35XX_MMCHS_PWCNT 0x030
#define OMAP35XX_MMCHS_BLK 0x104
#define OMAP35XX_MMCHS_ARG 0x108
#define OMAP35XX_MMCHS_CMD 0x10C
#define OMAP35XX_MMCHS_RSP10 0x110
#define OMAP35XX_MMCHS_RSP32 0x114
#define OMAP35XX_MMCHS_RSP54 0x118
#define OMAP35XX_MMCHS_RSP76 0x11C
#define OMAP35XX_MMCHS_DATA 0x120
#define OMAP35XX_MMCHS_PSTATE 0x124
#define OMAP35XX_MMCHS_HCTL 0x128
#define OMAP35XX_MMCHS_SYSCTL 0x12C
#define OMAP35XX_MMCHS_STAT 0x130
#define OMAP35XX_MMCHS_IE 0x134
#define OMAP35XX_MMCHS_ISE 0x138
#define OMAP35XX_MMCHS_AC12 0x13C
#define OMAP35XX_MMCHS_CAPA 0x140
#define OMAP35XX_MMCHS_CUR_CAPA 0x148
#define OMAP35XX_MMCHS_REV 0x1FC
#endif /* _OMAP35XX_REG_H_ */

View File

@ -0,0 +1,19 @@
#$FreeBSD$
arm/arm/gic.c standard
arm/arm/mpcore_timer.c standard
arm/ti/ti_smc.S standard
arm/ti/usb/omap_ehci.c optional usb ehci
arm/ti/ti_sdma.c optional ti_sdma
arm/ti/ti_mmchs.c optional mmc
arm/ti/omap4/omap4_l2cache.c optional pl310
arm/ti/omap4/omap4_prcm_clks.c standard
arm/ti/omap4/omap4_scm_padconf.c standard
arm/ti/omap4/omap4_mp.c optional smp
arm/ti/twl/twl.c optional twl
arm/ti/twl/twl_vreg.c optional twl twl_vreg
arm/ti/twl/twl_clks.c optional twl twl_clks

View File

@ -0,0 +1,39 @@
/*-
* Copyright (c) 2012 Olivier Houchard. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <arm/ti/ti_smc.h>
#include <arm/ti/omap4/omap4_smc.h>
#include <machine/pl310.h>
void
platform_init_pl310(struct pl310_softc *softc)
{
ti_smc0(1, 0, L2CACHE_ENABLE_L2);
}

View File

@ -0,0 +1,87 @@
/*-
* Copyright (c) 2012 Olivier Houchard. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/smp.h>
#include <machine/smp.h>
#include <machine/fdt.h>
#include <machine/intr.h>
#include <arm/ti/ti_smc.h>
#include <arm/ti/omap4/omap4_smc.h>
void mpentry(void);
void mptramp(void);
void
platform_mp_init_secondary(void)
{
gic_init_secondary();
}
void
platform_mp_setmaxid(void)
{
mp_maxid = 1;
}
int
platform_mp_probe(void)
{
mp_ncpus = 2;
return (1);
}
void
platform_mp_start_ap(void)
{
bus_addr_t scu_addr;
if (bus_space_map(fdtbus_bs_tag, 0x48240000, 0x1000, 0, &scu_addr) != 0)
panic("Couldn't map the SCU\n");
/* Enable the SCU */
*(volatile unsigned int *)scu_addr |= 1;
//*(volatile unsigned int *)(scu_addr + 0x30) |= 1;
cpu_idcache_wbinv_all();
cpu_l2cache_wbinv_all();
ti_smc0(0x200, 0xfffffdff, MODIFY_AUX_CORE_0);
ti_smc0(pmap_kextract(mpentry), 0, WRITE_AUX_CORE_1);
armv7_sev();
bus_space_unmap(fdtbus_bs_tag, scu_addr, 0x1000);
}
void
platform_ipi_send(cpuset_t cpus, u_int ipi)
{
pic_ipi_send(cpus, ipi);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,586 @@
/*-
* Copyright (c) 2011
* Ben Gray <ben.r.gray@gmail.com>.
* 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 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 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$
*/
/*
* Texas Instruments - OMAP44xx series processors
*
* Reference:
* OMAP44xx Applications Processor
* Technical Reference Manual
* (omap44xx_techref.pdf)
*
*
* Note:
* The devices are mapped into address above 0xD000_0000 as the kernel space
* memory is at 0xC000_0000 and above. The first 256MB after this is reserved
* for the size of the kernel, everything above that is reserved for SoC
* devices.
*
*/
#ifndef _OMAP44XX_REG_H_
#define _OMAP44XX_REG_H_
#ifndef _LOCORE
#include <sys/types.h> /* for uint32_t */
#endif
/* Physical/Virtual address for SDRAM controller */
#define OMAP44XX_SMS_VBASE 0x6C000000UL
#define OMAP44XX_SMS_HWBASE 0x6C000000UL
#define OMAP44XX_SMS_SIZE 0x01000000UL
#define OMAP44XX_SDRC_VBASE 0x6D000000UL
#define OMAP44XX_SDRC_HWBASE 0x6D000000UL
#define OMAP44XX_SDRC_SIZE 0x01000000UL
/* Physical/Virtual address for I/O space */
#define OMAP44XX_L3_EMU_VBASE 0xD4000000UL
#define OMAP44XX_L3_EMU_HWBASE 0x54000000UL
#define OMAP44XX_L3_EMU_SIZE 0x00200000UL
#define OMAP44XX_L3_EMIF1_VBASE 0xEC000000UL
#define OMAP44XX_L3_EMIF1_HWBASE 0x4C000000UL
#define OMAP44XX_L3_EMIF1_SIZE 0x01000000UL
#define OMAP44XX_L3_EMIF2_VBASE 0xED000000UL
#define OMAP44XX_L3_EMIF2_HWBASE 0x4D000000UL
#define OMAP44XX_L3_EMIF2_SIZE 0x01000000UL
#define OMAP44XX_L4_CORE_VBASE 0xEA000000UL
#define OMAP44XX_L4_CORE_HWBASE 0x4A000000UL
#define OMAP44XX_L4_CORE_SIZE 0x01000000UL
#define OMAP44XX_L4_WAKEUP_VBASE 0xEA300000UL
#define OMAP44XX_L4_WAKEUP_HWBASE 0x4A300000UL
#define OMAP44XX_L4_WAKEUP_SIZE 0x00040000UL
#define OMAP44XX_L4_PERIPH_VBASE 0xE8000000UL
#define OMAP44XX_L4_PERIPH_HWBASE 0x48000000UL
#define OMAP44XX_L4_PERIPH_SIZE 0x01000000UL
#define OMAP44XX_L4_ABE_VBASE 0xE9000000UL
#define OMAP44XX_L4_ABE_HWBASE 0x49000000UL
#define OMAP44XX_L4_ABE_SIZE 0x00100000UL
/* Physical/Virtual address for MPU Subsystem space */
#define OMAP44XX_MPU_SUBSYS_VBASE (OMAP44XX_L4_PERIPH_VBASE + 0x00240000UL)
#define OMAP44XX_MPU_SUBSYS_HWBASE (OMAP44XX_L4_PERIPH_HWBASE + 0x00240000UL)
#define OMAP44XX_MPU_SUBSYS_SIZE 0x00004000UL
/*
* MPU Subsystem addresss offsets
*/
#define OMAP44XX_SCU_OFFSET 0x00000000UL
#define OMAP44XX_GIC_CPU_OFFSET 0x00000100UL
#define OMAP44XX_GBL_TIMER_OFFSET 0x00000200UL
#define OMAP44XX_PRV_TIMER_OFFSET 0x00000600UL
#define OMAP44XX_GIC_DIST_OFFSET 0x00001000UL
#define OMAP44XX_PL310_OFFSET 0x00002000UL
#define OMAP44XX_CORTEXA9_SOCKET_PRCM_OFFSET 0x00003000UL
#define OMAP44XX_CORTEXA9_PRM_OFFSET 0x00003200UL
#define OMAP44XX_CORTEXA9_CPU0_OFFSET 0x00003400UL
#define OMAP44XX_CORTEXA9_CPU1_OFFSET 0x00003800UL
#define OMAP44XX_SCU_HWBASE (OMAP44XX_MPU_SUBSYS_HWBASE + OMAP44XX_SCU_OFFSET)
#define OMAP44XX_SCU_VBASE (OMAP44XX_MPU_SUBSYS_VBASE + OMAP44XX_SCU_OFFSET)
#define OMAP44XX_SCU_SIZE 0x00000080UL
#define OMAP44XX_GIC_CPU_HWBASE (OMAP44XX_MPU_SUBSYS_HWBASE + OMAP44XX_GIC_CPU_OFFSET)
#define OMAP44XX_GIC_CPU_VBASE (OMAP44XX_MPU_SUBSYS_VBASE + OMAP44XX_GIC_CPU_OFFSET)
#define OMAP44XX_GIC_CPU_SIZE 0x00000100UL
#define OMAP44XX_GBL_TIMER_HWBASE (OMAP44XX_MPU_SUBSYS_HWBASE + OMAP44XX_GBL_TIMER_OFFSET)
#define OMAP44XX_GBL_TIMER_VBASE (OMAP44XX_MPU_SUBSYS_VBASE + OMAP44XX_GBL_TIMER_OFFSET)
#define OMAP44XX_GBL_TIMER_SIZE 0x00000100UL
#define OMAP44XX_PRV_TIMER_HWBASE (OMAP44XX_MPU_SUBSYS_HWBASE + OMAP44XX_PRV_TIMER_OFFSET)
#define OMAP44XX_PRV_TIMER_VBASE (OMAP44XX_MPU_SUBSYS_VBASE + OMAP44XX_PRV_TIMER_OFFSET)
#define OMAP44XX_PRV_TIMER_SIZE 0x00000100UL
#define OMAP44XX_GIC_DIST_HWBASE (OMAP44XX_MPU_SUBSYS_HWBASE + OMAP44XX_GIC_DIST_OFFSET)
#define OMAP44XX_GIC_DIST_VBASE (OMAP44XX_MPU_SUBSYS_VBASE + OMAP44XX_GIC_DIST_OFFSET)
#define OMAP44XX_GIC_DIST_SIZE 0x00000100UL
#define OMAP44XX_PL310_HWBASE (OMAP44XX_MPU_SUBSYS_HWBASE + OMAP44XX_PL310_OFFSET)
#define OMAP44XX_PL310_VBASE (OMAP44XX_MPU_SUBSYS_VBASE + OMAP44XX_PL310_OFFSET)
#define OMAP44XX_PL310_SIZE 0x00001000UL
/*
* L4-CORE Physical/Virtual addresss offsets
*/
#define OMAP44XX_SCM_OFFSET 0x00002000UL
#define OMAP44XX_CM_OFFSET 0x00004000UL
#define OMAP44XX_SDMA_OFFSET 0x00056000UL
#define OMAP44XX_USB_TLL_OFFSET 0x00062000UL
#define OMAP44XX_USB_UHH_OFFSET 0x00064000UL
#define OMAP44XX_USB_OHCI_OFFSET 0x00064800UL
#define OMAP44XX_USB_EHCI_OFFSET 0x00064C00UL
#define OMAP44XX_MCBSP1_OFFSET 0x00074000UL
#define OMAP44XX_MCBSP5_OFFSET 0x00096000UL
#define OMAP44XX_SCM_PADCONF_OFFSET 0x00100000UL
/*
* L4-WAKEUP Physical/Virtual addresss offsets
*/
#define OMAP44XX_PRM_OFFSET 0x00006000UL
#define OMAP44XX_SCRM_OFFSET 0x0000A000UL
#define OMAP44XX_GPIO1_OFFSET 0x00010000UL
#define OMAP44XX_GPTIMER1_OFFSET 0x00018000UL
/*
* L4-PERIPH Physical/Virtual addresss offsets
*/
#define OMAP44XX_UART3_OFFSET 0x00020000UL
#define OMAP44XX_GPTIMER2_OFFSET 0x00032000UL
#define OMAP44XX_GPTIMER3_OFFSET 0x00034000UL
#define OMAP44XX_GPTIMER4_OFFSET 0x00036000UL
#define OMAP44XX_GPTIMER9_OFFSET 0x0003E000UL
#define OMAP44XX_GPIO2_OFFSET 0x00055000UL
#define OMAP44XX_GPIO3_OFFSET 0x00057000UL
#define OMAP44XX_GPIO4_OFFSET 0x00059000UL
#define OMAP44XX_GPIO5_OFFSET 0x0005B000UL
#define OMAP44XX_GPIO6_OFFSET 0x0005D000UL
#define OMAP44XX_I2C3_OFFSET 0x00060000UL
#define OMAP44XX_UART1_OFFSET 0x0006A000UL
#define OMAP44XX_UART2_OFFSET 0x0006C000UL
#define OMAP44XX_UART4_OFFSET 0x0006E000UL
#define OMAP44XX_I2C1_OFFSET 0x00070000UL
#define OMAP44XX_I2C2_OFFSET 0x00072000UL
#define OMAP44XX_SLIMBUS2_OFFSET 0x00076000UL
#define OMAP44XX_ELM_OFFSET 0x00078000UL
#define OMAP44XX_GPTIMER10_OFFSET 0x00086000UL
#define OMAP44XX_GPTIMER11_OFFSET 0x00088000UL
#define OMAP44XX_MCBSP4_OFFSET 0x00096000UL
#define OMAP44XX_MCSPI1_OFFSET 0x00098000UL
#define OMAP44XX_MCSPI2_OFFSET 0x0009A000UL
#define OMAP44XX_MMCHS1_OFFSET 0x0009C000UL
#define OMAP44XX_MMCSD3_OFFSET 0x000AD000UL
#define OMAP44XX_MMCHS2_OFFSET 0x000B4000UL
#define OMAP44XX_MMCSD4_OFFSET 0x000D1000UL
#define OMAP44XX_MMCSD5_OFFSET 0x000D5000UL
#define OMAP44XX_I2C4_OFFSET 0x00350000UL
/* The following are registers defined as part of the ARM MPCORE system,
* they are not SoC components rather registers that control the MPCORE core.
*/
// #define OMAP44XX_SCU_OFFSET 0x48240000 /* Snoop control unit */
// #define OMAP44XX_GIC_PROC_OFFSET 0x48240100 /* Interrupt controller unit */
// #define OMAP44XX_MPU_TIMER_OFFSET 0x48240600
// #define OMAP44XX_GIC_INTR_OFFSET 0x48241000
// #define OMAP44XX_PL310_OFFSET 0x48242000 /* L2 Cache controller */
/*
* L4-ABE Physical/Virtual addresss offsets
*/
#define OMAP44XX_GPTIMER5_OFFSET 0x00038000UL
#define OMAP44XX_GPTIMER6_OFFSET 0x0003A000UL
#define OMAP44XX_GPTIMER7_OFFSET 0x0003C000UL
#define OMAP44XX_GPTIMER8_OFFSET 0x0003E000UL
/*
* System Control Module
*/
#define OMAP44XX_SCM_HWBASE (OMAP44XX_L4_CORE_HWBASE + OMAP44XX_SCM_OFFSET)
#define OMAP44XX_SCM_VBASE (OMAP44XX_L4_CORE_VBASE + OMAP44XX_SCM_OFFSET)
#define OMAP44XX_SCM_SIZE 0x00001000UL
/*
*
*/
#define OMAP44XX_CM_HWBASE (OMAP44XX_L4_CORE_HWBASE + OMAP44XX_CM_OFFSET)
#define OMAP44XX_CM_VBASE (OMAP44XX_L4_CORE_VBASE + OMAP44XX_CM_OFFSET)
#define OMAP44XX_CM_SIZE 0x00001500UL
/*
*
*/
#define OMAP44XX_PRM_HWBASE (OMAP44XX_L4_WAKEUP_HWBASE + OMAP44XX_PRM_OFFSET)
#define OMAP44XX_PRM_VBASE (OMAP44XX_L4_WAKEUP_VBASE + OMAP44XX_PRM_OFFSET)
#define OMAP44XX_PRM_SIZE 0x00001600UL
/*
*
*/
#define OMAP44XX_SCRM_HWBASE (OMAP44XX_L4_WAKEUP_HWBASE + OMAP44XX_SCRM_OFFSET)
#define OMAP44XX_SCRM_VBASE (OMAP44XX_L4_WAKEUP_VBASE + OMAP44XX_SCRM_OFFSET)
#define OMAP44XX_SCRM_SIZE 0x00000800UL
/*
* Uarts
*/
#define OMAP44XX_UART1_HWBASE (OMAP44XX_L4_CORE_HWBASE + OMAP44XX_UART1_OFFSET)
#define OMAP44XX_UART1_VBASE (OMAP44XX_L4_CORE_VBASE + OMAP44XX_UART1_OFFSET)
#define OMAP44XX_UART1_SIZE 0x00001000UL
#define OMAP44XX_UART2_HWBASE (OMAP44XX_L4_CORE_HWBASE + OMAP44XX_UART2_OFFSET)
#define OMAP44XX_UART2_VBASE (OMAP44XX_L4_CORE_VBASE + OMAP44XX_UART2_OFFSET)
#define OMAP44XX_UART2_SIZE 0x00001000UL
#define OMAP44XX_UART3_HWBASE (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_UART3_OFFSET)
#define OMAP44XX_UART3_VBASE (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_UART3_OFFSET)
#define OMAP44XX_UART3_SIZE 0x00001000UL
#define OMAP44XX_UART4_HWBASE (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_UART4_OFFSET)
#define OMAP44XX_UART4_VBASE (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_UART4_OFFSET)
#define OMAP44XX_UART4_SIZE 0x00001000UL
/*
* I2C Modules
*/
#define OMAP44XX_I2C1_HWBASE (OMAP44XX_L4_CORE_HWBASE + OMAP44XX_I2C1_OFFSET)
#define OMAP44XX_I2C1_VBASE (OMAP44XX_L4_CORE_VBASE + OMAP44XX_I2C1_OFFSET)
#define OMAP44XX_I2C1_SIZE 0x00000080UL
#define OMAP44XX_I2C2_HWBASE (OMAP44XX_L4_CORE_HWBASE + OMAP44XX_I2C2_OFFSET)
#define OMAP44XX_I2C2_VBASE (OMAP44XX_L4_CORE_VBASE + OMAP44XX_I2C2_OFFSET)
#define OMAP44XX_I2C2_SIZE 0x00000080UL
#define OMAP44XX_I2C3_HWBASE (OMAP44XX_L4_CORE_HWBASE + OMAP44XX_I2C3_OFFSET)
#define OMAP44XX_I2C3_VBASE (OMAP44XX_L4_CORE_VBASE + OMAP44XX_I2C3_OFFSET)
#define OMAP44XX_I2C3_SIZE 0x00000080UL
/*
* McBSP Modules
*/
#define OMAP44XX_MCBSP1_HWBASE (OMAP44XX_L4_CORE_HWBASE + OMAP44XX_MCBSP1_OFFSET)
#define OMAP44XX_MCBSP1_VBASE (OMAP44XX_L4_CORE_VBASE + OMAP44XX_MCBSP1_OFFSET)
#define OMAP44XX_MCBSP1_SIZE 0x00001000UL
#define OMAP44XX_MCBSP2_HWBASE (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_MCBSP2_OFFSET)
#define OMAP44XX_MCBSP2_VBASE (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_MCBSP2_OFFSET)
#define OMAP44XX_MCBSP2_SIZE 0x00001000UL
#define OMAP44XX_MCBSP3_HWBASE (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_MCBSP3_OFFSET)
#define OMAP44XX_MCBSP3_VBASE (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_MCBSP3_OFFSET)
#define OMAP44XX_MCBSP3_SIZE 0x00001000UL
#define OMAP44XX_MCBSP4_HWBASE (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_MCBSP4_OFFSET)
#define OMAP44XX_MCBSP4_VBASE (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_MCBSP4_OFFSET)
#define OMAP44XX_MCBSP4_SIZE 0x00001000UL
#define OMAP44XX_MCBSP5_HWBASE (OMAP44XX_L4_CORE_HWBASE + OMAP44XX_MCBSP5_OFFSET)
#define OMAP44XX_MCBSP5_VBASE (OMAP44XX_L4_CORE_VBASE + OMAP44XX_MCBSP5_OFFSET)
#define OMAP44XX_MCBSP5_SIZE 0x00001000UL
/*
* USB TTL Module
*/
#define OMAP44XX_USB_TLL_HWBASE (OMAP44XX_L4_CORE_HWBASE + OMAP44XX_USB_TLL_OFFSET)
#define OMAP44XX_USB_TLL_VBASE (OMAP44XX_L4_CORE_VBASE + OMAP44XX_USB_TLL_OFFSET)
#define OMAP44XX_USB_TLL_SIZE 0x00001000UL
/*
* USB Host Module
*/
#define OMAP44XX_USB_UHH_HWBASE (OMAP44XX_L4_CORE_HWBASE + OMAP44XX_USB_UHH_OFFSET)
#define OMAP44XX_USB_UHH_VBASE (OMAP44XX_L4_CORE_VBASE + OMAP44XX_USB_UHH_OFFSET)
#define OMAP44XX_USB_UHH_SIZE 0x00000700UL
/*
* USB OHCI Module
*/
#define OMAP44XX_USB_OHCI_HWBASE (OMAP44XX_L4_CORE_HWBASE + OMAP44XX_USB_OHCI_OFFSET)
#define OMAP44XX_USB_OHCI_VBASE (OMAP44XX_L4_CORE_VBASE + OMAP44XX_USB_OHCI_OFFSET)
#define OMAP44XX_USB_OHCI_SIZE 0x00000400UL
/*
* USB EHCI Module
*/
#define OMAP44XX_USB_EHCI_HWBASE (OMAP44XX_L4_CORE_HWBASE + OMAP44XX_USB_EHCI_OFFSET)
#define OMAP44XX_USB_EHCI_VBASE (OMAP44XX_L4_CORE_VBASE + OMAP44XX_USB_EHCI_OFFSET)
#define OMAP44XX_USB_EHCI_SIZE 0x0000400UL
/*
* SDMA Offset
* PA 0x4805 6000
*/
#define OMAP44XX_SDMA_HWBASE (OMAP44XX_L4_CORE_HWBASE + OMAP44XX_SDMA_OFFSET)
#define OMAP44XX_SDMA_VBASE (OMAP44XX_L4_CORE_VBASE + OMAP44XX_SDMA_OFFSET)
#define OMAP44XX_SDMA_SIZE 0x00001000UL
/*
* Interrupt Controller Unit.
*
* Refer to the omap4_intr.c file for interrupt controller (GIC)
* implementation.
*
* Note:
* - 16 Interprocessor interrupts (IPI): ID[15:0]
* - 2 private Timer/Watchdog interrupts: ID[30:29]
* - 2 legacy nFIQ & nIRQ: one per CPU, bypasses the interrupt distributor
* logic and directly drives interrupt requests into CPU if used in
* legacy mode (else treated like other interrupts lines with ID28
* and ID31 respectively)
* - 128 hardware interrupts: ID[159:32] (rising-edge or high-level sensitive).
*/
#define OMAP44XX_HARDIRQ(x) (32 + (x))
#define OMAP44XX_IRQ_L2CACHE OMAP44XX_HARDIRQ(0) /* L2 cache controller interrupt */
#define OMAP44XX_IRQ_CTI_0 OMAP44XX_HARDIRQ(1) /* Cross-trigger module 0 (CTI0) interrupt */
#define OMAP44XX_IRQ_CTI_1 OMAP44XX_HARDIRQ(2) /* Cross-trigger module 1 (CTI1) interrupt */
#define OMAP44XX_IRQ_RESERVED3 OMAP44XX_HARDIRQ(3) /* RESERVED */
#define OMAP44XX_IRQ_ELM OMAP44XX_HARDIRQ(4) /* Error location process completion */
#define OMAP44XX_IRQ_RESERVED5 OMAP44XX_HARDIRQ(5) /* RESERVED */
#define OMAP44XX_IRQ_RESERVED6 OMAP44XX_HARDIRQ(6) /* RESERVED */
#define OMAP44XX_IRQ_SYS_NIRQ OMAP44XX_HARDIRQ(7) /* External source (active low) */
#define OMAP44XX_IRQ_RESERVED8 OMAP44XX_HARDIRQ(8) /* RESERVED */
#define OMAP44XX_IRQ_L3_DBG OMAP44XX_HARDIRQ(9) /* L3 interconnect debug error */
#define OMAP44XX_IRQ_L3_APP OMAP44XX_HARDIRQ(10) /* L3 interconnect application error */
#define OMAP44XX_IRQ_PRCM_MPU OMAP44XX_HARDIRQ(11) /* PRCM module IRQ */
#define OMAP44XX_IRQ_SDMA0 OMAP44XX_HARDIRQ(12) /* System DMA request 0(3) */
#define OMAP44XX_IRQ_SDMA1 OMAP44XX_HARDIRQ(13) /* System DMA request 1(3) */
#define OMAP44XX_IRQ_SDMA2 OMAP44XX_HARDIRQ(14) /* System DMA request 2 */
#define OMAP44XX_IRQ_SDMA3 OMAP44XX_HARDIRQ(15) /* System DMA request 3 */
#define OMAP44XX_IRQ_MCBSP4 OMAP44XX_HARDIRQ(16) /* McBSP module 4 IRQ */
#define OMAP44XX_IRQ_MCBSP1 OMAP44XX_HARDIRQ(17) /* McBSP module 1 IRQ */
#define OMAP44XX_IRQ_SR1 OMAP44XX_HARDIRQ(18) /* SmartReflex™ 1 */
#define OMAP44XX_IRQ_SR2 OMAP44XX_HARDIRQ(19) /* SmartReflex™ 2 */
#define OMAP44XX_IRQ_GPMC OMAP44XX_HARDIRQ(20) /* General-purpose memory controller module */
#define OMAP44XX_IRQ_SGX OMAP44XX_HARDIRQ(21) /* 2D/3D graphics module */
#define OMAP44XX_IRQ_MCBSP2 OMAP44XX_HARDIRQ(22) /* McBSP module 2 */
#define OMAP44XX_IRQ_MCBSP3 OMAP44XX_HARDIRQ(23) /* McBSP module 3 */
#define OMAP44XX_IRQ_ISS5 OMAP44XX_HARDIRQ(24) /* Imaging subsystem interrupt 5 */
#define OMAP44XX_IRQ_DSS OMAP44XX_HARDIRQ(25) /* Display subsystem module(3) */
#define OMAP44XX_IRQ_MAIL_U0 OMAP44XX_HARDIRQ(26) /* Mailbox user 0 request */
#define OMAP44XX_IRQ_C2C_SSCM OMAP44XX_HARDIRQ(27) /* C2C status interrupt */
#define OMAP44XX_IRQ_DSP_MMU OMAP44XX_HARDIRQ(28) /* DSP MMU */
#define OMAP44XX_IRQ_GPIO1_MPU OMAP44XX_HARDIRQ(29) /* GPIO module 1(3) */
#define OMAP44XX_IRQ_GPIO2_MPU OMAP44XX_HARDIRQ(30) /* GPIO module 2(3) */
#define OMAP44XX_IRQ_GPIO3_MPU OMAP44XX_HARDIRQ(31) /* GPIO module 3(3) */
#define OMAP44XX_IRQ_GPIO4_MPU OMAP44XX_HARDIRQ(32) /* GPIO module 4(3) */
#define OMAP44XX_IRQ_GPIO5_MPU OMAP44XX_HARDIRQ(33) /* GPIO module 5(3) */
#define OMAP44XX_IRQ_GPIO6_MPU OMAP44XX_HARDIRQ(34) /* GPIO module 6(3) */
#define OMAP44XX_IRQ_RESERVED35 OMAP44XX_HARDIRQ(35) /* RESERVED */
#define OMAP44XX_IRQ_WDT3 OMAP44XX_HARDIRQ(36) /* Watchdog timer module 3 overflow */
#define OMAP44XX_IRQ_GPT1 OMAP44XX_HARDIRQ(37) /* General-purpose timer module 1 */
#define OMAP44XX_IRQ_GPT2 OMAP44XX_HARDIRQ(38) /* General-purpose timer module 2 */
#define OMAP44XX_IRQ_GPT3 OMAP44XX_HARDIRQ(39) /* General-purpose timer module 3 */
#define OMAP44XX_IRQ_GPT4 OMAP44XX_HARDIRQ(40) /* General-purpose timer module 4 */
#define OMAP44XX_IRQ_GPT5 OMAP44XX_HARDIRQ(41) /* General-purpose timer module 5 */
#define OMAP44XX_IRQ_GPT6 OMAP44XX_HARDIRQ(42) /* General-purpose timer module 6 */
#define OMAP44XX_IRQ_GPT7 OMAP44XX_HARDIRQ(43) /* General-purpose timer module 7 */
#define OMAP44XX_IRQ_GPT8 OMAP44XX_HARDIRQ(44) /* General-purpose timer module 8 */
#define OMAP44XX_IRQ_GPT9 OMAP44XX_HARDIRQ(45) /* General-purpose timer module 9 */
#define OMAP44XX_IRQ_GPT10 OMAP44XX_HARDIRQ(46) /* General-purpose timer module 10 */
#define OMAP44XX_IRQ_GPT11 OMAP44XX_HARDIRQ(47) /* General-purpose timer module 11 */
#define OMAP44XX_IRQ_MCSPI4 OMAP44XX_HARDIRQ(48) /* McSPI module 4 */
#define OMAP44XX_IRQ_RESERVED49 OMAP44XX_HARDIRQ(49) /* RESERVED */
#define OMAP44XX_IRQ_RESERVED50 OMAP44XX_HARDIRQ(50) /* RESERVED */
#define OMAP44XX_IRQ_RESERVED51 OMAP44XX_HARDIRQ(51) /* RESERVED */
#define OMAP44XX_IRQ_RESERVED52 OMAP44XX_HARDIRQ(52) /* RESERVED */
#define OMAP44XX_IRQ_DSS_DSI1 OMAP44XX_HARDIRQ(53) /* Display Subsystem DSI1 interrupt */
#define OMAP44XX_IRQ_RESERVED54 OMAP44XX_HARDIRQ(54) /* RESERVED */
#define OMAP44XX_IRQ_RESERVED55 OMAP44XX_HARDIRQ(55) /* RESERVED */
#define OMAP44XX_IRQ_I2C1 OMAP44XX_HARDIRQ(56) /* I2C module 1 */
#define OMAP44XX_IRQ_I2C2 OMAP44XX_HARDIRQ(57) /* I2C module 2 */
#define OMAP44XX_IRQ_HDQ OMAP44XX_HARDIRQ(58) /* HDQ / One-wire */
#define OMAP44XX_IRQ_MMC5 OMAP44XX_HARDIRQ(59) /* MMC5 interrupt */
#define OMAP44XX_IRQ_RESERVED60 OMAP44XX_HARDIRQ(60) /* RESERVED */
#define OMAP44XX_IRQ_I2C3 OMAP44XX_HARDIRQ(61) /* I2C module 3 */
#define OMAP44XX_IRQ_I2C4 OMAP44XX_HARDIRQ(62) /* I2C module 4 */
#define OMAP44XX_IRQ_RESERVED63 OMAP44XX_HARDIRQ(63) /* RESERVED */
#define OMAP44XX_IRQ_RESERVED64 OMAP44XX_HARDIRQ(64) /* RESERVED */
#define OMAP44XX_IRQ_MCSPI1 OMAP44XX_HARDIRQ(65) /* McSPI module 1 */
#define OMAP44XX_IRQ_MCSPI2 OMAP44XX_HARDIRQ(66) /* McSPI module 2 */
#define OMAP44XX_IRQ_HSI_P1 OMAP44XX_HARDIRQ(67) /* HSI Port 1 interrupt */
#define OMAP44XX_IRQ_HSI_P2 OMAP44XX_HARDIRQ(68) /* HSI Port 2 interrupt */
#define OMAP44XX_IRQ_FDIF_3 OMAP44XX_HARDIRQ(69) /* Face detect interrupt 3 */
#define OMAP44XX_IRQ_UART4 OMAP44XX_HARDIRQ(70) /* UART module 4 interrupt */
#define OMAP44XX_IRQ_HSI_DMA OMAP44XX_HARDIRQ(71) /* HSI DMA engine MPU request */
#define OMAP44XX_IRQ_UART1 OMAP44XX_HARDIRQ(72) /* UART module 1 */
#define OMAP44XX_IRQ_UART2 OMAP44XX_HARDIRQ(73) /* UART module 2 */
#define OMAP44XX_IRQ_UART3 OMAP44XX_HARDIRQ(74) /* UART module 3 (also infrared)(3) */
#define OMAP44XX_IRQ_PBIAS OMAP44XX_HARDIRQ(75) /* Merged interrupt for PBIASlite1 and 2 */
#define OMAP44XX_IRQ_OHCI OMAP44XX_HARDIRQ(76) /* OHCI controller HSUSB MP Host Interrupt */
#define OMAP44XX_IRQ_EHCI OMAP44XX_HARDIRQ(77) /* EHCI controller HSUSB MP Host Interrupt */
#define OMAP44XX_IRQ_TLL OMAP44XX_HARDIRQ(78) /* HSUSB MP TLL Interrupt */
#define OMAP44XX_IRQ_RESERVED79 OMAP44XX_HARDIRQ(79) /* RESERVED */
#define OMAP44XX_IRQ_WDT2 OMAP44XX_HARDIRQ(80) /* WDTIMER2 interrupt */
#define OMAP44XX_IRQ_RESERVED81 OMAP44XX_HARDIRQ(81) /* RESERVED */
#define OMAP44XX_IRQ_RESERVED82 OMAP44XX_HARDIRQ(82) /* RESERVED */
#define OMAP44XX_IRQ_MMC1 OMAP44XX_HARDIRQ(83) /* MMC/SD module 1 */
#define OMAP44XX_IRQ_DSS_DSI2 OMAP44XX_HARDIRQ(84) /* Display subsystem DSI2 interrupt */
#define OMAP44XX_IRQ_RESERVED85 OMAP44XX_HARDIRQ(85) /* Reserved */
#define OMAP44XX_IRQ_MMC2 OMAP44XX_HARDIRQ(86) /* MMC/SD module 2 */
#define OMAP44XX_IRQ_MPU_ICR OMAP44XX_HARDIRQ(87) /* MPU ICR */
#define OMAP44XX_IRQ_C2C_GPI OMAP44XX_HARDIRQ(88) /* C2C GPI interrupt */
#define OMAP44XX_IRQ_FSUSB OMAP44XX_HARDIRQ(89) /* FS-USB - host controller Interrupt */
#define OMAP44XX_IRQ_FSUSB_SMI OMAP44XX_HARDIRQ(90) /* FS-USB - host controller SMI Interrupt */
#define OMAP44XX_IRQ_MCSPI3 OMAP44XX_HARDIRQ(91) /* McSPI module 3 */
#define OMAP44XX_IRQ_HSUSB_OTG OMAP44XX_HARDIRQ(92) /* High-Speed USB OTG controller */
#define OMAP44XX_IRQ_HSUSB_OTG_DMA OMAP44XX_HARDIRQ(93) /* High-Speed USB OTG DMA controller */
#define OMAP44XX_IRQ_MMC3 OMAP44XX_HARDIRQ(94) /* MMC/SD module 3 */
#define OMAP44XX_IRQ_RESERVED95 OMAP44XX_HARDIRQ(95) /* RESERVED */
#define OMAP44XX_IRQ_MMC4 OMAP44XX_HARDIRQ(96) /* MMC4 interrupt */
#define OMAP44XX_IRQ_SLIMBUS1 OMAP44XX_HARDIRQ(97) /* SLIMBUS1 interrupt */
#define OMAP44XX_IRQ_SLIMBUS2 OMAP44XX_HARDIRQ(98) /* SLIMBUS2 interrupt */
#define OMAP44XX_IRQ_ABE OMAP44XX_HARDIRQ(99) /* Audio back-end interrupt */
#define OMAP44XX_IRQ_CORTEXM3_MMU OMAP44XX_HARDIRQ(100) /* Cortex-M3 MMU interrupt */
#define OMAP44XX_IRQ_DSS_HDMI OMAP44XX_HARDIRQ(101) /* Display subsystem HDMI interrupt */
#define OMAP44XX_IRQ_SR_IVA OMAP44XX_HARDIRQ(102) /* SmartReflex IVA interrupt */
#define OMAP44XX_IRQ_IVAHD1 OMAP44XX_HARDIRQ(103) /* Sync interrupt from iCONT2 (vDMA) */
#define OMAP44XX_IRQ_IVAHD2 OMAP44XX_HARDIRQ(104) /* Sync interrupt from iCONT1 */
#define OMAP44XX_IRQ_RESERVED105 OMAP44XX_HARDIRQ(105) /* RESERVED */
#define OMAP44XX_IRQ_RESERVED106 OMAP44XX_HARDIRQ(106) /* RESERVED */
#define OMAP44XX_IRQ_IVAHD_MAILBOX0 OMAP44XX_HARDIRQ(107) /* IVAHD mailbox interrupt */
#define OMAP44XX_IRQ_RESERVED108 OMAP44XX_HARDIRQ(108) /* RESERVED */
#define OMAP44XX_IRQ_MCASP1 OMAP44XX_HARDIRQ(109) /* McASP1 transmit interrupt */
#define OMAP44XX_IRQ_EMIF1 OMAP44XX_HARDIRQ(110) /* EMIF1 interrupt */
#define OMAP44XX_IRQ_EMIF2 OMAP44XX_HARDIRQ(111) /* EMIF2 interrupt */
#define OMAP44XX_IRQ_MCPDM OMAP44XX_HARDIRQ(112) /* MCPDM interrupt */
#define OMAP44XX_IRQ_DMM OMAP44XX_HARDIRQ(113) /* DMM interrupt */
#define OMAP44XX_IRQ_DMIC OMAP44XX_HARDIRQ(114) /* DMIC interrupt */
#define OMAP44XX_IRQ_RESERVED115 OMAP44XX_HARDIRQ(115) /* RESERVED */
#define OMAP44XX_IRQ_RESERVED116 OMAP44XX_HARDIRQ(116) /* RESERVED */
#define OMAP44XX_IRQ_RESERVED117 OMAP44XX_HARDIRQ(117) /* RESERVED */
#define OMAP44XX_IRQ_RESERVED118 OMAP44XX_HARDIRQ(118) /* RESERVED */
#define OMAP44XX_IRQ_SYS_NIRQ2 OMAP44XX_HARDIRQ(119) /* External source 2 (active low) */
#define OMAP44XX_IRQ_KBD OMAP44XX_HARDIRQ(120) /* Keyboard controller interrupt */
#define OMAP44XX_IRQ_RESERVED121 OMAP44XX_HARDIRQ(121) /* RESERVED */
#define OMAP44XX_IRQ_RESERVED122 OMAP44XX_HARDIRQ(122) /* RESERVED */
#define OMAP44XX_IRQ_RESERVED123 OMAP44XX_HARDIRQ(123) /* RESERVED */
#define OMAP44XX_IRQ_RESERVED124 OMAP44XX_HARDIRQ(124) /* RESERVED */
#define OMAP44XX_IRQ_RESERVED125 OMAP44XX_HARDIRQ(125) /* RESERVED */
#define OMAP44XX_IRQ_RESERVED126 OMAP44XX_HARDIRQ(126) /* RESERVED */
#define OMAP44XX_IRQ_RESERVED127 OMAP44XX_HARDIRQ(127) /* RESERVED */
/*
* General Purpose Timers
*/
#define OMAP44XX_GPTIMER1_VBASE (OMAP44XX_L4_WAKEUP_VBASE + OMAP44XX_GPTIMER1_OFFSET)
#define OMAP44XX_GPTIMER1_HWBASE (OMAP44XX_L4_WAKEUP_HWBASE + OMAP44XX_GPTIMER1_OFFSET)
#define OMAP44XX_GPTIMER2_VBASE (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_GPTIMER2_OFFSET)
#define OMAP44XX_GPTIMER2_HWBASE (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_GPTIMER2_OFFSET)
#define OMAP44XX_GPTIMER3_VBASE (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_GPTIMER3_OFFSET)
#define OMAP44XX_GPTIMER3_HWBASE (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_GPTIMER3_OFFSET)
#define OMAP44XX_GPTIMER4_VBASE (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_GPTIMER4_OFFSET)
#define OMAP44XX_GPTIMER4_HWBASE (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_GPTIMER4_OFFSET)
#define OMAP44XX_GPTIMER5_VBASE (OMAP44XX_L4_ABE_VBASE + OMAP44XX_GPTIMER5_OFFSET)
#define OMAP44XX_GPTIMER5_HWBASE (OMAP44XX_L4_ABE_HWBASE + OMAP44XX_GPTIMER5_OFFSET)
#define OMAP44XX_GPTIMER6_VBASE (OMAP44XX_L4_ABE_VBASE + OMAP44XX_GPTIMER6_OFFSET)
#define OMAP44XX_GPTIMER6_HWBASE (OMAP44XX_L4_ABE_HWBASE + OMAP44XX_GPTIMER6_OFFSET)
#define OMAP44XX_GPTIMER7_VBASE (OMAP44XX_L4_ABE_VBASE + OMAP44XX_GPTIMER7_OFFSET)
#define OMAP44XX_GPTIMER7_HWBASE (OMAP44XX_L4_ABE_HWBASE + OMAP44XX_GPTIMER7_OFFSET)
#define OMAP44XX_GPTIMER8_VBASE (OMAP44XX_L4_ABE_VBASE + OMAP44XX_GPTIMER8_OFFSET)
#define OMAP44XX_GPTIMER8_HWBASE (OMAP44XX_L4_ABE_HWBASE + OMAP44XX_GPTIMER8_OFFSET)
#define OMAP44XX_GPTIMER9_VBASE (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_GPTIMER9_OFFSET)
#define OMAP44XX_GPTIMER9_HWBASE (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_GPTIMER9_OFFSET)
#define OMAP44XX_GPTIMER10_VBASE (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_GPTIMER10_OFFSET)
#define OMAP44XX_GPTIMER10_HWBASE (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_GPTIMER10_OFFSET)
#define OMAP44XX_GPTIMER11_VBASE (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_GPTIMER11_OFFSET)
#define OMAP44XX_GPTIMER11_HWBASE (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_GPTIMER11_OFFSET)
#define OMAP44XX_GPTIMER_SIZE 0x00001000UL
/*
* GPIO - General Purpose IO
*/
/* Base addresses for the GPIO modules */
#define OMAP44XX_GPIO1_HWBASE (OMAP44XX_L4_WAKEUP_HWBASE + OMAP44XX_GPIO1_OFFSET)
#define OMAP44XX_GPIO1_VBASE (OMAP44XX_L4_WAKEUP_VBASE + OMAP44XX_GPIO1_OFFSET)
#define OMAP44XX_GPIO1_SIZE 0x00001000UL
#define OMAP44XX_GPIO2_HWBASE (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_GPIO2_OFFSET)
#define OMAP44XX_GPIO2_VBASE (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_GPIO2_OFFSET)
#define OMAP44XX_GPIO2_SIZE 0x00001000UL
#define OMAP44XX_GPIO3_HWBASE (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_GPIO3_OFFSET)
#define OMAP44XX_GPIO3_VBASE (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_GPIO3_OFFSET)
#define OMAP44XX_GPIO3_SIZE 0x00001000UL
#define OMAP44XX_GPIO4_HWBASE (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_GPIO4_OFFSET)
#define OMAP44XX_GPIO4_VBASE (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_GPIO4_OFFSET)
#define OMAP44XX_GPIO4_SIZE 0x00001000UL
#define OMAP44XX_GPIO5_HWBASE (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_GPIO5_OFFSET)
#define OMAP44XX_GPIO5_VBASE (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_GPIO5_OFFSET)
#define OMAP44XX_GPIO5_SIZE 0x00001000UL
#define OMAP44XX_GPIO6_HWBASE (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_GPIO6_OFFSET)
#define OMAP44XX_GPIO6_VBASE (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_GPIO6_OFFSET)
#define OMAP44XX_GPIO6_SIZE 0x00001000UL
/*
* MMC/SD/SDIO
*/
/* Base addresses for the MMC/SD/SDIO modules */
#define OMAP44XX_MMCHS1_HWBASE (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_MMCHS1_OFFSET)
#define OMAP44XX_MMCHS1_VBASE (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_MMCHS1_OFFSET)
#define OMAP44XX_MMCHS2_HWBASE (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_MMCHS2_OFFSET)
#define OMAP44XX_MMCHS2_VBASE (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_MMCHS2_OFFSET)
#define OMAP44XX_MMCHS3_HWBASE (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_MMCSD3_OFFSET)
#define OMAP44XX_MMCHS3_VBASE (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_MMCSD3_OFFSET)
#define OMAP44XX_MMCHS4_HWBASE (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_MMCSD4_OFFSET)
#define OMAP44XX_MMCHS4_VBASE (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_MMCSD4_OFFSET)
#define OMAP44XX_MMCHS5_HWBASE (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_MMCSD5_OFFSET)
#define OMAP44XX_MMCHS5_VBASE (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_MMCSD5_OFFSET)
#define OMAP44XX_MMCHS_SIZE 0x00001000UL
/*
* SCM - System Control Module
*/
/* Base addresses for the SC modules */
#define OMAP44XX_SCM_PADCONF_HWBASE (OMAP44XX_L4_CORE_HWBASE + OMAP44XX_SCM_PADCONF_OFFSET)
#define OMAP44XX_SCM_PADCONF_VBASE (OMAP44XX_L4_CORE_VBASE + OMAP44XX_SCM_PADCONF_OFFSET)
#define OMAP44XX_SCM_PADCONF_SIZE 0x00001000UL
#endif /* _OMAP44XX_REG_H_ */

View File

@ -0,0 +1,405 @@
/*-
* Copyright (c) 2011
* Ben Gray <ben.r.gray@gmail.com>.
* 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 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 BEN GRAY ``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 BEN GRAY 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/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/frame.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <sys/gpio.h>
#include <arm/ti/tivar.h>
#include <arm/ti/ti_scm.h>
#include <arm/ti/omap4/omap4var.h>
#include <arm/ti/omap4/omap4_reg.h>
/*
* This file defines the pin mux configuration for the OMAP4xxx series of
* devices.
*
* How This is Suppose to Work
* ===========================
* - There is a top level ti_scm module (System Control Module) that is
* the interface for all omap drivers, which can use it to change the mux
* settings for individual pins. (That said, typically the pin mux settings
* are set to defaults by the 'hints' and then not altered by the driver).
*
* - For this to work the top level driver needs all the pin info, and hence
* this is where this file comes in. Here we define all the pin information
* that is supplied to the top level driver.
*
*/
#define CONTROL_PADCONF_WAKEUP_EVENT (1UL << 15)
#define CONTROL_PADCONF_WAKEUP_ENABLE (1UL << 14)
#define CONTROL_PADCONF_OFF_PULL_UP (1UL << 13)
#define CONTROL_PADCONF_OFF_PULL_ENABLE (1UL << 12)
#define CONTROL_PADCONF_OFF_OUT_HIGH (1UL << 11)
#define CONTROL_PADCONF_OFF_OUT_ENABLE (1UL << 10)
#define CONTROL_PADCONF_OFF_ENABLE (1UL << 9)
#define CONTROL_PADCONF_INPUT_ENABLE (1UL << 8)
#define CONTROL_PADCONF_PULL_UP (1UL << 4)
#define CONTROL_PADCONF_PULL_ENABLE (1UL << 3)
#define CONTROL_PADCONF_MUXMODE_MASK (0x7)
#define CONTROL_PADCONF_SATE_MASK ( CONTROL_PADCONF_WAKEUP_EVENT \
| CONTROL_PADCONF_WAKEUP_ENABLE \
| CONTROL_PADCONF_OFF_PULL_UP \
| CONTROL_PADCONF_OFF_PULL_ENABLE \
| CONTROL_PADCONF_OFF_OUT_HIGH \
| CONTROL_PADCONF_OFF_OUT_ENABLE \
| CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_INPUT_ENABLE \
| CONTROL_PADCONF_PULL_UP \
| CONTROL_PADCONF_PULL_ENABLE )
/* Active pin states */
#define PADCONF_PIN_OUTPUT 0
#define PADCONF_PIN_INPUT CONTROL_PADCONF_INPUT_ENABLE
#define PADCONF_PIN_INPUT_PULLUP ( CONTROL_PADCONF_INPUT_ENABLE \
| CONTROL_PADCONF_PULL_ENABLE \
| CONTROL_PADCONF_PULL_UP)
#define PADCONF_PIN_INPUT_PULLDOWN ( CONTROL_PADCONF_INPUT_ENABLE \
| CONTROL_PADCONF_PULL_ENABLE )
/* Off mode states */
#define PADCONF_PIN_OFF_NONE 0
#define PADCONF_PIN_OFF_OUTPUT_HIGH ( CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_OFF_OUT_ENABLE \
| CONTROL_PADCONF_OFF_OUT_HIGH)
#define PADCONF_PIN_OFF_OUTPUT_LOW ( CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_OFF_OUT_ENABLE)
#define PADCONF_PIN_OFF_INPUT_PULLUP ( CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_OFF_PULL_ENABLE \
| CONTROL_PADCONF_OFF_PULL_UP)
#define PADCONF_PIN_OFF_INPUT_PULLDOWN ( CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_OFF_PULL_ENABLE)
#define PADCONF_PIN_OFF_WAKEUPENABLE CONTROL_PADCONF_WAKEUP_ENABLE
#define _PINDEF(r, b, gp, gm, m0, m1, m2, m3, m4, m5, m6, m7) \
{ .reg_off = r, \
.gpio_pin = gp, \
.gpio_mode = gm, \
.ballname = b, \
.muxmodes[0] = m0, \
.muxmodes[1] = m1, \
.muxmodes[2] = m2, \
.muxmodes[3] = m3, \
.muxmodes[4] = m4, \
.muxmodes[5] = m5, \
.muxmodes[6] = m6, \
.muxmodes[7] = m7, \
}
const struct ti_scm_padstate ti_padstate_devmap[] = {
{"output", PADCONF_PIN_OUTPUT},
{"input", PADCONF_PIN_INPUT},
{"input_pullup", PADCONF_PIN_INPUT_PULLUP},
{"input_pulldown", PADCONF_PIN_INPUT_PULLDOWN},
{ .state = NULL }
};
/*
* Table 18-10, p. 3470
*/
const struct ti_scm_padconf ti_padconf_devmap[] = {
_PINDEF(0x0040, "c12", 0, 0, "gpmc_ad0", "sdmmc2_dat0", NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0042, "d12", 0, 0, "gpmc_ad1", "sdmmc2_dat1", NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0044, "c13", 0, 0, "gpmc_ad2", "sdmmc2_dat2", NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0046, "d13", 0, 0, "gpmc_ad3", "sdmmc2_dat3", NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0048, "c15", 0, 0, "gpmc_ad4", "sdmmc2_dat4", "sdmmc2_dir_dat0", NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x004a, "d15", 0, 0, "gpmc_ad5", "sdmmc2_dat5", "sdmmc2_dir_dat1", NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x004c, "a16", 0, 0, "gpmc_ad6", "sdmmc2_dat6", "sdmmc2_dir_cmd", NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x004e, "b16", 0, 0, "gpmc_ad7", "sdmmc2_dat7", "sdmmc2_clk_fdbk", NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0050, "c16", 32, 3, "gpmc_ad8", "kpd_row0", "c2c_data15", "gpio_32", NULL, "sdmmc1_dat0", NULL, NULL),
_PINDEF(0x0052, "d16", 33, 3, "gpmc_ad9", "kpd_row1", "c2c_data14", "gpio_33", NULL, "sdmmc1_dat1", NULL, NULL),
_PINDEF(0x0054, "c17", 34, 3, "gpmc_ad10", "kpd_row2", "c2c_data13", "gpio_34", NULL, "sdmmc1_dat2", NULL, NULL),
_PINDEF(0x0056, "d17", 35, 3, "gpmc_ad11", "kpd_row3", "c2c_data12", "gpio_35", NULL, "sdmmc1_dat3", NULL, NULL),
_PINDEF(0x0058, "c18", 36, 3, "gpmc_ad12", "kpd_col0", "c2c_data11", "gpio_36", NULL, "sdmmc1_dat4", NULL, NULL),
_PINDEF(0x005a, "d18", 37, 3, "gpmc_ad13", "kpd_col1", "c2c_data10", "gpio_37", NULL, "sdmmc1_dat5", NULL, NULL),
_PINDEF(0x005c, "c19", 38, 3, "gpmc_ad14", "kpd_col2", "c2c_data9", "gpio_38", NULL, "sdmmc1_dat6", NULL, NULL),
_PINDEF(0x005e, "d19", 39, 3, "gpmc_ad15", "kpd_col3", "c2c_data8", "gpio_39", NULL, "sdmmc1_dat7", NULL, NULL),
_PINDEF(0x0060, "b17", 40, 3, "gpmc_a16", "kpd_row4", "c2c_datain0", "gpio_40", "venc_656_data0", NULL, NULL, "safe_mode"),
_PINDEF(0x0062, "a18", 41, 3, "gpmc_a17", "kpd_row5", "c2c_datain1", "gpio_41", "venc_656_data1", NULL, NULL, "safe_mode"),
_PINDEF(0x0064, "b18", 42, 3, "gpmc_a18", "kpd_row6", "c2c_datain2", "gpio_42", "venc_656_data2", NULL, NULL, "safe_mode"),
_PINDEF(0x0066, "a19", 43, 3, "gpmc_a19", "kpd_row7", "c2c_datain3", "gpio_43", "venc_656_data3", NULL, NULL, "safe_mode"),
_PINDEF(0x0068, "b19", 44, 3, "gpmc_a20", "kpd_col4", "c2c_datain4", "gpio_44", "venc_656_data4", NULL, NULL, "safe_mode"),
_PINDEF(0x006a, "b20", 45, 3, "gpmc_a21", "kpd_col5", "c2c_datain5", "gpio_45", "venc_656_data5", NULL, NULL, "safe_mode"),
_PINDEF(0x006c, "a21", 46, 3, "gpmc_a22", "kpd_col6", "c2c_datain6", "gpio_46", "venc_656_data6", NULL, NULL, "safe_mode"),
_PINDEF(0x006e, "b21", 47, 3, "gpmc_a23", "kpd_col7", "c2c_datain7", "gpio_47", "venc_656_data7", NULL, NULL, "safe_mode"),
_PINDEF(0x0070, "c20", 48, 3, "gpmc_a24", "kpd_col8", "c2c_clkout0", "gpio_48", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0072, "d20", 49, 3, "gpmc_a25", NULL, "c2c_clkout1", "gpio_49", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0074, "b25", 50, 3, "gpmc_ncs0", NULL, NULL, "gpio_50", "sys_ndmareq0", NULL, NULL, NULL),
_PINDEF(0x0076, "c21", 51, 3, "gpmc_ncs1", NULL, "c2c_dataout6", "gpio_51", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0078, "d21", 52, 3, "gpmc_ncs2", "kpd_row8", "c2c_dataout7", "gpio_52", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x007a, "c22", 53, 3, "gpmc_ncs3", "gpmc_dir", "c2c_dataout4", "gpio_53", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x007c, "c25", 54, 3, "gpmc_nwp", "dsi1_te0", NULL, "gpio_54", "sys_ndmareq1", NULL, NULL, NULL),
_PINDEF(0x007e, "b22", 55, 3, "gpmc_clk", NULL, NULL, "gpio_55", "sys_ndmareq2", "sdmmc1_cmd", NULL, NULL),
_PINDEF(0x0080, "d25", 56, 3, "gpmc_nadv_ale", "dsi1_te1", NULL, "gpio_56", "sys_ndmareq3", "sdmmc1_clk", NULL, NULL),
_PINDEF(0x0082, "b11", 0, 0, "gpmc_noe", "sdmmc2_clk", NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0084, "b12", 0, 0, "gpmc_nwe", "sdmmc2_cmd", NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0086, "c23", 59, 3, "gpmc_nbe0_cle", "dsi2_te0", NULL, "gpio_59", NULL, NULL, NULL, NULL),
_PINDEF(0x0088, "d22", 60, 3, "gpmc_nbe1", NULL, "c2c_dataout5", "gpio_60", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x008a, "b26", 61, 3, "gpmc_wait0", "dsi2_te1", NULL, "gpio_61", NULL, NULL, NULL, NULL),
_PINDEF(0x008c, "b23", 62, 3, "gpmc_wait1", NULL, "c2c_dataout2", "gpio_62", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x008e, "d23", 100, 3, "gpmc_wait2", "usbc1_icusb_txen", "c2c_dataout3", "gpio_100", "sys_ndmareq0", NULL, NULL, "safe_mode"),
_PINDEF(0x0090, "a24", 101, 3, "gpmc_ncs4", "dsi1_te0", "c2c_clkin0", "gpio_101", "sys_ndmareq1", NULL, NULL, "safe_mode"),
_PINDEF(0x0092, "b24", 102, 3, "gpmc_ncs5", "dsi1_te1", "c2c_clkin1", "gpio_102", "sys_ndmareq2", NULL, NULL, "safe_mode"),
_PINDEF(0x0094, "c24", 103, 3, "gpmc_ncs6", "dsi2_te0", "c2c_dataout0", "gpio_103", "sys_ndmareq3", NULL, NULL, "safe_mode"),
_PINDEF(0x0096, "d24", 104, 3, "gpmc_ncs7", "dsi2_te1", "c2c_dataout1", "gpio_104", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0098, "b9", 63, 3, "hdmi_hpd", NULL, NULL, "gpio_63", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x009a, "b10", 64, 3, "hdmi_cec", NULL, NULL, "gpio_64", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x009c, "a8", 65, 3, "hdmi_ddc_scl", NULL, NULL, "gpio_65", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x009e, "b8", 66, 3, "hdmi_ddc_sda", NULL, NULL, "gpio_66", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00a0, "r26", 0, 0, "csi21_dx0", NULL, NULL, "gpi_67", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00a2, "r25", 0, 0, "csi21_dy0", NULL, NULL, "gpi_68", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00a4, "t26", 0, 0, "csi21_dx1", NULL, NULL, "gpi_69", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00a6, "t25", 0, 0, "csi21_dy1", NULL, NULL, "gpi_70", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00a8, "u26", 0, 0, "csi21_dx2", NULL, NULL, "gpi_71", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00aa, "u25", 0, 0, "csi21_dy2", NULL, NULL, "gpi_72", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00ac, "v26", 0, 0, "csi21_dx3", NULL, NULL, "gpi_73", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00ae, "v25", 0, 0, "csi21_dy3", NULL, NULL, "gpi_74", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00b0, "w26", 0, 0, "csi21_dx4", NULL, NULL, "gpi_75", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00b2, "w25", 0, 0, "csi21_dy4", NULL, NULL, "gpi_76", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00b4, "m26", 0, 0, "csi22_dx0", NULL, NULL, "gpi_77", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00b6, "m25", 0, 0, "csi22_dy0", NULL, NULL, "gpi_78", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00b8, "n26", 0, 0, "csi22_dx1", NULL, NULL, "gpi_79", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00ba, "n25", 0, 0, "csi22_dy1", NULL, NULL, "gpi_80", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00bc, "t27", 81, 3, "cam_shutter", NULL, NULL, "gpio_81", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00be, "u27", 82, 3, "cam_strobe", NULL, NULL, "gpio_82", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00c0, "v27", 83, 3, "cam_globalreset", NULL, NULL, "gpio_83", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00c2, "ae18", 84, 3, "usbb1_ulpitll_clk", "hsi1_cawake", NULL, "gpio_84", "usbb1_ulpiphy_clk", NULL, "hw_dbg20", "safe_mode"),
_PINDEF(0x00c4, "ag19", 85, 3, "usbb1_ulpitll_stp", "hsi1_cadata", "mcbsp4_clkr", "gpio_85", "usbb1_ulpiphy_stp", "usbb1_mm_rxdp", "hw_dbg21", "safe_mode"),
_PINDEF(0x00c6, "af19", 86, 3, "usbb1_ulpitll_dir", "hsi1_caflag", "mcbsp4_fsr", "gpio_86", "usbb1_ulpiphy_dir", NULL, "hw_dbg22", "safe_mode"),
_PINDEF(0x00c8, "ae19", 87, 3, "usbb1_ulpitll_nxt", "hsi1_acready", "mcbsp4_fsx", "gpio_87", "usbb1_ulpiphy_nxt", "usbb1_mm_rxdm", "hw_dbg23", "safe_mode"),
_PINDEF(0x00ca, "af18", 88, 3, "usbb1_ulpitll_dat0", "hsi1_acwake", "mcbsp4_clkx", "gpio_88", "usbb1_ulpiphy_dat0", "usbb1_mm_txen", "hw_dbg24", "safe_mode"),
_PINDEF(0x00cc, "ag18", 89, 3, "usbb1_ulpitll_dat1", "hsi1_acdata", "mcbsp4_dx", "gpio_89", "usbb1_ulpiphy_dat1", "usbb1_mm_txdat", "hw_dbg25", "safe_mode"),
_PINDEF(0x00ce, "ae17", 90, 3, "usbb1_ulpitll_dat2", "hsi1_acflag", "mcbsp4_dr", "gpio_90", "usbb1_ulpiphy_dat2", "usbb1_mm_txse0", "hw_dbg26", "safe_mode"),
_PINDEF(0x00d0, "af17", 91, 3, "usbb1_ulpitll_dat3", "hsi1_caready", NULL, "gpio_91", "usbb1_ulpiphy_dat3", "usbb1_mm_rxrcv", "hw_dbg27", "safe_mode"),
_PINDEF(0x00d2, "ah17", 92, 3, "usbb1_ulpitll_dat4", "dmtimer8_pwm_evt", "abe_mcbsp3_dr", "gpio_92", "usbb1_ulpiphy_dat4", NULL, "hw_dbg28", "safe_mode"),
_PINDEF(0x00d4, "ae16", 93, 3, "usbb1_ulpitll_dat5", "dmtimer9_pwm_evt", "abe_mcbsp3_dx", "gpio_93", "usbb1_ulpiphy_dat5", NULL, "hw_dbg29", "safe_mode"),
_PINDEF(0x00d6, "af16", 94, 3, "usbb1_ulpitll_dat6", "dmtimer10_pwm_evt", "abe_mcbsp3_clkx", "gpio_94", "usbb1_ulpiphy_dat6", "abe_dmic_din3", "hw_dbg30", "safe_mode"),
_PINDEF(0x00d8, "ag16", 95, 3, "usbb1_ulpitll_dat7", "dmtimer11_pwm_evt", "abe_mcbsp3_fsx", "gpio_95", "usbb1_ulpiphy_dat7", "abe_dmic_clk3", "hw_dbg31", "safe_mode"),
_PINDEF(0x00da, "af14", 96, 3, "usbb1_hsic_data", NULL, NULL, "gpio_96", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00dc, "ae14", 97, 3, "usbb1_hsic_strobe", NULL, NULL, "gpio_97", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00de, "h2", 98, 3, "usbc1_icusb_dp", NULL, NULL, "gpio_98", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00e0, "h3", 99, 3, "usbc1_icusb_dm", NULL, NULL, "gpio_99", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00e2, "d2", 100, 3, "sdmmc1_clk", NULL, "dpm_emu19", "gpio_100", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00e4, "e3", 101, 3, "sdmmc1_cmd", NULL, "uart1_rx", "gpio_101", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00e6, "e4", 102, 3, "sdmmc1_dat0", NULL, "dpm_emu18", "gpio_102", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00e8, "e2", 103, 3, "sdmmc1_dat1", NULL, "dpm_emu17", "gpio_103", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00ea, "e1", 104, 3, "sdmmc1_dat2", NULL, "dpm_emu16", "gpio_104", "jtag_tms_tmsc", NULL, NULL, "safe_mode"),
_PINDEF(0x00ec, "f4", 105, 3, "sdmmc1_dat3", NULL, "dpm_emu15", "gpio_105", "jtag_tck", NULL, NULL, "safe_mode"),
_PINDEF(0x00ee, "f3", 106, 3, "sdmmc1_dat4", NULL, NULL, "gpio_106", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00f0, "f1", 107, 3, "sdmmc1_dat5", NULL, NULL, "gpio_107", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00f2, "g4", 108, 3, "sdmmc1_dat6", NULL, NULL, "gpio_108", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00f4, "g3", 109, 3, "sdmmc1_dat7", NULL, NULL, "gpio_109", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00f6, "ad27", 110, 3, "abe_mcbsp2_clkx", "mcspi2_clk", "abe_mcasp_ahclkx", "gpio_110", "usbb2_mm_rxdm", NULL, NULL, "safe_mode"),
_PINDEF(0x00f8, "ad26", 111, 3, "abe_mcbsp2_dr", "mcspi2_somi", "abe_mcasp_axr", "gpio_111", "usbb2_mm_rxdp", NULL, NULL, "safe_mode"),
_PINDEF(0x00fa, "ad25", 112, 3, "abe_mcbsp2_dx", "mcspi2_simo", "abe_mcasp_amute", "gpio_112", "usbb2_mm_rxrcv", NULL, NULL, "safe_mode"),
_PINDEF(0x00fc, "ac28", 113, 3, "abe_mcbsp2_fsx", "mcspi2_cs0", "abe_mcasp_afsx", "gpio_113", "usbb2_mm_txen", NULL, NULL, "safe_mode"),
_PINDEF(0x00fe, "ac26", 114, 3, "abe_mcbsp1_clkx", "abe_slimbus1_clock", NULL, "gpio_114", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0100, "ac25", 115, 3, "abe_mcbsp1_dr", "abe_slimbus1_data", NULL, "gpio_115", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0102, "ab25", 116, 3, "abe_mcbsp1_dx", "sdmmc3_dat2", "abe_mcasp_aclkx", "gpio_116", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0104, "ac27", 117, 3, "abe_mcbsp1_fsx", "sdmmc3_dat3", "abe_mcasp_amutein", "gpio_117", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0106, "ag25", 0, 0, "abe_pdm_ul_data", "abe_mcbsp3_dr", NULL, NULL, NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0108, "af25", 0, 0, "abe_pdm_dl_data", "abe_mcbsp3_dx", NULL, NULL, NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x010a, "ae25", 0, 0, "abe_pdm_frame", "abe_mcbsp3_clkx", NULL, NULL, NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x010c, "af26", 0, 0, "abe_pdm_lb_clk", "abe_mcbsp3_fsx", NULL, NULL, NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x010e, "ah26", 118, 3, "abe_clks", NULL, NULL, "gpio_118", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0110, "ae24", 119, 3, "abe_dmic_clk1", NULL, NULL, "gpio_119", "usbb2_mm_txse0", "uart4_cts", NULL, "safe_mode"),
_PINDEF(0x0112, "af24", 120, 3, "abe_dmic_din1", NULL, NULL, "gpio_120", "usbb2_mm_txdat", "uart4_rts", NULL, "safe_mode"),
_PINDEF(0x0114, "ag24", 121, 3, "abe_dmic_din2", "slimbus2_clock", "abe_mcasp_axr", "gpio_121", NULL, "dmtimer11_pwm_evt", NULL, "safe_mode"),
_PINDEF(0x0116, "ah24", 122, 3, "abe_dmic_din3", "slimbus2_data", "abe_dmic_clk2", "gpio_122", NULL, "dmtimer9_pwm_evt", NULL, "safe_mode"),
_PINDEF(0x0118, "ab26", 123, 3, "uart2_cts", "sdmmc3_clk", NULL, "gpio_123", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x011a, "ab27", 124, 3, "uart2_rts", "sdmmc3_cmd", NULL, "gpio_124", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x011c, "aa25", 125, 3, "uart2_rx", "sdmmc3_dat0", NULL, "gpio_125", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x011e, "aa26", 126, 3, "uart2_tx", "sdmmc3_dat1", NULL, "gpio_126", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0120, "aa27", 127, 3, "hdq_sio", "i2c3_sccb", "i2c2_sccb", "gpio_127", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0122, "ae28", 0, 0, "i2c1_scl", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0124, "ae26", 0, 0, "i2c1_sda", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0126, "c26", 128, 3, "i2c2_scl", "uart1_rx", NULL, "gpio_128", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0128, "d26", 129, 3, "i2c2_sda", "uart1_tx", NULL, "gpio_129", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x012a, "w27", 130, 3, "i2c3_scl", NULL, NULL, "gpio_130", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x012c, "y27", 131, 3, "i2c3_sda", NULL, NULL, "gpio_131", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x012e, "ag21", 132, 3, "i2c4_scl", NULL, NULL, "gpio_132", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0130, "ah22", 133, 3, "i2c4_sda", NULL, NULL, "gpio_133", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0132, "af22", 134, 3, "mcspi1_clk", NULL, NULL, "gpio_134", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0134, "ae22", 135, 3, "mcspi1_somi", NULL, NULL, "gpio_135", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0136, "ag22", 136, 3, "mcspi1_simo", NULL, NULL, "gpio_136", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0138, "ae23", 137, 3, "mcspi1_cs0", NULL, NULL, "gpio_137", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x013a, "af23", 138, 3, "mcspi1_cs1", "uart1_rx", NULL, "gpio_138", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x013c, "ag23", 139, 3, "mcspi1_cs2", "uart1_cts", "slimbus2_clock", "gpio_139", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x013e, "ah23", 140, 3, "mcspi1_cs3", "uart1_rts", "slimbus2_data", "gpio_140", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0140, "f27", 141, 3, "uart3_cts_rctx", "uart1_tx", NULL, "gpio_141", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0142, "f28", 142, 3, "uart3_rts_sd", NULL, NULL, "gpio_142", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0144, "g27", 143, 3, "uart3_rx_irrx", "dmtimer8_pwm_evt", NULL, "gpio_143", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0146, "g28", 144, 3, "uart3_tx_irtx", "dmtimer9_pwm_evt", NULL, "gpio_144", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0148, "ae5", 145, 3, "sdmmc5_clk", "mcspi2_clk", "usbc1_icusb_dp", "gpio_145", NULL, "sdmmc2_clk", NULL, "safe_mode"),
_PINDEF(0x014a, "af5", 146, 3, "sdmmc5_cmd", "mcspi2_simo", "usbc1_icusb_dm", "gpio_146", NULL, "sdmmc2_cmd", NULL, "safe_mode"),
_PINDEF(0x014c, "ae4", 147, 3, "sdmmc5_dat0", "mcspi2_somi", "usbc1_icusb_rcv", "gpio_147", NULL, "sdmmc2_dat0", NULL, "safe_mode"),
_PINDEF(0x014e, "af4", 148, 3, "sdmmc5_dat1", NULL, "usbc1_icusb_txen", "gpio_148", NULL, "sdmmc2_dat1", NULL, "safe_mode"),
_PINDEF(0x0150, "ag3", 149, 3, "sdmmc5_dat2", "mcspi2_cs1", NULL, "gpio_149", NULL, "sdmmc2_dat2", NULL, "safe_mode"),
_PINDEF(0x0152, "af3", 150, 3, "sdmmc5_dat3", "mcspi2_cs0", NULL, "gpio_150", NULL, "sdmmc2_dat3", NULL, "safe_mode"),
_PINDEF(0x0154, "ae21", 151, 3, "mcspi4_clk", "sdmmc4_clk", "kpd_col6", "gpio_151", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0156, "af20", 152, 3, "mcspi4_simo", "sdmmc4_cmd", "kpd_col7", "gpio_152", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0158, "af21", 153, 3, "mcspi4_somi", "sdmmc4_dat0", "kpd_row6", "gpio_153", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x015a, "ae20", 154, 3, "mcspi4_cs0", "sdmmc4_dat3", "kpd_row7", "gpio_154", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x015c, "ag20", 155, 3, "uart4_rx", "sdmmc4_dat2", "kpd_row8", "gpio_155", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x015e, "ah19", 156, 3, "uart4_tx", "sdmmc4_dat1", "kpd_col8", "gpio_156", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0160, "ag12", 157, 3, "usbb2_ulpitll_clk", "usbb2_ulpiphy_clk", "sdmmc4_cmd", "gpio_157", "hsi2_cawake", NULL, NULL, "safe_mode"),
_PINDEF(0x0162, "af12", 158, 3, "usbb2_ulpitll_stp", "usbb2_ulpiphy_stp", "sdmmc4_clk", "gpio_158", "hsi2_cadata", "dispc2_data23", NULL, "safe_mode"),
_PINDEF(0x0164, "ae12", 159, 3, "usbb2_ulpitll_dir", "usbb2_ulpiphy_dir", "sdmmc4_dat0", "gpio_159", "hsi2_caflag", "dispc2_data22", NULL, "safe_mode"),
_PINDEF(0x0166, "ag13", 160, 3, "usbb2_ulpitll_nxt", "usbb2_ulpiphy_nxt", "sdmmc4_dat1", "gpio_160", "hsi2_acready", "dispc2_data21", NULL, "safe_mode"),
_PINDEF(0x0168, "ae11", 161, 3, "usbb2_ulpitll_dat0", "usbb2_ulpiphy_dat0", "sdmmc4_dat2", "gpio_161", "hsi2_acwake", "dispc2_data20", "usbb2_mm_txen", "safe_mode"),
_PINDEF(0x016a, "af11", 162, 3, "usbb2_ulpitll_dat1", "usbb2_ulpiphy_dat1", "sdmmc4_dat3", "gpio_162", "hsi2_acdata", "dispc2_data19", "usbb2_mm_txdat", "safe_mode"),
_PINDEF(0x016c, "ag11", 163, 3, "usbb2_ulpitll_dat2", "usbb2_ulpiphy_dat2", "sdmmc3_dat2", "gpio_163", "hsi2_acflag", "dispc2_data18", "usbb2_mm_txse0", "safe_mode"),
_PINDEF(0x016e, "ah11", 164, 3, "usbb2_ulpitll_dat3", "usbb2_ulpiphy_dat3", "sdmmc3_dat1", "gpio_164", "hsi2_caready", "dispc2_data15", "rfbi_data15", "safe_mode"),
_PINDEF(0x0170, "ae10", 165, 3, "usbb2_ulpitll_dat4", "usbb2_ulpiphy_dat4", "sdmmc3_dat0", "gpio_165", "mcspi3_somi", "dispc2_data14", "rfbi_data14", "safe_mode"),
_PINDEF(0x0172, "af10", 166, 3, "usbb2_ulpitll_dat5", "usbb2_ulpiphy_dat5", "sdmmc3_dat3", "gpio_166", "mcspi3_cs0", "dispc2_data13", "rfbi_data13", "safe_mode"),
_PINDEF(0x0174, "ag10", 167, 3, "usbb2_ulpitll_dat6", "usbb2_ulpiphy_dat6", "sdmmc3_cmd", "gpio_167", "mcspi3_simo", "dispc2_data12", "rfbi_data12", "safe_mode"),
_PINDEF(0x0176, "ae9", 168, 3, "usbb2_ulpitll_dat7", "usbb2_ulpiphy_dat7", "sdmmc3_clk", "gpio_168", "mcspi3_clk", "dispc2_data11", "rfbi_data11", "safe_mode"),
_PINDEF(0x0178, "af13", 169, 3, "usbb2_hsic_data", NULL, NULL, "gpio_169", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x017a, "ae13", 170, 3, "usbb2_hsic_strobe", NULL, NULL, "gpio_170", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x017c, "g26", 171, 3, "kpd_col3", "kpd_col0", NULL, "gpio_171", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x017e, "g25", 172, 3, "kpd_col4", "kpd_col1", NULL, "gpio_172", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0180, "h26", 173, 3, "kpd_col5", "kpd_col2", NULL, "gpio_173", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0182, "h25", 174, 3, "kpd_col0", "kpd_col3", NULL, "gpio_174", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0184, "j27", 0, 0, "kpd_col1", "kpd_col4", NULL, "gpio_0", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0186, "h27", 1, 3, "kpd_col2", "kpd_col5", NULL, "gpio_1", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0188, "j26", 175, 3, "kpd_row3", "kpd_row0", NULL, "gpio_175", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x018a, "j25", 176, 3, "kpd_row4", "kpd_row1", NULL, "gpio_176", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x018c, "k26", 177, 3, "kpd_row5", "kpd_row2", NULL, "gpio_177", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x018e, "k25", 178, 3, "kpd_row0", "kpd_row3", NULL, "gpio_178", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0190, "l27", 2, 3, "kpd_row1", "kpd_row4", NULL, "gpio_2", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0192, "k27", 3, 3, "kpd_row2", "kpd_row5", NULL, "gpio_3", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0194, "c3", 0, 0, "usba0_otg_ce", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0196, "b5", 0, 0, "usba0_otg_dp", "uart3_rx_irrx", "uart2_rx", NULL, NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0198, "b4", 0, 0, "usba0_otg_dm", "uart3_tx_irtx", "uart2_tx", NULL, NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x019a, "aa28", 181, 3, "fref_clk1_out", NULL, NULL, "gpio_181", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x019c, "y28", 182, 3, "fref_clk2_out", NULL, NULL, "gpio_182", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x019e, "ae6", 0, 0, "sys_nirq1", NULL, NULL, NULL, NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x01a0, "af6", 183, 3, "sys_nirq2", NULL, NULL, "gpio_183", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x01a2, "f26", 184, 3, "sys_boot0", NULL, NULL, "gpio_184", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x01a4, "e27", 185, 3, "sys_boot1", NULL, NULL, "gpio_185", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x01a6, "e26", 186, 3, "sys_boot2", NULL, NULL, "gpio_186", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x01a8, "e25", 187, 3, "sys_boot3", NULL, NULL, "gpio_187", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x01aa, "d28", 188, 3, "sys_boot4", NULL, NULL, "gpio_188", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x01ac, "d27", 189, 3, "sys_boot5", NULL, NULL, "gpio_189", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x01ae, "m2", 11, 3, "dpm_emu0", NULL, NULL, "gpio_11", NULL, NULL, "hw_dbg0", "safe_mode"),
_PINDEF(0x01b0, "n2", 12, 3, "dpm_emu1", NULL, NULL, "gpio_12", NULL, NULL, "hw_dbg1", "safe_mode"),
_PINDEF(0x01b2, "p2", 13, 3, "dpm_emu2", "usba0_ulpiphy_clk", NULL, "gpio_13", NULL, "dispc2_fid", "hw_dbg2", "safe_mode"),
_PINDEF(0x01b4, "v1", 14, 3, "dpm_emu3", "usba0_ulpiphy_stp", NULL, "gpio_14", "rfbi_data10", "dispc2_data10", "hw_dbg3", "safe_mode"),
_PINDEF(0x01b6, "v2", 15, 3, "dpm_emu4", "usba0_ulpiphy_dir", NULL, "gpio_15", "rfbi_data9", "dispc2_data9", "hw_dbg4", "safe_mode"),
_PINDEF(0x01b8, "w1", 16, 3, "dpm_emu5", "usba0_ulpiphy_nxt", NULL, "gpio_16", "rfbi_te_vsync0", "dispc2_data16", "hw_dbg5", "safe_mode"),
_PINDEF(0x01ba, "w2", 17, 3, "dpm_emu6", "usba0_ulpiphy_dat0", "uart3_tx_irtx", "gpio_17", "rfbi_hsync0", "dispc2_data17", "hw_dbg6", "safe_mode"),
_PINDEF(0x01bc, "w3", 18, 3, "dpm_emu7", "usba0_ulpiphy_dat1", "uart3_rx_irrx", "gpio_18", "rfbi_cs0", "dispc2_hsync", "hw_dbg7", "safe_mode"),
_PINDEF(0x01be, "w4", 19, 3, "dpm_emu8", "usba0_ulpiphy_dat2", "uart3_rts_sd", "gpio_19", "rfbi_re", "dispc2_pclk", "hw_dbg8", "safe_mode"),
_PINDEF(0x01c0, "y2", 20, 3, "dpm_emu9", "usba0_ulpiphy_dat3", "uart3_cts_rctx", "gpio_20", "rfbi_we", "dispc2_vsync", "hw_dbg9", "safe_mode"),
_PINDEF(0x01c2, "y3", 21, 3, "dpm_emu10", "usba0_ulpiphy_dat4", NULL, "gpio_21", "rfbi_a0", "dispc2_de", "hw_dbg10", "safe_mode"),
_PINDEF(0x01c4, "y4", 22, 3, "dpm_emu11", "usba0_ulpiphy_dat5", NULL, "gpio_22", "rfbi_data8", "dispc2_data8", "hw_dbg11", "safe_mode"),
_PINDEF(0x01c6, "aa1", 23, 3, "dpm_emu12", "usba0_ulpiphy_dat6", NULL, "gpio_23", "rfbi_data7", "dispc2_data7", "hw_dbg12", "safe_mode"),
_PINDEF(0x01c8, "aa2", 24, 3, "dpm_emu13", "usba0_ulpiphy_dat7", NULL, "gpio_24", "rfbi_data6", "dispc2_data6", "hw_dbg13", "safe_mode"),
_PINDEF(0x01ca, "aa3", 25, 3, "dpm_emu14", "sys_drm_msecure", "uart1_rx", "gpio_25", "rfbi_data5", "dispc2_data5", "hw_dbg14", "safe_mode"),
_PINDEF(0x01cc, "aa4", 26, 3, "dpm_emu15", "sys_secure_indicator", NULL, "gpio_26", "rfbi_data4", "dispc2_data4", "hw_dbg15", "safe_mode"),
_PINDEF(0x01ce, "ab2", 27, 3, "dpm_emu16", "dmtimer8_pwm_evt", "dsi1_te0", "gpio_27", "rfbi_data3", "dispc2_data3", "hw_dbg16", "safe_mode"),
_PINDEF(0x01d0, "ab3", 28, 3, "dpm_emu17", "dmtimer9_pwm_evt", "dsi1_te1", "gpio_28", "rfbi_data2", "dispc2_data2", "hw_dbg17", "safe_mode"),
_PINDEF(0x01d2, "ab4", 190, 3, "dpm_emu18", "dmtimer10_pwm_evt", "dsi2_te0", "gpio_190", "rfbi_data1", "dispc2_data1", "hw_dbg18", "safe_mode"),
_PINDEF(0x01d4, "ac4", 191, 3, "dpm_emu19", "dmtimer11_pwm_evt", "dsi2_te1", "gpio_191", "rfbi_data0", "dispc2_data0", "hw_dbg19", "safe_mode"),
{ .ballname = NULL },
};
const struct ti_scm_device ti_scm_dev = {
.padconf_muxmode_mask = CONTROL_PADCONF_MUXMODE_MASK,
.padconf_sate_mask = CONTROL_PADCONF_SATE_MASK,
.padstate = (struct ti_scm_padstate *) &ti_padstate_devmap,
.padconf = (struct ti_scm_padconf *) &ti_padconf_devmap,
};
int
ti_scm_padconf_set_gpioflags(uint32_t gpio, uint32_t flags)
{
unsigned int state = 0;
/* First the SCM driver needs to be told to put the pad into GPIO mode */
if (flags & GPIO_PIN_OUTPUT)
state = PADCONF_PIN_OUTPUT;
else if (flags & GPIO_PIN_INPUT) {
if (flags & GPIO_PIN_PULLUP)
state = PADCONF_PIN_INPUT_PULLUP;
else if (flags & GPIO_PIN_PULLDOWN)
state = PADCONF_PIN_INPUT_PULLDOWN;
else
state = PADCONF_PIN_INPUT;
}
return ti_scm_padconf_set_gpiomode(gpio, state);
}
void
ti_scm_padconf_get_gpioflags(uint32_t gpio, uint32_t *flags)
{
unsigned int state;
/* Get the current pin state */
if (ti_scm_padconf_get_gpiomode(gpio, &state) != 0)
*flags = 0;
else {
switch (state) {
case PADCONF_PIN_OUTPUT:
*flags = GPIO_PIN_OUTPUT;
break;
case PADCONF_PIN_INPUT:
*flags = GPIO_PIN_INPUT;
break;
case PADCONF_PIN_INPUT_PULLUP:
*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLUP;
break;
case PADCONF_PIN_INPUT_PULLDOWN:
*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLDOWN;
break;
default:
*flags = 0;
break;
}
}
}

View File

@ -0,0 +1,52 @@
/*-
* Copyright (c) 2012 Olivier Houchard. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* $FreeBSD$
*/
#ifndef OMAP4_SMC_H_
#define OMAP4_SMC_H_
/* Define the various function IDs used by the OMAP4 */
#define L2CACHE_WRITE_DEBUG_REG 0x100
#define L2CACHE_CLEAN_INV_RANG 0x101
#define L2CACHE_ENABLE_L2 0x102
#define READ_AUX_CORE_REGS 0x103
#define MODIFY_AUX_CORE_0 0x104
#define WRITE_AUX_CORE_1 0x105
#define READ_WKG_CTRL_REG 0x106
#define CLEAR_WKG_CTRL_REG 0x107
#define SET_POWER_STATUS_REG 0x108
#define WRITE_AUXCTRL_REG 0x109
#define LOCKDOWN_TLB 0x10a
#define SELECT_TLB_ENTRY_FOR_WRITE 0x10b
#define READ_TLB_VA_ENTRY 0x10c
#define WRITE_TLB_VA_ENTRY 0x10d
#define READ_TLB_PA_ENTRY 0x10e
#define WRITE_TLB_PA_ENTRY 0x10f
#define READ_TLB_ATTR_ENTRY 0x110
#define WRITE_TLB_ATTR_ENTRY 0x111
#define WRITE_LATENCY_CTRL_REG 0x112
#define WRITE_PREFETCH_CTRL_REG 0x113
#endif /* OMAP4_SMC_H_ */

View File

@ -0,0 +1,91 @@
/*-
* Copyright (c) 2010
* Ben Gray <ben.r.gray@gmail.com>.
* 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 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 BEN GRAY ``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 BEN GRAY 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 _OMAP4VAR_H_
#define _OMAP4VAR_H_
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/time.h>
#include <sys/bus.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/sysctl.h>
#include <sys/endian.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
void omap4_mask_all_intr(void);
void omap4_post_filter_intr(void *arg);
struct omap4_softc {
device_t sc_dev;
bus_space_tag_t sc_iotag;
/* Handles for the two generic interrupt controller (GIC) register mappings */
bus_space_handle_t sc_gic_cpu_ioh;
bus_space_handle_t sc_gic_dist_ioh;
/* Handle for the PL310 L2 cache controller */
bus_space_handle_t sc_pl310_ioh;
/* Handle for the global and provate timer register set in the Cortex core */
bus_space_handle_t sc_prv_timer_ioh;
bus_space_handle_t sc_gbl_timer_ioh;
/* SCM access */
struct resource *sc_scm_mem;
int sc_scm_rid;
};
struct omap4_intr_conf {
int num;
unsigned int priority;
unsigned int target_cpu;
};
int omap4_setup_intr_controller(device_t dev,
const struct omap4_intr_conf *irqs);
int omap4_setup_gic_cpu(unsigned int prio_mask);
void omap4_init_timer(device_t dev);
int omap4_setup_l2cache_controller(struct omap4_softc *sc);
void omap4_smc_call(uint32_t fn, uint32_t arg);
#endif /* _OMAP4VAR_H_ */

View File

@ -0,0 +1,3 @@
# $FreeBSD$
arm/ti/omap4/pandaboard/pandaboard.c standard

View File

@ -0,0 +1,210 @@
/*-
* Copyright (c) 2011
* Ben Gray <ben.r.gray@gmail.com>.
* 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 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 BEN GRAY ``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 BEN GRAY 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 <vm/vm.h>
#include <vm/pmap.h>
#include <machine/bus.h>
#include <machine/pte.h>
#include <machine/pmap.h>
#include <machine/vmparam.h>
#include <machine/fdt.h>
#include <arm/ti/omap4/omap4var.h>
#include <arm/ti/omap4/omap4_reg.h>
/* Registers in the SCRM that control the AUX clocks */
#define SCRM_ALTCLKSRC (0x110)
#define SCRM_AUXCLK0 (0x0310)
#define SCRM_AUXCLK1 (0x0314)
#define SCRM_AUXCLK2 (0x0318)
#define SCRM_AUXCLK3 (0x031C)
/* Some of the GPIO register set */
#define GPIO1_OE (0x0134)
#define GPIO1_CLEARDATAOUT (0x0190)
#define GPIO1_SETDATAOUT (0x0194)
#define GPIO2_OE (0x0134)
#define GPIO2_CLEARDATAOUT (0x0190)
#define GPIO2_SETDATAOUT (0x0194)
/* Some of the PADCONF register set */
#define CONTROL_WKUP_PAD0_FREF_CLK3_OUT (0x058)
#define CONTROL_CORE_PAD1_KPD_COL2 (0x186)
#define CONTROL_CORE_PAD0_GPMC_WAIT1 (0x08C)
#define REG_WRITE32(r, x) *((volatile uint32_t*)(r)) = (uint32_t)(x)
#define REG_READ32(r) *((volatile uint32_t*)(r))
#define REG_WRITE16(r, x) *((volatile uint16_t*)(r)) = (uint16_t)(x)
#define REG_READ16(r) *((volatile uint16_t*)(r))
/**
* usb_hub_init - initialises and resets the external USB hub
*
* The USB hub needs to be held in reset while the power is being applied
* and the reference clock is enabled at 19.2MHz. The following is the
* layout of the USB hub taken from the Pandaboard reference manual.
*
*
* .-------------. .--------------. .----------------.
* | OMAP4430 | | USB3320C | | LAN9514 |
* | | | | | USB Hub / Eth |
* | CLK | <------ | CLKOUT | | |
* | STP | ------> | STP | | |
* | DIR | <------ | DIR | | |
* | NXT | <------ | NXT | | |
* | DAT0 | <-----> | DAT0 | | |
* | DAT1 | <-----> | DAT1 DP | <-----> | DP |
* | DAT2 | <-----> | DAT2 DM | <-----> | DM |
* | DAT3 | <-----> | DAT3 | | |
* | DAT4 | <-----> | DAT4 | | |
* | DAT5 | <-----> | DAT5 | +----> | N_RESET |
* | DAT6 | <-----> | DAT6 | | | |
* | DAT7 | <-----> | DAT7 | | | |
* | | | | | +-> | VDD33IO |
* | AUX_CLK3 | ------> | REFCLK | | +-> | VDD33A |
* | | | | | | | |
* | GPIO_62 | --+---> | RESET | | | | |
* | | | | | | | | |
* | | | '--------------' | | '----------------'
* | | | .--------------. | |
* | | '---->| VOLT CONVERT |--' |
* | | '--------------' |
* | | |
* | | .--------------. |
* | GPIO_1 | ------> | TPS73633 |-----'
* | | '--------------'
* '-------------'
*
*
* RETURNS:
* nothing.
*/
static void
usb_hub_init(void)
{
bus_space_handle_t scrm_addr, gpio1_addr, gpio2_addr, scm_addr;
if (bus_space_map(fdtbus_bs_tag, OMAP44XX_SCRM_HWBASE,
OMAP44XX_SCRM_SIZE, 0, &scrm_addr) != 0)
panic("Couldn't map SCRM registers");
if (bus_space_map(fdtbus_bs_tag, OMAP44XX_GPIO1_HWBASE,
OMAP44XX_GPIO1_SIZE, 0, &gpio1_addr) != 0)
panic("Couldn't map GPIO1 registers");
if (bus_space_map(fdtbus_bs_tag, OMAP44XX_GPIO2_HWBASE,
OMAP44XX_GPIO2_SIZE, 0, &gpio2_addr) != 0)
panic("Couldn't map GPIO2 registers");
if (bus_space_map(fdtbus_bs_tag, OMAP44XX_SCM_PADCONF_HWBASE,
OMAP44XX_SCM_PADCONF_SIZE, 0, &scm_addr) != 0)
panic("Couldn't map SCM Padconf registers");
/* Need to set FREF_CLK3_OUT to 19.2 MHz and pump it out on pin GPIO_WK31.
* We know the SYS_CLK is 38.4Mhz and therefore to get the needed 19.2Mhz,
* just use a 2x divider and ensure the SYS_CLK is used as the source.
*/
REG_WRITE32(scrm_addr + SCRM_AUXCLK3, (1 << 16) | /* Divider of 2 */
(0 << 1) | /* Use the SYS_CLK as the source */
(1 << 8)); /* Enable the clock */
/* Enable the clock out to the pin (GPIO_WK31).
* muxmode=fref_clk3_out, pullup/down=disabled, input buffer=disabled,
* wakeup=disabled.
*/
REG_WRITE16(scm_addr + CONTROL_WKUP_PAD0_FREF_CLK3_OUT, 0x0000);
/* Disable the power to the USB hub, drive GPIO1 low */
REG_WRITE32(gpio1_addr + GPIO1_OE, REG_READ32(gpio1_addr +
GPIO1_OE) & ~(1UL << 1));
REG_WRITE32(gpio1_addr + GPIO1_CLEARDATAOUT, (1UL << 1));
REG_WRITE16(scm_addr + CONTROL_CORE_PAD1_KPD_COL2, 0x0003);
/* Reset the USB PHY and Hub using GPIO_62 */
REG_WRITE32(gpio2_addr + GPIO2_OE,
REG_READ32(gpio2_addr + GPIO2_OE) & ~(1UL << 30));
REG_WRITE32(gpio2_addr + GPIO2_CLEARDATAOUT, (1UL << 30));
REG_WRITE16(scm_addr + CONTROL_CORE_PAD0_GPMC_WAIT1, 0x0003);
DELAY(10);
REG_WRITE32(gpio2_addr + GPIO2_SETDATAOUT, (1UL << 30));
/* Enable power to the hub (GPIO_1) */
REG_WRITE32(gpio1_addr + GPIO1_SETDATAOUT, (1UL << 1));
bus_space_unmap(fdtbus_bs_tag, scrm_addr, OMAP44XX_SCRM_SIZE);
bus_space_unmap(fdtbus_bs_tag, gpio1_addr, OMAP44XX_GPIO1_SIZE);
bus_space_unmap(fdtbus_bs_tag, gpio2_addr, OMAP44XX_GPIO2_SIZE);
bus_space_unmap(fdtbus_bs_tag, scm_addr, OMAP44XX_SCM_PADCONF_SIZE);
}
/**
* board_init - initialises the pandaboard
* @dummy: ignored
*
* This function is called before any of the driver are initialised, which is
* annoying because it means we can't use the SCM, PRCM and GPIO modules which
* would really be useful.
*
* So we don't have:
* - any drivers
* - no interrupts
*
* What we do have:
* - virt/phys mappings from the devmap (see omap4.c)
* -
*
*
* So we are hamstrung without the useful drivers and we have to go back to
* direct register manupulation. Luckly we don't have to do to much, basically
* just setup the usb hub/ethernet.
*
*/
static void
board_init(void *dummy)
{
/* Initialise the USB phy and hub */
usb_hub_init();
/*
* XXX Board identification e.g. read out from FPGA or similar should
* go here
*/
}
SYSINIT(board_init, SI_SUB_CPU, SI_ORDER_THIRD, board_init, NULL);

View File

@ -0,0 +1,4 @@
# $FreeBSD$
include "../ti/omap4/std.omap4"
files "../ti/omap4/pandaboard/files.pandaboard"

View File

@ -0,0 +1,21 @@
# Omap4430 generic configuration
#$FreeBSD$
files "../ti/omap4/files.omap4"
include "../ti/std.ti"
makeoption ARM_LITTLE_ENDIAN
# Physical memory starts at 0x80000000. We assume images are loaded at
# 0x80200000, e.g. from u-boot with 'fatload mmc 0 0x80200000 kernel.bin'
#
#
options PHYSADDR=0x80000000
options KERNPHYSADDR=0x80200000
makeoptions KERNPHYSADDR=0x80200000
options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm
makeoptions KERNVIRTADDR=0xc0200000
options STARTUP_PAGETABLE_ADDR=0x80000000
options SOC_OMAP4
options ARM_L2_PIPT

5
sys/arm/ti/std.ti Normal file
View File

@ -0,0 +1,5 @@
# $FreeBSD$
cpu CPU_CORTEXA
files "../ti/files.ti"

285
sys/arm/ti/ti_cpuid.c Normal file
View File

@ -0,0 +1,285 @@
/*-
* Copyright (c) 2011
* Ben Gray <ben.r.gray@gmail.com>.
* 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 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 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/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <machine/bus.h>
#include <machine/fdt.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/frame.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <arm/ti/tivar.h>
#include <arm/ti/ti_cpuid.h>
#include <arm/ti/omap4/omap4_reg.h>
#include <arm/ti/omap3/omap3_reg.h>
#include <arm/ti/am335x/am335x_reg.h>
#define OMAP4_STD_FUSE_DIE_ID_0 0x2200
#define OMAP4_ID_CODE 0x2204
#define OMAP4_STD_FUSE_DIE_ID_1 0x2208
#define OMAP4_STD_FUSE_DIE_ID_2 0x220C
#define OMAP4_STD_FUSE_DIE_ID_3 0x2210
#define OMAP4_STD_FUSE_PROD_ID_0 0x2214
#define OMAP4_STD_FUSE_PROD_ID_1 0x2218
#define OMAP3_ID_CODE 0xA204
static uint32_t chip_revision = 0xffffffff;
/**
* ti_revision - Returns the revision number of the device
*
* Simply returns an identifier for the revision of the chip we are running
* on.
*
* RETURNS
* A 32-bit identifier for the current chip
*/
uint32_t
ti_revision(void)
{
return chip_revision;
}
/**
* omap4_get_revision - determines omap4 revision
*
* Reads the registers to determine the revision of the chip we are currently
* running on. Stores the information in global variables.
*
*
*/
static void
omap4_get_revision(void)
{
uint32_t id_code;
uint32_t revision;
uint32_t hawkeye;
bus_space_handle_t bsh;
/* The chip revsion is read from the device identification registers and
* the JTAG (?) tap registers, which are located in address 0x4A00_2200 to
* 0x4A00_2218. This is part of the L4_CORE memory range and should have
* been mapped in by the machdep.c code.
*
* STD_FUSE_DIE_ID_0 0x4A00 2200
* ID_CODE 0x4A00 2204 (this is the only one we need)
* STD_FUSE_DIE_ID_1 0x4A00 2208
* STD_FUSE_DIE_ID_2 0x4A00 220C
* STD_FUSE_DIE_ID_3 0x4A00 2210
* STD_FUSE_PROD_ID_0 0x4A00 2214
* STD_FUSE_PROD_ID_1 0x4A00 2218
*/
// id_code = REG_READ32(OMAP44XX_L4_CORE_VBASE + OMAP4_ID_CODE);
//FIXME Should we map somewhere else?
bus_space_map(fdtbus_bs_tag,OMAP44XX_L4_CORE_HWBASE, 0x4000, 0, &bsh);
id_code = bus_space_read_4(fdtbus_bs_tag, bsh, OMAP4_ID_CODE);
bus_space_unmap(fdtbus_bs_tag, bsh, 0x4000);
hawkeye = ((id_code >> 12) & 0xffff);
revision = ((id_code >> 28) & 0xf);
/* Apparently according to the linux code there were some ES2.0 samples that
* have the wrong id code and report themselves as ES1.0 silicon. So used
* the ARM cpuid to get the correct revision.
*/
if (revision == 0) {
id_code = cpufunc_id();
revision = (id_code & 0xf) - 1;
}
switch (hawkeye) {
case 0xB852:
if (revision == 0)
chip_revision = OMAP4430_REV_ES1_0;
else
chip_revision = OMAP4430_REV_ES2_0;
break;
case 0xB95C:
if (revision == 3)
chip_revision = OMAP4430_REV_ES2_1;
else if (revision == 4)
chip_revision = OMAP4430_REV_ES2_2;
else
chip_revision = OMAP4430_REV_ES2_3;
break;
default:
/* Default to the latest revision if we can't determine type */
chip_revision = OMAP4430_REV_ES2_3;
break;
}
printf("Texas Instruments OMAP%04x Processor, Revision ES%u.%u\n",
OMAP_REV_DEVICE(chip_revision), OMAP_REV_MAJOR(chip_revision),
OMAP_REV_MINOR(chip_revision));
}
/**
* omap3_get_revision - determines omap3 revision
*
* Reads the registers to determine the revision of the chip we are currently
* running on. Stores the information in global variables.
*
* WARNING: This function currently only really works for OMAP3530 devices.
*
*
*
*/
static void
omap3_get_revision(void)
{
uint32_t id_code;
uint32_t revision;
uint32_t hawkeye;
bus_space_handle_t bsh;
/* The chip revsion is read from the device identification registers and
* the JTAG (?) tap registers, which are located in address 0x4A00_2200 to
* 0x4A00_2218. This is part of the L4_CORE memory range and should have
* been mapped in by the machdep.c code.
*
* CONTROL_IDCODE 0x4830 A204 (this is the only one we need)
*
*
*/
//id_code = REG_READ32(OMAP35XX_L4_WAKEUP_VBASE + OMAP3_ID_CODE);
bus_space_map(fdtbus_bs_tag,OMAP35XX_L4_WAKEUP_HWBASE, 0x10000, 0, &bsh);
id_code = bus_space_read_4(fdtbus_bs_tag, bsh, OMAP3_ID_CODE);
bus_space_unmap(fdtbus_bs_tag, bsh, 0x4000);
hawkeye = ((id_code >> 12) & 0xffff);
revision = ((id_code >> 28) & 0xf);
switch (hawkeye) {
case 0xB6D6:
chip_revision = OMAP3350_REV_ES1_0;
break;
case 0xB7AE:
if (revision == 1)
chip_revision = OMAP3530_REV_ES2_0;
else if (revision == 2)
chip_revision = OMAP3530_REV_ES2_1;
else if (revision == 3)
chip_revision = OMAP3530_REV_ES3_0;
else if (revision == 4)
chip_revision = OMAP3530_REV_ES3_1;
else if (revision == 7)
chip_revision = OMAP3530_REV_ES3_1_2;
break;
default:
/* Default to the latest revision if we can't determine type */
chip_revision = OMAP3530_REV_ES3_1_2;
break;
}
printf("Texas Instruments OMAP%04x Processor, Revision ES%u.%u\n",
OMAP_REV_DEVICE(chip_revision), OMAP_REV_MAJOR(chip_revision),
OMAP_REV_MINOR(chip_revision));
}
static void
am335x_get_revision(void)
{
uint32_t dev_feature;
uint8_t cpu_last_char;
bus_space_handle_t bsh;
bus_space_map(fdtbus_bs_tag, AM335X_CONTROL_BASE, AM335X_CONTROL_SIZE, 0, &bsh);
chip_revision = bus_space_read_4(fdtbus_bs_tag, bsh, AM335X_CONTROL_DEVICE_ID);
dev_feature = bus_space_read_4(fdtbus_bs_tag, bsh, AM335X_CONTROL_DEV_FEATURE);
bus_space_unmap(fdtbus_bs_tag, bsh, AM335X_CONTROL_SIZE);
switch (dev_feature) {
case 0x00FF0382:
cpu_last_char='2';
break;
case 0x20FF0382:
cpu_last_char='4';
break;
case 0x00FF0383:
cpu_last_char='6';
break;
case 0x00FE0383:
cpu_last_char='7';
break;
case 0x20FF0383:
cpu_last_char='8';
break;
case 0x20FE0383:
cpu_last_char='9';
break;
default:
cpu_last_char='x';
}
printf("Texas Instruments AM335%c Processor, Revision ES1.%u\n",
cpu_last_char, AM335X_DEVREV(chip_revision));
}
/**
* ti_cpu_ident - attempts to identify the chip we are running on
* @dummy: ignored
*
* This function is called before any of the driver are initialised, however
* the basic virt to phys maps have been setup in machdep.c so we can still
* access the required registers, we just have to use direct register reads
* and writes rather than going through the bus stuff.
*
*
*/
static void
ti_cpu_ident(void *dummy)
{
switch(ti_chip()) {
case CHIP_OMAP_3:
omap3_get_revision();
break;
case CHIP_OMAP_4:
omap4_get_revision();
break;
case CHIP_AM335X:
am335x_get_revision();
break;
default:
panic("Unknown chip type, fixme!\n");
}
}
SYSINIT(ti_cpu_ident, SI_SUB_CPU, SI_ORDER_SECOND, ti_cpu_ident, NULL);

77
sys/arm/ti/ti_cpuid.h Normal file
View File

@ -0,0 +1,77 @@
/*-
* Copyright (c) 2011
* Ben Gray <ben.r.gray@gmail.com>.
* 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 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 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 _TI_CPUID_H_
#define _TI_CPUID_H_
#define OMAP_MAKEREV(d, a, b, c) \
(uint32_t)(((d) << 16) | (((a) & 0xf) << 8) | (((b) & 0xf) << 4) | ((c) & 0xf))
#define OMAP_REV_DEVICE(x) (((x) >> 16) & 0xffff)
#define OMAP_REV_MAJOR(x) (((x) >> 8) & 0xf)
#define OMAP_REV_MINOR(x) (((x) >> 4) & 0xf)
#define OMAP_REV_MINOR_MINOR(x) (((x) >> 0) & 0xf)
#define OMAP3350_DEV 0x3530
#define OMAP3350_REV_ES1_0 OMAP_MAKEREV(OMAP3350_DEV, 1, 0, 0)
#define OMAP3530_REV_ES2_0 OMAP_MAKEREV(OMAP3350_DEV, 2, 0, 0)
#define OMAP3530_REV_ES2_1 OMAP_MAKEREV(OMAP3350_DEV, 2, 1, 0)
#define OMAP3530_REV_ES3_0 OMAP_MAKEREV(OMAP3350_DEV, 3, 0, 0)
#define OMAP3530_REV_ES3_1 OMAP_MAKEREV(OMAP3350_DEV, 3, 1, 0)
#define OMAP3530_REV_ES3_1_2 OMAP_MAKEREV(OMAP3350_DEV, 3, 1, 2)
#define OMAP4430_DEV 0x4430
#define OMAP4430_REV_ES1_0 OMAP_MAKEREV(OMAP4430_DEV, 1, 0, 0)
#define OMAP4430_REV_ES2_0 OMAP_MAKEREV(OMAP4430_DEV, 2, 0, 0)
#define OMAP4430_REV_ES2_1 OMAP_MAKEREV(OMAP4430_DEV, 2, 1, 0)
#define OMAP4430_REV_ES2_2 OMAP_MAKEREV(OMAP4430_DEV, 2, 2, 0)
#define OMAP4430_REV_ES2_3 OMAP_MAKEREV(OMAP4430_DEV, 2, 3, 0)
#define AM335X_DEVREV(x) ((x) >> 28)
#define CHIP_OMAP_3 0
#define CHIP_OMAP_4 1
#define CHIP_AM335X 2
static __inline int ti_chip(void)
{
#if defined(SOC_OMAP4)
return CHIP_OMAP_4;
#elif defined(SOC_OMAP3)
return CHIP_OMAP_3;
#elif defined(SOC_TI_AM335X)
return CHIP_AM335X;
#else
# error Chip type not defined, ensure SOC_xxxx is defined
#endif
}
uint32_t ti_revision(void);
#endif /* _TI_CPUID_H_ */

424
sys/arm/ti/ti_edma3.c Normal file
View File

@ -0,0 +1,424 @@
/*-
* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
* Copyright (c) 2012 Damjan Marion <dmarion@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.
* 3. Neither the name of authors nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* 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/endian.h>
#include <sys/mbuf.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/sockio.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <arm/ti/ti_scm.h>
#include <arm/ti/ti_prcm.h>
#include <arm/ti/ti_edma3.h>
#define TI_EDMA3_NUM_TCS 3
#define TI_EDMA3_NUM_IRQS 3
#define TI_EDMA3_NUM_DMA_CHS 64
#define TI_EDMA3_NUM_QDMA_CHS 8
#define TI_EDMA3CC_PID 0x000
#define TI_EDMA3CC_DCHMAP(p) (0x100 + ((p)*4))
#define TI_EDMA3CC_DMAQNUM(n) (0x240 + ((n)*4))
#define TI_EDMA3CC_QDMAQNUM 0x260
#define TI_EDMA3CC_EMCR 0x308
#define TI_EDMA3CC_EMCRH 0x30C
#define TI_EDMA3CC_QEMCR 0x314
#define TI_EDMA3CC_CCERR 0x318
#define TI_EDMA3CC_CCERRCLR 0x31C
#define TI_EDMA3CC_DRAE(p) (0x340 + ((p)*8))
#define TI_EDMA3CC_DRAEH(p) (0x344 + ((p)*8))
#define TI_EDMA3CC_QRAE(p) (0x380 + ((p)*4))
#define TI_EDMA3CC_S_ESR(p) (0x2010 + ((p)*0x200))
#define TI_EDMA3CC_S_ESRH(p) (0x2014 + ((p)*0x200))
#define TI_EDMA3CC_S_SECR(p) (0x2040 + ((p)*0x200))
#define TI_EDMA3CC_S_SECRH(p) (0x2044 + ((p)*0x200))
#define TI_EDMA3CC_S_EESR(p) (0x2030 + ((p)*0x200))
#define TI_EDMA3CC_S_EESRH(p) (0x2034 + ((p)*0x200))
#define TI_EDMA3CC_S_IESR(p) (0x2060 + ((p)*0x200))
#define TI_EDMA3CC_S_IESRH(p) (0x2064 + ((p)*0x200))
#define TI_EDMA3CC_S_IPR(p) (0x2068 + ((p)*0x200))
#define TI_EDMA3CC_S_IPRH(p) (0x206C + ((p)*0x200))
#define TI_EDMA3CC_S_QEESR(p) (0x208C + ((p)*0x200))
#define TI_EDMA3CC_PARAM_OFFSET 0x4000
#define TI_EDMA3CC_OPT(p) (TI_EDMA3CC_PARAM_OFFSET + 0x0 + ((p)*0x20))
#define TI_EDMA3CC_DMAQNUM_SET(c,q) ((0x7 & (q)) << (((c) % 8) * 4))
#define TI_EDMA3CC_DMAQNUM_CLR(c) (~(0x7 << (((c) % 8) * 4)))
#define TI_EDMA3CC_QDMAQNUM_SET(c,q) ((0x7 & (q)) << ((c) * 4))
#define TI_EDMA3CC_QDMAQNUM_CLR(c) (~(0x7 << ((c) * 4)))
#define TI_EDMA3CC_OPT_TCC_CLR (~(0x3F000))
#define TI_EDMA3CC_OPT_TCC_SET(p) (((0x3F000 >> 12) & (p)) << 12)
struct ti_edma3_softc {
device_t sc_dev;
struct resource * mem_res[TI_EDMA3_NUM_TCS+1];
struct resource * irq_res[TI_EDMA3_NUM_IRQS];
void *ih_cookie[TI_EDMA3_NUM_IRQS];
};
static struct ti_edma3_softc *ti_edma3_sc = NULL;
static struct resource_spec ti_edma3_mem_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 },
{ -1, 0, 0 }
};
static struct resource_spec ti_edma3_irq_spec[] = {
{ SYS_RES_IRQ, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 1, RF_ACTIVE },
{ SYS_RES_IRQ, 2, RF_ACTIVE },
{ -1, 0, 0 }
};
/* Read/Write macros */
#define ti_edma3_cc_rd_4(reg) bus_read_4(ti_edma3_sc->mem_res[0], reg)
#define ti_edma3_cc_wr_4(reg, val) bus_write_4(ti_edma3_sc->mem_res[0], reg, val)
#define ti_edma3_tc_rd_4(c, reg) bus_read_4(ti_edma3_sc->mem_res[c+1], reg)
#define ti_edma3_tc_wr_4(c, reg, val) bus_write_4(ti_edma3_sc->mem_res[c+1], reg, val)
static void ti_edma3_intr_comp(void *arg);
static void ti_edma3_intr_mperr(void *arg);
static void ti_edma3_intr_err(void *arg);
static struct {
driver_intr_t *handler;
char * description;
} ti_edma3_intrs[TI_EDMA3_NUM_IRQS] = {
{ ti_edma3_intr_comp, "EDMA Completion Interrupt" },
{ ti_edma3_intr_mperr, "EDMA Memory Protection Error Interrupt" },
{ ti_edma3_intr_err, "EDMA Error Interrupt" },
};
static int
ti_edma3_probe(device_t dev)
{
if (!ofw_bus_is_compatible(dev, "ti,edma"))
return (ENXIO);
device_set_desc(dev, "TI EDMA Controller");
return (0);
}
static int
ti_edma3_attach(device_t dev)
{
struct ti_edma3_softc *sc = device_get_softc(dev);
uint32_t reg;
int err;
int i;
if (ti_edma3_sc)
return (ENXIO);
ti_edma3_sc = sc;
sc->sc_dev = dev;
/* Request the memory resources */
err = bus_alloc_resources(dev, ti_edma3_mem_spec, sc->mem_res);
if (err) {
device_printf(dev, "Error: could not allocate mem resources\n");
return (ENXIO);
}
/* Request the IRQ resources */
err = bus_alloc_resources(dev, ti_edma3_irq_spec, sc->irq_res);
if (err) {
device_printf(dev, "Error: could not allocate irq resources\n");
return (ENXIO);
}
/* Enable Channel Controller */
ti_prcm_clk_enable(EDMA_TPCC_CLK);
reg = ti_edma3_cc_rd_4(TI_EDMA3CC_PID);
device_printf(dev, "EDMA revision %08x\n", reg);
/* Attach interrupt handlers */
for (i = 0; i < TI_EDMA3_NUM_IRQS; ++i) {
err = bus_setup_intr(dev, sc->irq_res[i], INTR_TYPE_MISC |
INTR_MPSAFE, NULL, *ti_edma3_intrs[i].handler,
sc, &sc->ih_cookie[i]);
if (err) {
device_printf(dev, "could not setup %s\n",
ti_edma3_intrs[i].description);
return (err);
}
}
return (0);
}
static device_method_t ti_edma3_methods[] = {
DEVMETHOD(device_probe, ti_edma3_probe),
DEVMETHOD(device_attach, ti_edma3_attach),
{0, 0},
};
static driver_t ti_edma3_driver = {
"ti_edma3",
ti_edma3_methods,
sizeof(struct ti_edma3_softc),
};
static devclass_t ti_edma3_devclass;
DRIVER_MODULE(ti_edma3, simplebus, ti_edma3_driver, ti_edma3_devclass, 0, 0);
MODULE_DEPEND(ti_edma3, ti_prcm, 1, 1, 1);
static void
ti_edma3_intr_comp(void *arg)
{
printf("%s: unimplemented\n", __func__);
}
static void
ti_edma3_intr_mperr(void *arg)
{
printf("%s: unimplemented\n", __func__);
}
static void
ti_edma3_intr_err(void *arg)
{
printf("%s: unimplemented\n", __func__);
}
void
ti_edma3_init(unsigned int eqn)
{
uint32_t reg;
int i;
/* on AM335x Event queue 0 is always mapped to Transfer Controller 0,
* event queue 1 to TC2, etc. So we are asking PRCM to power on specific
* TC based on what event queue we need to initialize */
ti_prcm_clk_enable(EDMA_TPTC0_CLK + eqn);
/* Clear Event Missed Regs */
ti_edma3_cc_wr_4(TI_EDMA3CC_EMCR, 0xFFFFFFFF);
ti_edma3_cc_wr_4(TI_EDMA3CC_EMCRH, 0xFFFFFFFF);
ti_edma3_cc_wr_4(TI_EDMA3CC_QEMCR, 0xFFFFFFFF);
/* Clear Error Reg */
ti_edma3_cc_wr_4(TI_EDMA3CC_CCERRCLR, 0xFFFFFFFF);
/* Enable DMA channels 0-63 */
ti_edma3_cc_wr_4(TI_EDMA3CC_DRAE(0), 0xFFFFFFFF);
ti_edma3_cc_wr_4(TI_EDMA3CC_DRAEH(0), 0xFFFFFFFF);
for (i = 0; i < 64; i++) {
ti_edma3_cc_wr_4(TI_EDMA3CC_DCHMAP(i), i<<5);
}
/* Initialize the DMA Queue Number Registers */
for (i = 0; i < TI_EDMA3_NUM_DMA_CHS; i++) {
reg = ti_edma3_cc_rd_4(TI_EDMA3CC_DMAQNUM(i>>3));
reg &= TI_EDMA3CC_DMAQNUM_CLR(i);
reg |= TI_EDMA3CC_DMAQNUM_SET(i, eqn);
ti_edma3_cc_wr_4(TI_EDMA3CC_DMAQNUM(i>>3), reg);
}
/* Enable the QDMA Region access for all channels */
ti_edma3_cc_wr_4(TI_EDMA3CC_QRAE(0), (1 << TI_EDMA3_NUM_QDMA_CHS) - 1);
/*Initialize QDMA Queue Number Registers */
for (i = 0; i < TI_EDMA3_NUM_QDMA_CHS; i++) {
reg = ti_edma3_cc_rd_4(TI_EDMA3CC_QDMAQNUM);
reg &= TI_EDMA3CC_QDMAQNUM_CLR(i);
reg |= TI_EDMA3CC_QDMAQNUM_SET(i, eqn);
ti_edma3_cc_wr_4(TI_EDMA3CC_QDMAQNUM, reg);
}
}
#ifdef notyet
int
ti_edma3_enable_event_intr(unsigned int ch)
{
uint32_t reg;
if (ch >= TI_EDMA3_NUM_DMA_CHS)
return (EINVAL);
if (ch < 32) {
ti_edma3_cc_wr_4(TI_EDMA3CC_S_IESR(0), 1 << ch);
} else {
ti_edma3_cc_wr_4(TI_EDMA3CC_S_IESRH(0), 1 << (ch - 32));
}
return 0;
}
#endif
int
ti_edma3_request_dma_ch(unsigned int ch, unsigned int tccn, unsigned int eqn)
{
uint32_t reg;
if (ch >= TI_EDMA3_NUM_DMA_CHS)
return (EINVAL);
/* Enable the DMA channel in the DRAE/DRAEH registers */
if (ch < 32) {
reg = ti_edma3_cc_rd_4(TI_EDMA3CC_DRAE(0));
reg |= (0x01 << ch);
ti_edma3_cc_wr_4(TI_EDMA3CC_DRAE(0), reg);
} else {
reg = ti_edma3_cc_rd_4(TI_EDMA3CC_DRAEH(0));
reg |= (0x01 << (ch - 32));
ti_edma3_cc_wr_4(TI_EDMA3CC_DRAEH(0), reg);
}
/* Associate DMA Channel to Event Queue */
reg = ti_edma3_cc_rd_4(TI_EDMA3CC_DMAQNUM(ch >> 3));
reg &= TI_EDMA3CC_DMAQNUM_CLR(ch);
reg |= TI_EDMA3CC_DMAQNUM_SET((ch), eqn);
ti_edma3_cc_wr_4(TI_EDMA3CC_DMAQNUM(ch >> 3), reg);
/* Set TCC in corresponding PaRAM Entry */
reg = ti_edma3_cc_rd_4(TI_EDMA3CC_OPT(ch));
reg &= TI_EDMA3CC_OPT_TCC_CLR;
reg |= TI_EDMA3CC_OPT_TCC_SET(ch);
ti_edma3_cc_wr_4(TI_EDMA3CC_OPT(ch), reg);
return 0;
}
int
ti_edma3_request_qdma_ch(unsigned int ch, unsigned int tccn, unsigned int eqn)
{
uint32_t reg;
if (ch >= TI_EDMA3_NUM_DMA_CHS)
return (EINVAL);
/* Enable the QDMA channel in the QRAE registers */
reg = ti_edma3_cc_rd_4(TI_EDMA3CC_QRAE(0));
reg |= (0x01 << ch);
ti_edma3_cc_wr_4(TI_EDMA3CC_QRAE(0), reg);
/* Associate QDMA Channel to Event Queue */
reg = ti_edma3_cc_rd_4(TI_EDMA3CC_QDMAQNUM);
reg |= TI_EDMA3CC_QDMAQNUM_SET(ch, eqn);
ti_edma3_cc_wr_4(TI_EDMA3CC_QDMAQNUM, reg);
/* Set TCC in corresponding PaRAM Entry */
reg = ti_edma3_cc_rd_4(TI_EDMA3CC_OPT(ch));
reg &= TI_EDMA3CC_OPT_TCC_CLR;
reg |= TI_EDMA3CC_OPT_TCC_SET(ch);
ti_edma3_cc_wr_4(TI_EDMA3CC_OPT(ch), reg);
return 0;
}
int
ti_edma3_enable_transfer_manual(unsigned int ch)
{
if (ch >= TI_EDMA3_NUM_DMA_CHS)
return (EINVAL);
/* set corresponding bit in ESR/ESRH to set a event */
if (ch < 32) {
ti_edma3_cc_wr_4(TI_EDMA3CC_S_ESR(0), 1 << ch);
} else {
ti_edma3_cc_wr_4(TI_EDMA3CC_S_ESRH(0), 1 << (ch - 32));
}
return 0;
}
int
ti_edma3_enable_transfer_qdma(unsigned int ch)
{
if (ch >= TI_EDMA3_NUM_QDMA_CHS)
return (EINVAL);
/* set corresponding bit in QEESR to enable QDMA event */
ti_edma3_cc_wr_4(TI_EDMA3CC_S_QEESR(0), (1 << ch));
return 0;
}
int
ti_edma3_enable_transfer_event(unsigned int ch)
{
if (ch >= TI_EDMA3_NUM_DMA_CHS)
return (EINVAL);
/* Clear SECR(H) & EMCR(H) to clean any previous NULL request
* and set corresponding bit in EESR to enable DMA event */
if(ch < 32) {
ti_edma3_cc_wr_4(TI_EDMA3CC_S_SECR(0), (1 << ch));
ti_edma3_cc_wr_4(TI_EDMA3CC_EMCR, (1 << ch));
ti_edma3_cc_wr_4(TI_EDMA3CC_S_EESR(0), (1 << ch));
} else {
ti_edma3_cc_wr_4(TI_EDMA3CC_S_SECRH(0), 1 << (ch - 32));
ti_edma3_cc_wr_4(TI_EDMA3CC_EMCRH, 1 << (ch - 32));
ti_edma3_cc_wr_4(TI_EDMA3CC_S_EESRH(0), 1 << (ch - 32));
}
return 0;
}
void
ti_edma3_param_write(unsigned int ch, struct ti_edma3cc_param_set *prs)
{
bus_write_region_4(ti_edma3_sc->mem_res[0], TI_EDMA3CC_OPT(ch),
(uint32_t *) prs, 8);
}
void
ti_edma3_param_read(unsigned int ch, struct ti_edma3cc_param_set *prs)
{
bus_read_region_4(ti_edma3_sc->mem_res[0], TI_EDMA3CC_OPT(ch),
(uint32_t *) prs, 8);
}

81
sys/arm/ti/ti_edma3.h Normal file
View File

@ -0,0 +1,81 @@
/*-
* Copyright (c) 2012 Damjan Marion <dmarion@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 _TI_EDMA3_H_
#define _TI_EDMA3_H_
/* Direct Mapped EDMA3 Events */
#define TI_EDMA3_EVENT_SDTXEVT1 2
#define TI_EDMA3_EVENT_SDRXEVT1 3
#define TI_EDMA3_EVENT_SDTXEVT0 24
#define TI_EDMA3_EVENT_SDRXEVT0 25
struct ti_edma3cc_param_set {
struct {
uint32_t sam:1; /* Source address mode */
uint32_t dam:1; /* Destination address mode */
uint32_t syncdim:1; /* Transfer synchronization dimension */
uint32_t static_set:1; /* Static Set */
uint32_t :4;
uint32_t fwid:3; /* FIFO Width */
uint32_t tccmode:1; /* Transfer complete code mode */
uint32_t tcc:6; /* Transfer complete code */
uint32_t :2;
uint32_t tcinten:1; /* Transfer complete interrupt enable */
uint32_t itcinten:1; /* Intermediate xfer completion intr. ena */
uint32_t tcchen:1; /* Transfer complete chaining enable */
uint32_t itcchen:1; /* Intermediate xfer completion chaining ena */
uint32_t privid:4; /* Privilege identification */
uint32_t :3;
uint32_t priv:1; /* Privilege level */
} opt;
uint32_t src; /* Channel Source Address */
uint16_t acnt; /* Count for 1st Dimension */
uint16_t bcnt; /* Count for 2nd Dimension */
uint32_t dst; /* Channel Destination Address */
int16_t srcbidx; /* Source B Index */
int16_t dstbidx; /* Destination B Index */
uint16_t link; /* Link Address */
uint16_t bcntrld; /* BCNT Reload */
int16_t srccidx; /* Source C Index */
int16_t dstcidx; /* Destination C Index */
uint16_t ccnt; /* Count for 3rd Dimension */
uint16_t reserved; /* Reserved */
};
void ti_edma3_init(unsigned int eqn);
int ti_edma3_request_dma_ch(unsigned int ch, unsigned int tccn, unsigned int eqn);
int ti_edma3_request_qdma_ch(unsigned int ch, unsigned int tccn, unsigned int eqn);
int ti_edma3_enable_transfer_manual(unsigned int ch);
int ti_edma3_enable_transfer_qdma(unsigned int ch);
int ti_edma3_enable_transfer_event(unsigned int ch);
void ti_edma3_param_write(unsigned int ch, struct ti_edma3cc_param_set *prs);
void ti_edma3_param_read(unsigned int ch, struct ti_edma3cc_param_set *prs);
#endif /* _TI_EDMA3_H_ */

802
sys/arm/ti/ti_gpio.c Normal file
View File

@ -0,0 +1,802 @@
/*-
* Copyright (c) 2011
* Ben Gray <ben.r.gray@gmail.com>.
* 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 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 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.
*/
/**
* Very simple GPIO (general purpose IO) driver module for TI OMAP SoC's.
*
* Currently this driver only does the basics, get a value on a pin & set a
* value on a pin. Hopefully over time I'll expand this to be a bit more generic
* and support interrupts and other various bits on the SoC can do ... in the
* meantime this is all you get.
*
* Beware the OMA datasheet(s) lists GPIO banks 1-6, whereas I've used 0-5 here
* in the code.
*
*
*/
#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 <arm/ti/ti_scm.h>
#include <arm/ti/ti_prcm.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 "gpio_if.h"
/* Register definitions */
#define TI_GPIO_REVISION 0x0000
#define TI_GPIO_SYSCONFIG 0x0010
#if defined(SOC_OMAP3)
#define TI_GPIO_REVISION 0x0000
#define TI_GPIO_SYSCONFIG 0x0010
#define TI_GPIO_SYSSTATUS 0x0014
#define TI_GPIO_IRQSTATUS1 0x0018
#define TI_GPIO_IRQENABLE1 0x001C
#define TI_GPIO_WAKEUPENABLE 0x0020
#define TI_GPIO_IRQSTATUS2 0x0028
#define TI_GPIO_IRQENABLE2 0x002C
#define TI_GPIO_CTRL 0x0030
#define TI_GPIO_OE 0x0034
#define TI_GPIO_DATAIN 0x0038
#define TI_GPIO_DATAOUT 0x003C
#define TI_GPIO_LEVELDETECT0 0x0040
#define TI_GPIO_LEVELDETECT1 0x0044
#define TI_GPIO_RISINGDETECT 0x0048
#define TI_GPIO_FALLINGDETECT 0x004C
#define TI_GPIO_DEBOUNCENABLE 0x0050
#define TI_GPIO_DEBOUNCINGTIME 0x0054
#define TI_GPIO_CLEARIRQENABLE1 0x0060
#define TI_GPIO_SETIRQENABLE1 0x0064
#define TI_GPIO_CLEARIRQENABLE2 0x0070
#define TI_GPIO_SETIRQENABLE2 0x0074
#define TI_GPIO_CLEARWKUENA 0x0080
#define TI_GPIO_SETWKUENA 0x0084
#define TI_GPIO_CLEARDATAOUT 0x0090
#define TI_GPIO_SETDATAOUT 0x0094
#elif defined(SOC_OMAP4) || defined(SOC_TI_AM335X)
#define TI_GPIO_IRQSTATUS_RAW_0 0x0024
#define TI_GPIO_IRQSTATUS_RAW_1 0x0028
#define TI_GPIO_IRQSTATUS_0 0x002C
#define TI_GPIO_IRQSTATUS_1 0x0030
#define TI_GPIO_IRQSTATUS_SET_0 0x0034
#define TI_GPIO_IRQSTATUS_SET_1 0x0038
#define TI_GPIO_IRQSTATUS_CLR_0 0x003C
#define TI_GPIO_IRQSTATUS_CLR_1 0x0040
#define TI_GPIO_IRQWAKEN_0 0x0044
#define TI_GPIO_IRQWAKEN_1 0x0048
#define TI_GPIO_SYSSTATUS 0x0114
#define TI_GPIO_IRQSTATUS1 0x0118
#define TI_GPIO_IRQENABLE1 0x011C
#define TI_GPIO_WAKEUPENABLE 0x0120
#define TI_GPIO_IRQSTATUS2 0x0128
#define TI_GPIO_IRQENABLE2 0x012C
#define TI_GPIO_CTRL 0x0130
#define TI_GPIO_OE 0x0134
#define TI_GPIO_DATAIN 0x0138
#define TI_GPIO_DATAOUT 0x013C
#define TI_GPIO_LEVELDETECT0 0x0140
#define TI_GPIO_LEVELDETECT1 0x0144
#define TI_GPIO_RISINGDETECT 0x0148
#define TI_GPIO_FALLINGDETECT 0x014C
#define TI_GPIO_DEBOUNCENABLE 0x0150
#define TI_GPIO_DEBOUNCINGTIME 0x0154
#define TI_GPIO_CLEARIRQENABLE1 0x0160
#define TI_GPIO_SETIRQENABLE1 0x0164
#define TI_GPIO_CLEARIRQENABLE2 0x0170
#define TI_GPIO_SETIRQENABLE2 0x0174
#define TI_GPIO_CLEARWKUPENA 0x0180
#define TI_GPIO_SETWKUENA 0x0184
#define TI_GPIO_CLEARDATAOUT 0x0190
#define TI_GPIO_SETDATAOUT 0x0194
#else
#error "Unknown SoC"
#endif
/*Other SoC Specific definitions*/
#if defined(SOC_OMAP3)
#define MAX_GPIO_BANKS 6
#define FIRST_GPIO_BANK 1
#define PINS_PER_BANK 32
#define TI_GPIO_REV 0x00000025
#elif defined(SOC_OMAP4)
#define MAX_GPIO_BANKS 6
#define FIRST_GPIO_BANK 1
#define PINS_PER_BANK 32
#define TI_GPIO_REV 0x50600801
#elif defined(SOC_TI_AM335X)
#define MAX_GPIO_BANKS 4
#define FIRST_GPIO_BANK 0
#define PINS_PER_BANK 32
#define TI_GPIO_REV 0x50600801
#endif
/**
* ti_gpio_mem_spec - Resource specification used when allocating resources
* ti_gpio_irq_spec - Resource specification used when allocating resources
*
* This driver module can have up to six independent memory regions, each
* region typically controls 32 GPIO pins.
*/
static struct resource_spec ti_gpio_mem_spec[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
{ SYS_RES_MEMORY, 1, RF_ACTIVE | RF_OPTIONAL },
{ SYS_RES_MEMORY, 2, RF_ACTIVE | RF_OPTIONAL },
{ SYS_RES_MEMORY, 3, RF_ACTIVE | RF_OPTIONAL },
#if !defined(SOC_TI_AM335X)
{ SYS_RES_MEMORY, 4, RF_ACTIVE | RF_OPTIONAL },
{ SYS_RES_MEMORY, 5, RF_ACTIVE | RF_OPTIONAL },
#endif
{ -1, 0, 0 }
};
static struct resource_spec ti_gpio_irq_spec[] = {
{ SYS_RES_IRQ, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 1, RF_ACTIVE | RF_OPTIONAL },
{ SYS_RES_IRQ, 2, RF_ACTIVE | RF_OPTIONAL },
{ SYS_RES_IRQ, 3, RF_ACTIVE | RF_OPTIONAL },
#if !defined(SOC_TI_AM335X)
{ SYS_RES_IRQ, 4, RF_ACTIVE | RF_OPTIONAL },
{ SYS_RES_IRQ, 5, RF_ACTIVE | RF_OPTIONAL },
#endif
{ -1, 0, 0 }
};
/**
* Structure that stores the driver context.
*
* This structure is allocated during driver attach.
*/
struct ti_gpio_softc {
device_t sc_dev;
/* The memory resource(s) for the PRCM register set, when the device is
* created the caller can assign up to 4 memory regions.
*/
struct resource* sc_mem_res[MAX_GPIO_BANKS];
struct resource* sc_irq_res[MAX_GPIO_BANKS];
/* The handle for the register IRQ handlers */
void* sc_irq_hdl[MAX_GPIO_BANKS];
/* The following describes the H/W revision of each of the GPIO banks */
uint32_t sc_revision[MAX_GPIO_BANKS];
struct mtx sc_mtx;
};
/**
* Macros for driver mutex locking
*/
#define TI_GPIO_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
#define TI_GPIO_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
#define TI_GPIO_LOCK_INIT(_sc) \
mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_dev), \
"ti_gpio", MTX_DEF)
#define TI_GPIO_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx);
#define TI_GPIO_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED);
#define TI_GPIO_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
/**
* ti_gpio_read_4 - reads a 16-bit value from one of the PADCONFS registers
* @sc: GPIO device context
* @bank: The bank to read from
* @off: The offset of a register from the GPIO register address range
*
*
* RETURNS:
* 32-bit value read from the register.
*/
static inline uint32_t
ti_gpio_read_4(struct ti_gpio_softc *sc, unsigned int bank, bus_size_t off)
{
return (bus_read_4(sc->sc_mem_res[bank], off));
}
/**
* ti_gpio_write_4 - writes a 32-bit value to one of the PADCONFS registers
* @sc: GPIO device context
* @bank: The bank to write to
* @off: The offset of a register from the GPIO register address range
* @val: The value to write into the register
*
* RETURNS:
* nothing
*/
static inline void
ti_gpio_write_4(struct ti_gpio_softc *sc, unsigned int bank, bus_size_t off,
uint32_t val)
{
bus_write_4(sc->sc_mem_res[bank], off, val);
}
/**
* ti_gpio_pin_max - Returns the maximum number of GPIO pins
* @dev: gpio device handle
* @maxpin: pointer to a value that upon return will contain the maximum number
* of pins in the device.
*
*
* LOCKING:
* Internally locks the context
*
* RETURNS:
* Returns 0 on success otherwise an error code
*/
static int
ti_gpio_pin_max(device_t dev, int *maxpin)
{
struct ti_gpio_softc *sc = device_get_softc(dev);
unsigned int i;
unsigned int banks = 0;
TI_GPIO_LOCK(sc);
/* Calculate how many valid banks we have and then multiply that by 32 to
* give use the total number of pins.
*/
for (i = 0; i < MAX_GPIO_BANKS; i++) {
if (sc->sc_mem_res[i] != NULL)
banks++;
}
*maxpin = (banks * PINS_PER_BANK);
TI_GPIO_UNLOCK(sc);
return (0);
}
/**
* ti_gpio_pin_getcaps - Gets the capabilties of a given pin
* @dev: gpio device handle
* @pin: the number of the pin
* @caps: pointer to a value that upon return will contain the capabilities
*
* Currently all pins have the same capability, notably:
* - GPIO_PIN_INPUT
* - GPIO_PIN_OUTPUT
* - GPIO_PIN_PULLUP
* - GPIO_PIN_PULLDOWN
*
* LOCKING:
* Internally locks the context
*
* RETURNS:
* Returns 0 on success otherwise an error code
*/
static int
ti_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
{
struct ti_gpio_softc *sc = device_get_softc(dev);
uint32_t bank = (pin / PINS_PER_BANK);
TI_GPIO_LOCK(sc);
/* Sanity check the pin number is valid */
if ((bank > MAX_GPIO_BANKS) || (sc->sc_mem_res[bank] == NULL)) {
TI_GPIO_UNLOCK(sc);
return (EINVAL);
}
*caps = (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |GPIO_PIN_PULLUP |
GPIO_PIN_PULLDOWN);
TI_GPIO_UNLOCK(sc);
return (0);
}
/**
* ti_gpio_pin_getflags - Gets the current flags of a given pin
* @dev: gpio device handle
* @pin: the number of the pin
* @flags: upon return will contain the current flags of the pin
*
* Reads the current flags of a given pin, here we actually read the H/W
* registers to determine the flags, rather than storing the value in the
* setflags call.
*
* LOCKING:
* Internally locks the context
*
* RETURNS:
* Returns 0 on success otherwise an error code
*/
static int
ti_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
{
struct ti_gpio_softc *sc = device_get_softc(dev);
uint32_t bank = (pin / PINS_PER_BANK);
TI_GPIO_LOCK(sc);
/* Sanity check the pin number is valid */
if ((bank > MAX_GPIO_BANKS) || (sc->sc_mem_res[bank] == NULL)) {
TI_GPIO_UNLOCK(sc);
return (EINVAL);
}
/* Get the current pin state */
ti_scm_padconf_get_gpioflags(pin, flags);
TI_GPIO_UNLOCK(sc);
return (0);
}
/**
* ti_gpio_pin_getname - Gets the name of a given pin
* @dev: gpio device handle
* @pin: the number of the pin
* @name: buffer to put the name in
*
* The driver simply calls the pins gpio_n, where 'n' is obviously the number
* of the pin.
*
* LOCKING:
* Internally locks the context
*
* RETURNS:
* Returns 0 on success otherwise an error code
*/
static int
ti_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
{
struct ti_gpio_softc *sc = device_get_softc(dev);
uint32_t bank = (pin / PINS_PER_BANK);
TI_GPIO_LOCK(sc);
/* Sanity check the pin number is valid */
if ((bank > MAX_GPIO_BANKS) || (sc->sc_mem_res[bank] == NULL)) {
TI_GPIO_UNLOCK(sc);
return (EINVAL);
}
/* Set a very simple name */
snprintf(name, GPIOMAXNAME, "gpio_%u", pin);
name[GPIOMAXNAME - 1] = '\0';
TI_GPIO_UNLOCK(sc);
return (0);
}
/**
* ti_gpio_pin_setflags - Sets the flags for a given pin
* @dev: gpio device handle
* @pin: the number of the pin
* @flags: the flags to set
*
* The flags of the pin correspond to things like input/output mode, pull-ups,
* pull-downs, etc. This driver doesn't support all flags, only the following:
* - GPIO_PIN_INPUT
* - GPIO_PIN_OUTPUT
* - GPIO_PIN_PULLUP
* - GPIO_PIN_PULLDOWN
*
* LOCKING:
* Internally locks the context
*
* RETURNS:
* Returns 0 on success otherwise an error code
*/
static int
ti_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
{
struct ti_gpio_softc *sc = device_get_softc(dev);
uint32_t bank = (pin / PINS_PER_BANK);
uint32_t mask = (1UL << (pin % PINS_PER_BANK));
uint32_t reg_val;
/* Sanity check the flags supplied are valid, i.e. not input and output */
if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) == 0x0000)
return (EINVAL);
if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) ==
(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT))
return (EINVAL);
if ((flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) ==
(GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN))
return (EINVAL);
TI_GPIO_LOCK(sc);
/* Sanity check the pin number is valid */
if ((bank > MAX_GPIO_BANKS) || (sc->sc_mem_res[bank] == NULL)) {
TI_GPIO_UNLOCK(sc);
return (EINVAL);
}
/* Set the GPIO mode and state */
if (ti_scm_padconf_set_gpioflags(pin, flags) != 0) {
TI_GPIO_UNLOCK(sc);
return (EINVAL);
}
/* If configuring as an output set the "output enable" bit */
reg_val = ti_gpio_read_4(sc, bank, TI_GPIO_OE);
if (flags & GPIO_PIN_INPUT)
reg_val |= mask;
else
reg_val &= ~mask;
ti_gpio_write_4(sc, bank, TI_GPIO_OE, reg_val);
TI_GPIO_UNLOCK(sc);
return (0);
}
/**
* ti_gpio_pin_set - Sets the current level on a GPIO pin
* @dev: gpio device handle
* @pin: the number of the pin
* @value: non-zero value will drive the pin high, otherwise the pin is
* driven low.
*
*
* LOCKING:
* Internally locks the context
*
* RETURNS:
* Returns 0 on success otherwise a error code
*/
static int
ti_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
{
struct ti_gpio_softc *sc = device_get_softc(dev);
uint32_t bank = (pin / PINS_PER_BANK);
uint32_t mask = (1UL << (pin % PINS_PER_BANK));
TI_GPIO_LOCK(sc);
/* Sanity check the pin number is valid */
if ((bank > MAX_GPIO_BANKS) || (sc->sc_mem_res[bank] == NULL)) {
TI_GPIO_UNLOCK(sc);
return (EINVAL);
}
ti_gpio_write_4(sc, bank, (value == GPIO_PIN_LOW) ? TI_GPIO_CLEARDATAOUT
: TI_GPIO_SETDATAOUT, mask);
TI_GPIO_UNLOCK(sc);
return (0);
}
/**
* ti_gpio_pin_get - Gets the current level on a GPIO pin
* @dev: gpio device handle
* @pin: the number of the pin
* @value: pointer to a value that upond return will contain the pin value
*
* The pin must be configured as an input pin beforehand, otherwise this
* function will fail.
*
* LOCKING:
* Internally locks the context
*
* RETURNS:
* Returns 0 on success otherwise a error code
*/
static int
ti_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value)
{
struct ti_gpio_softc *sc = device_get_softc(dev);
uint32_t bank = (pin / PINS_PER_BANK);
uint32_t mask = (1UL << (pin % PINS_PER_BANK));
uint32_t val = 0;
TI_GPIO_LOCK(sc);
/* Sanity check the pin number is valid */
if ((bank > MAX_GPIO_BANKS) || (sc->sc_mem_res[bank] == NULL)) {
TI_GPIO_UNLOCK(sc);
return (EINVAL);
}
/* Sanity check the pin is not configured as an output */
val = ti_gpio_read_4(sc, bank, TI_GPIO_OE);
if ((val & mask) == mask) {
TI_GPIO_UNLOCK(sc);
return (EINVAL);
}
/* Read the value on the pin */
*value = (ti_gpio_read_4(sc, bank, TI_GPIO_DATAIN) & mask) ? 1 : 0;
TI_GPIO_UNLOCK(sc);
return (0);
}
/**
* ti_gpio_pin_toggle - Toggles a given GPIO pin
* @dev: gpio device handle
* @pin: the number of the pin
*
*
* LOCKING:
* Internally locks the context
*
* RETURNS:
* Returns 0 on success otherwise a error code
*/
static int
ti_gpio_pin_toggle(device_t dev, uint32_t pin)
{
struct ti_gpio_softc *sc = device_get_softc(dev);
uint32_t bank = (pin / PINS_PER_BANK);
uint32_t mask = (1UL << (pin % PINS_PER_BANK));
uint32_t val;
TI_GPIO_LOCK(sc);
/* Sanity check the pin number is valid */
if ((bank > MAX_GPIO_BANKS) || (sc->sc_mem_res[bank] == NULL)) {
TI_GPIO_UNLOCK(sc);
return (EINVAL);
}
/* Toggle the pin */
val = ti_gpio_read_4(sc, bank, TI_GPIO_DATAOUT);
if (val & mask)
ti_gpio_write_4(sc, bank, TI_GPIO_CLEARDATAOUT, mask);
else
ti_gpio_write_4(sc, bank, TI_GPIO_SETDATAOUT, mask);
TI_GPIO_UNLOCK(sc);
return (0);
}
/**
* ti_gpio_intr - ISR for all GPIO modules
* @arg: the soft context pointer
*
* Unsused
*
* LOCKING:
* Internally locks the context
*
*/
static void
ti_gpio_intr(void *arg)
{
struct ti_gpio_softc *sc = arg;
TI_GPIO_LOCK(sc);
/* TODO: something useful */
TI_GPIO_UNLOCK(sc);
}
/**
* ti_gpio_probe - probe function for the driver
* @dev: gpio device handle
*
* Simply sets the name of the driver
*
* LOCKING:
* None
*
* RETURNS:
* Always returns 0
*/
static int
ti_gpio_probe(device_t dev)
{
if (!ofw_bus_is_compatible(dev, "ti,gpio"))
return (ENXIO);
device_set_desc(dev, "TI General Purpose I/O (GPIO)");
return (0);
}
/**
* ti_gpio_attach - attach function for the driver
* @dev: gpio device handle
*
* Allocates and sets up the driver context for all GPIO banks. This function
* expects the memory ranges and IRQs to already be allocated to the driver.
*
* LOCKING:
* None
*
* RETURNS:
* Always returns 0
*/
static int
ti_gpio_attach(device_t dev)
{
struct ti_gpio_softc *sc = device_get_softc(dev);
unsigned int i;
int err = 0;
sc->sc_dev = dev;
TI_GPIO_LOCK_INIT(sc);
/* There are up to 6 different GPIO register sets located in different
* memory areas on the chip. The memory range should have been set for
* the driver when it was added as a child.
*/
err = bus_alloc_resources(dev, ti_gpio_mem_spec, sc->sc_mem_res);
if (err) {
device_printf(dev, "Error: could not allocate mem resources\n");
return (ENXIO);
}
/* Request the IRQ resources */
err = bus_alloc_resources(dev, ti_gpio_irq_spec, sc->sc_irq_res);
if (err) {
device_printf(dev, "Error: could not allocate irq resources\n");
return (ENXIO);
}
/* Setup the IRQ resources */
for (i = 0; i < MAX_GPIO_BANKS; i++) {
if (sc->sc_irq_res[i] == NULL)
break;
/* Register an interrupt handler for each of the IRQ resources */
if ((bus_setup_intr(dev, sc->sc_irq_res[i], INTR_TYPE_MISC | INTR_MPSAFE,
NULL, ti_gpio_intr, sc, &(sc->sc_irq_hdl[i])))) {
device_printf(dev, "WARNING: unable to register interrupt handler\n");
return (ENXIO);
}
}
/* Store the device handle back in the sc */
sc->sc_dev = dev;
/* We need to go through each block and ensure the clocks are running and
* the module is enabled. It might be better to do this only when the
* pins are configured which would result in less power used if the GPIO
* pins weren't used ...
*/
for (i = 0; i < MAX_GPIO_BANKS; i++) {
if (sc->sc_mem_res[i] != NULL) {
/* Enable the interface and functional clocks for the module */
ti_prcm_clk_enable(GPIO0_CLK + FIRST_GPIO_BANK + i);
/* Read the revision number of the module. TI don't publish the
* actual revision numbers, so instead the values have been
* determined by experimentation.
*/
sc->sc_revision[i] = ti_gpio_read_4(sc, i, TI_GPIO_REVISION);
/* Check the revision */
if (sc->sc_revision[i] != TI_GPIO_REV) {
device_printf(dev, "Warning: could not determine the revision"
"of %u GPIO module (revision:0x%08x)\n",
i, sc->sc_revision[i]);
continue;
}
/* Disable interrupts for all pins */
ti_gpio_write_4(sc, i, TI_GPIO_CLEARIRQENABLE1, 0xffffffff);
ti_gpio_write_4(sc, i, TI_GPIO_CLEARIRQENABLE2, 0xffffffff);
}
}
/* Finish of the probe call */
device_add_child(dev, "gpioc", device_get_unit(dev));
device_add_child(dev, "gpiobus", device_get_unit(dev));
return (bus_generic_attach(dev));
}
/**
* ti_gpio_detach - detach function for the driver
* @dev: scm device handle
*
* Allocates and sets up the driver context, this simply entails creating a
* bus mappings for the SCM register set.
*
* LOCKING:
* None
*
* RETURNS:
* Always returns 0
*/
static int
ti_gpio_detach(device_t dev)
{
struct ti_gpio_softc *sc = device_get_softc(dev);
unsigned int i;
KASSERT(mtx_initialized(&sc->sc_mtx), ("gpio mutex not initialized"));
/* Disable all interrupts */
for (i = 0; i < MAX_GPIO_BANKS; i++) {
if (sc->sc_mem_res[i] != NULL) {
ti_gpio_write_4(sc, i, TI_GPIO_CLEARIRQENABLE1, 0xffffffff);
ti_gpio_write_4(sc, i, TI_GPIO_CLEARIRQENABLE2, 0xffffffff);
}
}
bus_generic_detach(dev);
/* Release the memory and IRQ resources */
for (i = 0; i < MAX_GPIO_BANKS; i++) {
if (sc->sc_mem_res[i] != NULL)
bus_release_resource(dev, SYS_RES_MEMORY, i, sc->sc_mem_res[i]);
if (sc->sc_irq_res[i] != NULL)
bus_release_resource(dev, SYS_RES_IRQ, i, sc->sc_irq_res[i]);
}
TI_GPIO_LOCK_DESTROY(sc);
return(0);
}
static device_method_t ti_gpio_methods[] = {
DEVMETHOD(device_probe, ti_gpio_probe),
DEVMETHOD(device_attach, ti_gpio_attach),
DEVMETHOD(device_detach, ti_gpio_detach),
/* GPIO protocol */
DEVMETHOD(gpio_pin_max, ti_gpio_pin_max),
DEVMETHOD(gpio_pin_getname, ti_gpio_pin_getname),
DEVMETHOD(gpio_pin_getflags, ti_gpio_pin_getflags),
DEVMETHOD(gpio_pin_getcaps, ti_gpio_pin_getcaps),
DEVMETHOD(gpio_pin_setflags, ti_gpio_pin_setflags),
DEVMETHOD(gpio_pin_get, ti_gpio_pin_get),
DEVMETHOD(gpio_pin_set, ti_gpio_pin_set),
DEVMETHOD(gpio_pin_toggle, ti_gpio_pin_toggle),
{0, 0},
};
static driver_t ti_gpio_driver = {
"gpio",
ti_gpio_methods,
sizeof(struct ti_gpio_softc),
};
static devclass_t ti_gpio_devclass;
DRIVER_MODULE(ti_gpio, simplebus, ti_gpio_driver, ti_gpio_devclass, 0, 0);

1179
sys/arm/ti/ti_i2c.c Normal file

File diff suppressed because it is too large Load Diff

115
sys/arm/ti/ti_i2c.h Normal file
View File

@ -0,0 +1,115 @@
/*-
* Copyright (c) 2011
* Ben Gray <ben.r.gray@gmail.com>.
* 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 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 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 _TI_I2C_H_
#define _TI_I2C_H_
/**
* Header file for the OMAP I2C driver.
*
* Simply contains register bit flags.
*/
/*
* OMAP4 I2C Registers, Summary 1
*/
#define I2C_REG_IE 0x84
#define I2C_IE_XDR (1UL << 14) /* Transmit draining interrupt */
#define I2C_IE_RDR (1UL << 13) /* Receive draining interrupt */
#define I2C_IE_AAS (1UL << 9) /* Addressed as Slave interrupt */
#define I2C_IE_BF (1UL << 8) /* Bus Free interrupt */
#define I2C_IE_AERR (1UL << 7) /* Access Error interrupt */
#define I2C_IE_STC (1UL << 6) /* Start Condition interrupt */
#define I2C_IE_GC (1UL << 5) /* General Call interrupt */
#define I2C_IE_XRDY (1UL << 4) /* Transmit Data Ready interrupt */
#define I2C_IE_RRDY (1UL << 3) /* Receive Data Ready interrupt */
#define I2C_IE_ARDY (1UL << 2) /* Register Access Ready interrupt */
#define I2C_IE_NACK (1UL << 1) /* No Acknowledgment interrupt */
#define I2C_IE_AL (1UL << 0) /* Arbitration Lost interrupt */
#define I2C_REG_STAT 0x88
#define I2C_STAT_XDR (1UL << 14)
#define I2C_STAT_RDR (1UL << 13)
#define I2C_STAT_BB (1UL << 12)
#define I2C_STAT_ROVR (1UL << 11)
#define I2C_STAT_XUDF (1UL << 10)
#define I2C_STAT_AAS (1UL << 9)
#define I2C_STAT_BF (1UL << 8)
#define I2C_STAT_AERR (1UL << 7)
#define I2C_STAT_STC (1UL << 6)
#define I2C_STAT_GC (1UL << 5)
#define I2C_STAT_XRDY (1UL << 4)
#define I2C_STAT_RRDY (1UL << 3)
#define I2C_STAT_ARDY (1UL << 2)
#define I2C_STAT_NACK (1UL << 1)
#define I2C_STAT_AL (1UL << 0)
#define I2C_REG_SYSS 0x90
#define I2C_REG_BUF 0x94
#define I2C_REG_CNT 0x98
#define I2C_REG_DATA 0x9c
#define I2C_REG_CON 0xa4
#define I2C_CON_I2C_EN (1UL << 15)
#define I2C_CON_OPMODE_STD (0UL << 12)
#define I2C_CON_OPMODE_HS (1UL << 12)
#define I2C_CON_OPMODE_SCCB (2UL << 12)
#define I2C_CON_OPMODE_MASK (3UL << 13)
#define I2C_CON_I2C_STB (1UL << 11)
#define I2C_CON_MST (1UL << 10)
#define I2C_CON_TRX (1UL << 9)
#define I2C_CON_XSA (1UL << 8)
#define I2C_CON_XOA0 (1UL << 7)
#define I2C_CON_XOA1 (1UL << 6)
#define I2C_CON_XOA2 (1UL << 5)
#define I2C_CON_XOA3 (1UL << 4)
#define I2C_CON_STP (1UL << 1)
#define I2C_CON_STT (1UL << 0)
#define I2C_REG_OA0 0xa8
#define I2C_REG_SA 0xac
#define I2C_REG_PSC 0xb0
#define I2C_REG_SCLL 0xb4
#define I2C_REG_SCLH 0xb8
#define I2C_REG_SYSTEST 0xbc
#define I2C_REG_BUFSTAT 0xc0
#define I2C_REG_OA1 0xc4
#define I2C_REG_OA2 0xc8
#define I2C_REG_OA3 0xcc
#define I2C_REG_ACTOA 0xd0
#define I2C_REG_SBLOCK 0xd4
/*
* OMAP4 I2C Registers, Summary 2
*/
#define I2C_REG_REVNB_LO 0x00
#define I2C_REG_REVNB_HI 0x04
#define I2C_REG_SYSC 0x10
#define I2C_REG_IRQENABLE_SET 0x2C
#define I2C_REG_IRQENABLE_CLR 0x30
#endif /* _TI_I2C_H_ */

618
sys/arm/ti/ti_machdep.c Normal file
View File

@ -0,0 +1,618 @@
/*-
* 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: //depot/projects/arm/src/sys/arm/at91/kb920x_machdep.c, rev 45
*/
#include "opt_ddb.h"
#include "opt_platform.h"
#include "opt_global.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#define _ARM32_BUS_DMA_PRIVATE
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysproto.h>
#include <sys/signalvar.h>
#include <sys/imgact.h>
#include <sys/kernel.h>
#include <sys/ktr.h>
#include <sys/linker.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/pcpu.h>
#include <sys/proc.h>
#include <sys/ptrace.h>
#include <sys/cons.h>
#include <sys/bio.h>
#include <sys/bus.h>
#include <sys/buf.h>
#include <sys/exec.h>
#include <sys/kdb.h>
#include <sys/msgbuf.h>
#include <machine/reg.h>
#include <machine/cpu.h>
#include <machine/fdt.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_pager.h>
#include <vm/vm_map.h>
#include <machine/pte.h>
#include <machine/pmap.h>
#include <machine/vmparam.h>
#include <machine/pcb.h>
#include <machine/undefined.h>
#include <machine/machdep.h>
#include <machine/metadata.h>
#include <machine/armreg.h>
#include <machine/bus.h>
#include <sys/reboot.h>
#include <arm/ti/omap4/omap4_reg.h>
#define DEBUG
#ifdef DEBUG
#define debugf(fmt, args...) printf(fmt, ##args)
#else
#define debugf(fmt, args...)
#endif
/* Start of address space used for bootstrap map */
#define DEVMAP_BOOTSTRAP_MAP_START 0xE0000000
/*
* This is the number of L2 page tables required for covering max
* (hypothetical) memsize of 4GB and all kernel mappings (vectors, msgbuf,
* stacks etc.), uprounded to be divisible by 4.
*/
#define KERNEL_PT_MAX 78
/* Define various stack sizes in pages */
#define IRQ_STACK_SIZE 1
#define ABT_STACK_SIZE 1
#define UND_STACK_SIZE 1
extern unsigned char kernbase[];
extern unsigned char _etext[];
extern unsigned char _edata[];
extern unsigned char __bss_start[];
extern unsigned char _end[];
#ifdef DDB
extern vm_offset_t ksym_start, ksym_end;
#endif
extern u_int data_abort_handler_address;
extern u_int prefetch_abort_handler_address;
extern u_int undefined_handler_address;
extern vm_offset_t pmap_bootstrap_lastaddr;
extern int *end;
struct pv_addr kernel_pt_table[KERNEL_PT_MAX];
/* Physical and virtual addresses for some global pages */
vm_paddr_t phys_avail[10];
vm_paddr_t dump_avail[4];
vm_offset_t physical_pages;
vm_offset_t pmap_bootstrap_lastaddr;
vm_paddr_t pmap_pa;
const struct pmap_devmap *pmap_devmap_bootstrap_table;
struct pv_addr systempage;
struct pv_addr msgbufpv;
struct pv_addr irqstack;
struct pv_addr undstack;
struct pv_addr abtstack;
struct pv_addr kernelstack;
void set_stackptrs(int cpu);
static struct mem_region availmem_regions[FDT_MEM_REGIONS];
static int availmem_regions_sz;
static void print_kenv(void);
static void print_kernel_section_addr(void);
static void physmap_init(void);
static int platform_devmap_init(void);
void (*ti_cpu_reset)(void);
static char *
kenv_next(char *cp)
{
if (cp != NULL) {
while (*cp != 0)
cp++;
cp++;
if (*cp == 0)
cp = NULL;
}
return (cp);
}
static void
print_kenv(void)
{
int len;
char *cp;
debugf("loader passed (static) kenv:\n");
if (kern_envp == NULL) {
debugf(" no env, null ptr\n");
return;
}
debugf(" kern_envp = 0x%08x\n", (uint32_t)kern_envp);
len = 0;
for (cp = kern_envp; cp != NULL; cp = kenv_next(cp))
debugf(" %x %s\n", (uint32_t)cp, cp);
}
static void
print_kernel_section_addr(void)
{
debugf("kernel image addresses:\n");
debugf(" kernbase = 0x%08x\n", (uint32_t)kernbase);
debugf(" _etext (sdata) = 0x%08x\n", (uint32_t)_etext);
debugf(" _edata = 0x%08x\n", (uint32_t)_edata);
debugf(" __bss_start = 0x%08x\n", (uint32_t)__bss_start);
debugf(" _end = 0x%08x\n", (uint32_t)_end);
}
static void
physmap_init(void)
{
int i, j, cnt;
vm_offset_t phys_kernelend, kernload;
uint32_t s, e, sz;
struct mem_region *mp, *mp1;
phys_kernelend = KERNPHYSADDR + (virtual_avail - KERNVIRTADDR);
kernload = KERNPHYSADDR;
ti_cpu_reset = NULL;
/*
* Remove kernel physical address range from avail
* regions list. Page align all regions.
* Non-page aligned memory isn't very interesting to us.
* Also, sort the entries for ascending addresses.
*/
sz = 0;
cnt = availmem_regions_sz;
debugf("processing avail regions:\n");
for (mp = availmem_regions; mp->mr_size; mp++) {
s = mp->mr_start;
e = mp->mr_start + mp->mr_size;
debugf(" %08x-%08x -> ", s, e);
/* Check whether this region holds all of the kernel. */
if (s < kernload && e > phys_kernelend) {
availmem_regions[cnt].mr_start = phys_kernelend;
availmem_regions[cnt++].mr_size = e - phys_kernelend;
e = kernload;
}
/* Look whether this regions starts within the kernel. */
if (s >= kernload && s < phys_kernelend) {
if (e <= phys_kernelend)
goto empty;
s = phys_kernelend;
}
/* Now look whether this region ends within the kernel. */
if (e > kernload && e <= phys_kernelend) {
if (s >= kernload) {
goto empty;
}
e = kernload;
}
/* Now page align the start and size of the region. */
s = round_page(s);
e = trunc_page(e);
if (e < s)
e = s;
sz = e - s;
debugf("%08x-%08x = %x\n", s, e, sz);
/* Check whether some memory is left here. */
if (sz == 0) {
empty:
printf("skipping\n");
bcopy(mp + 1, mp,
(cnt - (mp - availmem_regions)) * sizeof(*mp));
cnt--;
mp--;
continue;
}
/* Do an insertion sort. */
for (mp1 = availmem_regions; mp1 < mp; mp1++)
if (s < mp1->mr_start)
break;
if (mp1 < mp) {
bcopy(mp1, mp1 + 1, (char *)mp - (char *)mp1);
mp1->mr_start = s;
mp1->mr_size = sz;
} else {
mp->mr_start = s;
mp->mr_size = sz;
}
}
availmem_regions_sz = cnt;
/* Fill in phys_avail table, based on availmem_regions */
debugf("fill in phys_avail:\n");
for (i = 0, j = 0; i < availmem_regions_sz; i++, j += 2) {
debugf(" region: 0x%08x - 0x%08x (0x%08x)\n",
availmem_regions[i].mr_start,
availmem_regions[i].mr_start + availmem_regions[i].mr_size,
availmem_regions[i].mr_size);
phys_avail[j] = availmem_regions[i].mr_start;
phys_avail[j + 1] = availmem_regions[i].mr_start +
availmem_regions[i].mr_size;
}
phys_avail[j] = 0;
phys_avail[j + 1] = 0;
}
void *
initarm(struct arm_boot_params *abp)
{
struct pv_addr kernel_l1pt;
struct pv_addr dpcpu;
vm_offset_t dtbp, freemempos, l2_start, lastaddr;
uint32_t memsize, l2size;
void *kmdp;
u_int l1pagetable;
int i = 0, j = 0, err_devmap = 0;
lastaddr = parse_boot_param(abp);
memsize = 0;
set_cpufuncs();
kmdp = preload_search_by_type("elf kernel");
if (kmdp != NULL)
dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t);
else
dtbp = (vm_offset_t)NULL;
#if defined(FDT_DTB_STATIC)
/*
* In case the device tree blob was not retrieved (from metadata) try
* to use the statically embedded one.
*/
if (dtbp == (vm_offset_t)NULL)
dtbp = (vm_offset_t)&fdt_static_dtb;
#endif
if (OF_install(OFW_FDT, 0) == FALSE)
while (1);
if (OF_init((void *)dtbp) != 0)
while (1);
/* Grab physical memory regions information from device tree. */
if (fdt_get_mem_regions(availmem_regions, &availmem_regions_sz,
&memsize) != 0)
while(1);
// if (fdt_immr_addr(OMAP44XX_L4_PERIPH_VBASE) != 0)
// while (1);
/* Platform-specific initialisation */
pmap_bootstrap_lastaddr = DEVMAP_BOOTSTRAP_MAP_START - ARM_NOCACHE_KVA_SIZE;
pcpu0_init();
/* Calculate number of L2 tables needed for mapping vm_page_array */
l2size = (memsize / PAGE_SIZE) * sizeof(struct vm_page);
l2size = (l2size >> L1_S_SHIFT) + 1;
/*
* Add one table for end of kernel map, one for stacks, msgbuf and
* L1 and L2 tables map and one for vectors map.
*/
l2size += 3;
/* Make it divisible by 4 */
l2size = (l2size + 3) & ~3;
#define KERNEL_TEXT_BASE (KERNBASE)
freemempos = (lastaddr + PAGE_MASK) & ~PAGE_MASK;
/* Define a macro to simplify memory allocation */
#define valloc_pages(var, np) \
alloc_pages((var).pv_va, (np)); \
(var).pv_pa = (var).pv_va + (KERNPHYSADDR - KERNVIRTADDR);
#define alloc_pages(var, np) \
(var) = freemempos; \
freemempos += (np * PAGE_SIZE); \
memset((char *)(var), 0, ((np) * PAGE_SIZE));
while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0)
freemempos += PAGE_SIZE;
valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
for (i = 0; i < l2size; ++i) {
if (!(i % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) {
valloc_pages(kernel_pt_table[i],
L2_TABLE_SIZE / PAGE_SIZE);
j = i;
} else {
kernel_pt_table[i].pv_va = kernel_pt_table[j].pv_va +
L2_TABLE_SIZE_REAL * (i - j);
kernel_pt_table[i].pv_pa =
kernel_pt_table[i].pv_va - KERNVIRTADDR +
KERNPHYSADDR;
}
}
/*
* Allocate a page for the system page mapped to 0x00000000
* or 0xffff0000. This page will just contain the system vectors
* and can be shared by all processes.
*/
valloc_pages(systempage, 1);
/* Allocate dynamic per-cpu area. */
valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE);
dpcpu_init((void *)dpcpu.pv_va, 0);
/* Allocate stacks for all modes */
valloc_pages(irqstack, (IRQ_STACK_SIZE * MAXCPU));
valloc_pages(abtstack, (ABT_STACK_SIZE * MAXCPU));
valloc_pages(undstack, (UND_STACK_SIZE * MAXCPU));
valloc_pages(kernelstack, (KSTACK_PAGES * MAXCPU));
init_param1();
valloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE);
/*
* Now we start construction of the L1 page table
* We start by mapping the L2 page tables into the L1.
* This means that we can replace L1 mappings later on if necessary
*/
l1pagetable = kernel_l1pt.pv_va;
/*
* Try to map as much as possible of kernel text and data using
* 1MB section mapping and for the rest of initial kernel address
* space use L2 coarse tables.
*
* Link L2 tables for mapping remainder of kernel (modulo 1MB)
* and kernel structures
*/
l2_start = lastaddr & ~(L1_S_OFFSET);
for (i = 0 ; i < l2size - 1; i++)
pmap_link_l2pt(l1pagetable, l2_start + i * L1_S_SIZE,
&kernel_pt_table[i]);
pmap_curmaxkvaddr = l2_start + (l2size - 1) * L1_S_SIZE;
/* Map kernel code and data */
pmap_map_chunk(l1pagetable, KERNVIRTADDR, KERNPHYSADDR,
(((uint32_t)(lastaddr) - KERNVIRTADDR) + PAGE_MASK) & ~PAGE_MASK,
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
/* Map L1 directory and allocated L2 page tables */
pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,
L1_TABLE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
pmap_map_chunk(l1pagetable, kernel_pt_table[0].pv_va,
kernel_pt_table[0].pv_pa,
L2_TABLE_SIZE_REAL * l2size,
VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
/* Map allocated DPCPU, stacks and msgbuf */
pmap_map_chunk(l1pagetable, dpcpu.pv_va, dpcpu.pv_pa,
freemempos - dpcpu.pv_va,
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
/* Link and map the vector page */
pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH,
&kernel_pt_table[l2size - 1]);
pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE, PTE_CACHE);
/* Map pmap_devmap[] entries */
err_devmap = platform_devmap_init();
pmap_devmap_bootstrap(l1pagetable, pmap_devmap_bootstrap_table);
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) |
DOMAIN_CLIENT);
pmap_pa = kernel_l1pt.pv_pa;
setttb(kernel_l1pt.pv_pa);
cpu_tlb_flushID();
cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2));
/*
* Only after the SOC registers block is mapped we can perform device
* tree fixups, as they may attempt to read parameters from hardware.
*/
OF_interpret("perform-fixup", 0);
cninit();
physmem = memsize / PAGE_SIZE;
debugf("initarm: console initialized\n");
debugf(" arg1 kmdp = 0x%08x\n", (uint32_t)kmdp);
debugf(" boothowto = 0x%08x\n", boothowto);
debugf(" dtbp = 0x%08x\n", (uint32_t)dtbp);
print_kernel_section_addr();
print_kenv();
if (err_devmap != 0)
printf("WARNING: could not fully configure devmap, error=%d\n",
err_devmap);
/*
* Pages were allocated during the secondary bootstrap for the
* stacks for different CPU modes.
* We must now set the r13 registers in the different CPU modes to
* point to these stacks.
* Since the ARM stacks use STMFD etc. we must set r13 to the top end
* of the stack memory.
*/
cpu_control(CPU_CONTROL_MMU_ENABLE, CPU_CONTROL_MMU_ENABLE);
set_stackptrs(0);
/*
* We must now clean the cache again....
* Cleaning may be done by reading new data to displace any
* dirty data in the cache. This will have happened in setttb()
* but since we are boot strapping the addresses used for the read
* may have just been remapped and thus the cache could be out
* of sync. A re-clean after the switch will cure this.
* After booting there are no gross relocations of the kernel thus
* this problem will not occur after initarm().
*/
cpu_idcache_wbinv_all();
/* Set stack for exception handlers */
data_abort_handler_address = (u_int)data_abort_handler;
prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
undefined_handler_address = (u_int)undefinedinstruction_bounce;
undefined_init();
init_proc0(kernelstack.pv_va);
arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
arm_dump_avail_init(memsize, sizeof(dump_avail) / sizeof(dump_avail[0]));
pmap_bootstrap(freemempos, pmap_bootstrap_lastaddr, &kernel_l1pt);
msgbufp = (void *)msgbufpv.pv_va;
msgbufinit(msgbufp, msgbufsize);
mutex_init();
/*
* Prepare map of physical memory regions available to vm subsystem.
*/
physmap_init();
/* Do basic tuning, hz etc */
init_param2(physmem);
kdb_init();
return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
sizeof(struct pcb)));
}
void
set_stackptrs(int cpu)
{
set_stackptr(PSR_IRQ32_MODE,
irqstack.pv_va + ((IRQ_STACK_SIZE * PAGE_SIZE) * (cpu + 1)));
set_stackptr(PSR_ABT32_MODE,
abtstack.pv_va + ((ABT_STACK_SIZE * PAGE_SIZE) * (cpu + 1)));
set_stackptr(PSR_UND32_MODE,
undstack.pv_va + ((UND_STACK_SIZE * PAGE_SIZE) * (cpu + 1)));
}
#define FDT_DEVMAP_MAX (2) // FIXME
static struct pmap_devmap fdt_devmap[FDT_DEVMAP_MAX] = {
{ 0, 0, 0, 0, 0, }
};
/*
* Construct pmap_devmap[] with DT-derived config data.
*/
static int
platform_devmap_init(void)
{
int i = 0;
#if defined(SOC_OMAP4)
fdt_devmap[i].pd_va = 0xE8000000;
fdt_devmap[i].pd_pa = 0x48000000;
fdt_devmap[i].pd_size = 0x1000000;
fdt_devmap[i].pd_prot = VM_PROT_READ | VM_PROT_WRITE;
fdt_devmap[i].pd_cache = PTE_DEVICE;
i++;
#elif defined(SOC_TI_AM335X)
fdt_devmap[i].pd_va = 0xE4C00000;
fdt_devmap[i].pd_pa = 0x44C00000; /* L4_WKUP */
fdt_devmap[i].pd_size = 0x400000; /* 4 MB */
fdt_devmap[i].pd_prot = VM_PROT_READ | VM_PROT_WRITE;
fdt_devmap[i].pd_cache = PTE_DEVICE;
i++;
#else
#error "Unknown SoC"
#endif
pmap_devmap_bootstrap_table = &fdt_devmap[0];
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()
{
if (ti_cpu_reset)
(*ti_cpu_reset)();
else
printf("no cpu_reset implementation\n");
printf("Reset failed!\n");
while (1);
}

1839
sys/arm/ti/ti_mmchs.c Normal file

File diff suppressed because it is too large Load Diff

170
sys/arm/ti/ti_mmchs.h Normal file
View File

@ -0,0 +1,170 @@
/*-
* Copyright (c) 2011
* Ben Gray <ben.r.gray@gmail.com>.
* 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 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 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 _TI_MMCHS_H_
#define _TI_MMCHS_H_
/**
* Header file for the TI MMC/SD/SDIO driver.
*
* Simply contains register addresses and bit flags.
*/
/* Register offsets within each of the MMC/SD/SDIO controllers */
#define MMCHS_SYSCONFIG 0x010
#define MMCHS_SYSSTATUS 0x014
#define MMCHS_CSRE 0x024
#define MMCHS_SYSTEST 0x028
#define MMCHS_CON 0x02C
#define MMCHS_PWCNT 0x030
#define MMCHS_BLK 0x104
#define MMCHS_ARG 0x108
#define MMCHS_CMD 0x10C
#define MMCHS_RSP10 0x110
#define MMCHS_RSP32 0x114
#define MMCHS_RSP54 0x118
#define MMCHS_RSP76 0x11C
#define MMCHS_DATA 0x120
#define MMCHS_PSTATE 0x124
#define MMCHS_HCTL 0x128
#define MMCHS_SYSCTL 0x12C
#define MMCHS_STAT 0x130
#define MMCHS_IE 0x134
#define MMCHS_ISE 0x138
#define MMCHS_AC12 0x13C
#define MMCHS_CAPA 0x140
#define MMCHS_CUR_CAPA 0x148
#define MMCHS_REV 0x1FC
/* OMAP4 and OMAP4 have different register addresses */
#define OMAP3_MMCHS_REG_OFFSET 0x000
#define OMAP4_MMCHS_REG_OFFSET 0x100
#define AM335X_MMCHS_REG_OFFSET 0x100
/* Register bit settings */
#define MMCHS_STAT_BADA (1UL << 29)
#define MMCHS_STAT_CERR (1UL << 28)
#define MMCHS_STAT_ACE (1UL << 24)
#define MMCHS_STAT_DEB (1UL << 22)
#define MMCHS_STAT_DCRC (1UL << 21)
#define MMCHS_STAT_DTO (1UL << 20)
#define MMCHS_STAT_CIE (1UL << 19)
#define MMCHS_STAT_CEB (1UL << 18)
#define MMCHS_STAT_CCRC (1UL << 17)
#define MMCHS_STAT_CTO (1UL << 16)
#define MMCHS_STAT_ERRI (1UL << 15)
#define MMCHS_STAT_OBI (1UL << 9)
#define MMCHS_STAT_CIRQ (1UL << 8)
#define MMCHS_STAT_BRR (1UL << 5)
#define MMCHS_STAT_BWR (1UL << 4)
#define MMCHS_STAT_BGE (1UL << 2)
#define MMCHS_STAT_TC (1UL << 1)
#define MMCHS_STAT_CC (1UL << 0)
#define MMCHS_STAT_CLEAR_MASK 0x3BFF8337UL
#define MMCHS_SYSCTL_SRD (1UL << 26)
#define MMCHS_SYSCTL_SRC (1UL << 25)
#define MMCHS_SYSCTL_SRA (1UL << 24)
#define MMCHS_SYSCTL_DTO(x) (((x) & 0xf) << 16)
#define MMCHS_SYSCTL_DTO_MASK MMCHS_SYSCTL_DTO(0xf)
#define MMCHS_SYSCTL_CLKD(x) (((x) & 0x3ff) << 6)
#define MMCHS_SYSCTL_CLKD_MASK MMCHS_SYSCTL_CLKD(0x3ff)
#define MMCHS_SYSCTL_CEN (1UL << 2)
#define MMCHS_SYSCTL_ICS (1UL << 1)
#define MMCHS_SYSCTL_ICE (1UL << 0)
#define MMCHS_HCTL_OBWE (1UL << 27)
#define MMCHS_HCTL_REM (1UL << 26)
#define MMCHS_HCTL_INS (1UL << 25)
#define MMCHS_HCTL_IWE (1UL << 24)
#define MMCHS_HCTL_IBG (1UL << 19)
#define MMCHS_HCTL_RWC (1UL << 18)
#define MMCHS_HCTL_CR (1UL << 17)
#define MMCHS_HCTL_SBGR (1UL << 16)
#define MMCHS_HCTL_SDVS_MASK (7UL << 9)
#define MMCHS_HCTL_SDVS_V18 (5UL << 9)
#define MMCHS_HCTL_SDVS_V30 (6UL << 9)
#define MMCHS_HCTL_SDVS_V33 (7UL << 9)
#define MMCHS_HCTL_SDBP (1UL << 8)
#define MMCHS_HCTL_DTW (1UL << 1)
#define MMCHS_CAPA_VS18 (1UL << 26)
#define MMCHS_CAPA_VS30 (1UL << 25)
#define MMCHS_CAPA_VS33 (1UL << 24)
#define MMCHS_CMD_CMD_TYPE_IO_ABORT (3UL << 21)
#define MMCHS_CMD_CMD_TYPE_FUNC_SEL (2UL << 21)
#define MMCHS_CMD_CMD_TYPE_SUSPEND (1UL << 21)
#define MMCHS_CMD_CMD_TYPE_OTHERS (0UL << 21)
#define MMCHS_CMD_CMD_TYPE_MASK (3UL << 22)
#define MMCHS_CMD_DP (1UL << 21)
#define MMCHS_CMD_CICE (1UL << 20)
#define MMCHS_CMD_CCCE (1UL << 19)
#define MMCHS_CMD_RSP_TYPE_MASK (3UL << 16)
#define MMCHS_CMD_RSP_TYPE_NO (0UL << 16)
#define MMCHS_CMD_RSP_TYPE_136 (1UL << 16)
#define MMCHS_CMD_RSP_TYPE_48 (2UL << 16)
#define MMCHS_CMD_RSP_TYPE_48_BSY (3UL << 16)
#define MMCHS_CMD_MSBS (1UL << 5)
#define MMCHS_CMD_DDIR (1UL << 4)
#define MMCHS_CMD_ACEN (1UL << 2)
#define MMCHS_CMD_BCE (1UL << 1)
#define MMCHS_CMD_DE (1UL << 0)
#define MMCHS_CON_CLKEXTFREE (1UL << 16)
#define MMCHS_CON_PADEN (1UL << 15)
#define MMCHS_CON_OBIE (1UL << 14)
#define MMCHS_CON_OBIP (1UL << 13)
#define MMCHS_CON_CEATA (1UL << 12)
#define MMCHS_CON_CTPL (1UL << 11)
#define MMCHS_CON_DVAL_8_4MS (3UL << 9)
#define MMCHS_CON_DVAL_1MS (2UL << 9)
#define MMCHS_CON_DVAL_231US (1UL << 9)
#define MMCHS_CON_DVAL_33US (0UL << 9)
#define MMCHS_CON_DVAL_MASK (3UL << 9)
#define MMCHS_CON_WPP (1UL << 8)
#define MMCHS_CON_CDP (1UL << 7)
#define MMCHS_CON_MIT (1UL << 6)
#define MMCHS_CON_DW8 (1UL << 5)
#define MMCHS_CON_MODE (1UL << 4)
#define MMCHS_CON_STR (1UL << 3)
#define MMCHS_CON_HR (1UL << 2)
#define MMCHS_CON_INIT (1UL << 1)
#define MMCHS_CON_OD (1UL << 0)
#define MMCHS_CAPA_VS18 (1UL << 26)
#define MMCHS_CAPA_VS30 (1UL << 25)
#define MMCHS_CAPA_VS33 (1UL << 24)
#endif /* _TI_MMCHS_H_ */

309
sys/arm/ti/ti_prcm.c Normal file
View File

@ -0,0 +1,309 @@
/*
* Copyright (c) 2010
* Ben Gray <ben.r.gray@gmail.com>.
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ben Gray.
* 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 BEN GRAY ``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 BEN GRAY 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.
*/
/**
* Power, Reset and Clock Managment Module
*
* This is a very simple driver wrapper around the PRCM set of registers in
* the OMAP3 chip. It allows you to turn on and off things like the functional
* and interface clocks to the various on-chip modules.
*
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/frame.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <arm/ti/ti_prcm.h>
/**
* ti_clk_devmap - Array of clock devices, should be defined one per SoC
*
* This array is typically defined in one of the targeted *_prcm_clk.c
* files and is specific to the given SoC platform. Each entry in the array
* corresponds to an individual clock device.
*/
extern struct ti_clock_dev ti_clk_devmap[];
/**
* ti_prcm_clk_dev - returns a pointer to the clock device with given id
* @clk: the ID of the clock device to get
*
* Simply iterates through the clk_devmap global array and returns a pointer
* to the clock device if found.
*
* LOCKING:
* None
*
* RETURNS:
* The pointer to the clock device on success, on failure NULL is returned.
*/
static struct ti_clock_dev *
ti_prcm_clk_dev(clk_ident_t clk)
{
struct ti_clock_dev *clk_dev;
/* Find the clock within the devmap - it's a bit inefficent having a for
* loop for this, but this function should only called when a driver is
* being activated so IMHO not a big issue.
*/
clk_dev = &(ti_clk_devmap[0]);
while (clk_dev->id != INVALID_CLK_IDENT) {
if (clk_dev->id == clk) {
return (clk_dev);
}
clk_dev++;
}
/* Sanity check we managed to find the clock */
printf("ti_prcm: Failed to find clock device (%d)\n", clk);
return (NULL);
}
/**
* ti_prcm_clk_valid - enables a clock for a particular module
* @clk: identifier for the module to enable, see ti_prcm.h for a list
* of possible modules.
* Example: OMAP3_MODULE_MMC1_ICLK or OMAP3_MODULE_GPTIMER10_FCLK.
*
* This function can enable either a functional or interface clock.
*
* The real work done to enable the clock is really done in the callback
* function associated with the clock, this function is simply a wrapper
* around that.
*
* LOCKING:
* Internally locks the driver context.
*
* RETURNS:
* Returns 0 on success or positive error code on failure.
*/
int
ti_prcm_clk_valid(clk_ident_t clk)
{
int ret = 0;
if (ti_prcm_clk_dev(clk) == NULL)
ret = EINVAL;
return (ret);
}
/**
* ti_prcm_clk_enable - enables a clock for a particular module
* @clk: identifier for the module to enable, see ti_prcm.h for a list
* of possible modules.
* Example: OMAP3_MODULE_MMC1_ICLK or OMAP3_MODULE_GPTIMER10_FCLK.
*
* This function can enable either a functional or interface clock.
*
* The real work done to enable the clock is really done in the callback
* function associated with the clock, this function is simply a wrapper
* around that.
*
* LOCKING:
* Internally locks the driver context.
*
* RETURNS:
* Returns 0 on success or positive error code on failure.
*/
int
ti_prcm_clk_enable(clk_ident_t clk)
{
struct ti_clock_dev *clk_dev;
int ret;
/* Find the clock within the devmap - it's a bit inefficent having a for
* loop for this, but this function should only called when a driver is
* being activated so IMHO not a big issue.
*/
clk_dev = ti_prcm_clk_dev(clk);
/* Sanity check we managed to find the clock */
if (clk_dev == NULL)
return (EINVAL);
/* Activate the clock */
if (clk_dev->clk_activate)
ret = clk_dev->clk_activate(clk_dev);
else
ret = EINVAL;
return (ret);
}
/**
* ti_prcm_clk_disable - disables a clock for a particular module
* @clk: identifier for the module to enable, see ti_prcm.h for a list
* of possible modules.
* Example: OMAP3_MODULE_MMC1_ICLK or OMAP3_MODULE_GPTIMER10_FCLK.
*
* This function can enable either a functional or interface clock.
*
* The real work done to enable the clock is really done in the callback
* function associated with the clock, this function is simply a wrapper
* around that.
*
* LOCKING:
* Internally locks the driver context.
*
* RETURNS:
* Returns 0 on success or positive error code on failure.
*/
int
ti_prcm_clk_disable(clk_ident_t clk)
{
struct ti_clock_dev *clk_dev;
int ret;
/* Find the clock within the devmap - it's a bit inefficent having a for
* loop for this, but this function should only called when a driver is
* being activated so IMHO not a big issue.
*/
clk_dev = ti_prcm_clk_dev(clk);
/* Sanity check we managed to find the clock */
if (clk_dev == NULL)
return (EINVAL);
/* Activate the clock */
if (clk_dev->clk_deactivate)
ret = clk_dev->clk_deactivate(clk_dev);
else
ret = EINVAL;
return (ret);
}
/**
* ti_prcm_clk_set_source - sets the source
* @clk: identifier for the module to enable, see ti_prcm.h for a list
* of possible modules.
* Example: OMAP3_MODULE_MMC1_ICLK or OMAP3_MODULE_GPTIMER10_FCLK.
*
* This function can enable either a functional or interface clock.
*
* The real work done to enable the clock is really done in the callback
* function associated with the clock, this function is simply a wrapper
* around that.
*
* LOCKING:
* Internally locks the driver context.
*
* RETURNS:
* Returns 0 on success or positive error code on failure.
*/
int
ti_prcm_clk_set_source(clk_ident_t clk, clk_src_t clksrc)
{
struct ti_clock_dev *clk_dev;
int ret;
/* Find the clock within the devmap - it's a bit inefficent having a for
* loop for this, but this function should only called when a driver is
* being activated so IMHO not a big issue.
*/
clk_dev = ti_prcm_clk_dev(clk);
/* Sanity check we managed to find the clock */
if (clk_dev == NULL)
return (EINVAL);
/* Activate the clock */
if (clk_dev->clk_set_source)
ret = clk_dev->clk_set_source(clk_dev, clksrc);
else
ret = EINVAL;
return (ret);
}
/**
* ti_prcm_clk_get_source_freq - gets the source clock frequency
* @clk: identifier for the module to enable, see ti_prcm.h for a list
* of possible modules.
* @freq: pointer to an integer that upon return will contain the src freq
*
* This function returns the frequency of the source clock.
*
* The real work done to enable the clock is really done in the callback
* function associated with the clock, this function is simply a wrapper
* around that.
*
* LOCKING:
* Internally locks the driver context.
*
* RETURNS:
* Returns 0 on success or positive error code on failure.
*/
int
ti_prcm_clk_get_source_freq(clk_ident_t clk, unsigned int *freq)
{
struct ti_clock_dev *clk_dev;
int ret;
/* Find the clock within the devmap - it's a bit inefficent having a for
* loop for this, but this function should only called when a driver is
* being activated so IMHO not a big issue.
*/
clk_dev = ti_prcm_clk_dev(clk);
/* Sanity check we managed to find the clock */
if (clk_dev == NULL)
return (EINVAL);
/* Get the source frequency of the clock */
if (clk_dev->clk_get_source_freq)
ret = clk_dev->clk_get_source_freq(clk_dev, freq);
else
ret = EINVAL;
return (ret);
}

185
sys/arm/ti/ti_prcm.h Normal file
View File

@ -0,0 +1,185 @@
/*
* Copyright (c) 2010
* Ben Gray <ben.r.gray@gmail.com>.
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ben Gray.
* 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 BEN GRAY ``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 BEN GRAY 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$
*/
/*
* Texas Instruments - OMAP3xxx series processors
*
* Reference:
* OMAP35x Applications Processor
* Technical Reference Manual
* (omap35xx_techref.pdf)
*/
#ifndef _TI_PRCM_H_
#define _TI_PRCM_H_
typedef enum {
/* System clocks, typically you can only call ti_prcm_clk_get_source_freq()
* on these clocks as they are enabled by default.
*/
SYS_CLK = 1,
/* The MPU (ARM) core clock */
MPU_CLK = 20,
/* MMC modules */
MMC0_CLK = 100,
MMC1_CLK,
MMC2_CLK,
MMC3_CLK,
MMC4_CLK,
MMC5_CLK,
/* I2C modules */
I2C0_CLK = 200,
I2C1_CLK,
I2C2_CLK,
I2C3_CLK,
I2C4_CLK,
/* USB module(s) */
USBTLL_CLK = 300,
USBHSHOST_CLK,
USBFSHOST_CLK,
USBP1_PHY_CLK,
USBP2_PHY_CLK,
USBP1_UTMI_CLK,
USBP2_UTMI_CLK,
USBP1_HSIC_CLK,
USBP2_HSIC_CLK,
/* UART modules */
UART1_CLK = 400,
UART2_CLK,
UART3_CLK,
UART4_CLK,
/* General purpose timer modules */
GPTIMER1_CLK = 500,
GPTIMER2_CLK,
GPTIMER3_CLK,
GPTIMER4_CLK,
GPTIMER5_CLK,
GPTIMER6_CLK,
GPTIMER7_CLK,
GPTIMER8_CLK,
GPTIMER9_CLK,
GPTIMER10_CLK,
GPTIMER11_CLK,
GPTIMER12_CLK,
/* McBSP module(s) */
MCBSP1_CLK = 600,
MCBSP2_CLK,
MCBSP3_CLK,
MCBSP4_CLK,
MCBSP5_CLK,
/* General purpose I/O modules */
GPIO0_CLK = 700,
GPIO1_CLK,
GPIO2_CLK,
GPIO3_CLK,
GPIO4_CLK,
GPIO5_CLK,
GPIO6_CLK,
/* sDMA module */
SDMA_CLK = 800,
/* DMTimer modules */
DMTIMER0_CLK = 900,
DMTIMER1_CLK,
DMTIMER2_CLK,
DMTIMER3_CLK,
DMTIMER4_CLK,
DMTIMER5_CLK,
DMTIMER6_CLK,
DMTIMER7_CLK,
/* CPSW modules */
CPSW_CLK = 1000,
/* Mentor USB modules */
MUSB0_CLK = 1100,
/* EDMA module */
EDMA_TPCC_CLK = 1200,
EDMA_TPTC0_CLK,
EDMA_TPTC1_CLK,
EDMA_TPTC2_CLK,
INVALID_CLK_IDENT
} clk_ident_t;
/*
*
*/
typedef enum {
SYSCLK_CLK, /* System clock */
EXT_CLK,
F32KHZ_CLK, /* 32KHz clock */
F48MHZ_CLK, /* 48MHz clock */
F64MHZ_CLK, /* 64MHz clock */
F96MHZ_CLK, /* 96MHz clock */
} clk_src_t;
struct ti_clock_dev {
/* The profile of the timer */
clk_ident_t id;
/* A bunch of callbacks associated with the clock device */
int (*clk_activate)(struct ti_clock_dev *clkdev);
int (*clk_deactivate)(struct ti_clock_dev *clkdev);
int (*clk_set_source)(struct ti_clock_dev *clkdev,
clk_src_t clksrc);
int (*clk_accessible)(struct ti_clock_dev *clkdev);
int (*clk_get_source_freq)(struct ti_clock_dev *clkdev,
unsigned int *freq);
};
int ti_prcm_clk_valid(clk_ident_t clk);
int ti_prcm_clk_enable(clk_ident_t clk);
int ti_prcm_clk_disable(clk_ident_t clk);
int ti_prcm_clk_accessible(clk_ident_t clk);
int ti_prcm_clk_disable_autoidle(clk_ident_t clk);
int ti_prcm_clk_set_source(clk_ident_t clk, clk_src_t clksrc);
int ti_prcm_clk_get_source_freq(clk_ident_t clk, unsigned int *freq);
void ti_prcm_reset(void);
#endif /* _TI_PRCM_H_ */

493
sys/arm/ti/ti_scm.c Normal file
View File

@ -0,0 +1,493 @@
/*
* Copyright (c) 2010
* Ben Gray <ben.r.gray@gmail.com>.
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ben Gray.
* 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 BEN GRAY ``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 BEN GRAY 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.
*/
/**
* SCM - System Control Module
*
* Hopefully in the end this module will contain a bunch of utility functions
* for configuring and querying the general system control registers, but for
* now it only does pin(pad) multiplexing.
*
* This is different from the GPIO module in that it is used to configure the
* pins between modules not just GPIO input/output.
*
* This file contains the generic top level driver, however it relies on chip
* specific settings and therefore expects an array of ti_scm_padconf structs
* call ti_padconf_devmap to be located somewhere in the kernel.
*
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/frame.h>
#include <machine/resource.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 "ti_scm.h"
static struct resource_spec ti_scm_res_spec[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE }, /* Control memory window */
{ -1, 0 }
};
static struct ti_scm_softc *ti_scm_sc;
#define ti_scm_read_2(sc, reg) \
bus_space_read_2((sc)->sc_bst, (sc)->sc_bsh, (reg))
#define ti_scm_write_2(sc, reg, val) \
bus_space_write_2((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
#define ti_scm_read_4(sc, reg) \
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
#define ti_scm_write_4(sc, reg, val) \
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
/**
* ti_padconf_devmap - Array of pins, should be defined one per SoC
*
* This array is typically defined in one of the targeted *_scm_pinumx.c
* files and is specific to the given SoC platform. Each entry in the array
* corresponds to an individual pin.
*/
extern const struct ti_scm_device ti_scm_dev;
/**
* ti_scm_padconf_from_name - searches the list of pads and returns entry
* with matching ball name.
* @ballname: the name of the ball
*
* RETURNS:
* A pointer to the matching padconf or NULL if the ball wasn't found.
*/
static const struct ti_scm_padconf*
ti_scm_padconf_from_name(const char *ballname)
{
const struct ti_scm_padconf *padconf;
padconf = ti_scm_dev.padconf;
while (padconf->ballname != NULL) {
if (strcmp(ballname, padconf->ballname) == 0)
return(padconf);
padconf++;
}
return (NULL);
}
/**
* ti_scm_padconf_set_internal - sets the muxmode and state for a pad/pin
* @padconf: pointer to the pad structure
* @muxmode: the name of the mode to use for the pin, i.e. "uart1_rx"
* @state: the state to put the pad/pin in, i.e. PADCONF_PIN_???
*
*
* LOCKING:
* Internally locks it's own context.
*
* RETURNS:
* 0 on success.
* EINVAL if pin requested is outside valid range or already in use.
*/
static int
ti_scm_padconf_set_internal(struct ti_scm_softc *sc,
const struct ti_scm_padconf *padconf,
const char *muxmode, unsigned int state)
{
unsigned int mode;
uint16_t reg_val;
/* populate the new value for the PADCONF register */
reg_val = (uint16_t)(state & ti_scm_dev.padconf_sate_mask);
/* find the new mode requested */
for (mode = 0; mode < 8; mode++) {
if ((padconf->muxmodes[mode] != NULL) &&
(strcmp(padconf->muxmodes[mode], muxmode) == 0)) {
break;
}
}
/* couldn't find the mux mode */
if (mode >= 8)
return (EINVAL);
/* set the mux mode */
reg_val |= (uint16_t)(mode & ti_scm_dev.padconf_muxmode_mask);
printf("setting internal %x for %s\n", reg_val, muxmode);
/* write the register value (16-bit writes) */
ti_scm_write_2(sc, padconf->reg_off, reg_val);
return (0);
}
/**
* ti_scm_padconf_set - sets the muxmode and state for a pad/pin
* @padname: the name of the pad, i.e. "c12"
* @muxmode: the name of the mode to use for the pin, i.e. "uart1_rx"
* @state: the state to put the pad/pin in, i.e. PADCONF_PIN_???
*
*
* LOCKING:
* Internally locks it's own context.
*
* RETURNS:
* 0 on success.
* EINVAL if pin requested is outside valid range or already in use.
*/
int
ti_scm_padconf_set(const char *padname, const char *muxmode, unsigned int state)
{
const struct ti_scm_padconf *padconf;
if (!ti_scm_sc)
return (ENXIO);
/* find the pin in the devmap */
padconf = ti_scm_padconf_from_name(padname);
if (padconf == NULL)
return (EINVAL);
return (ti_scm_padconf_set_internal(ti_scm_sc, padconf, muxmode, state));
}
/**
* ti_scm_padconf_get - gets the muxmode and state for a pad/pin
* @padname: the name of the pad, i.e. "c12"
* @muxmode: upon return will contain the name of the muxmode of the pin
* @state: upon return will contain the state of the the pad/pin
*
*
* LOCKING:
* Internally locks it's own context.
*
* RETURNS:
* 0 on success.
* EINVAL if pin requested is outside valid range or already in use.
*/
int
ti_scm_padconf_get(const char *padname, const char **muxmode,
unsigned int *state)
{
const struct ti_scm_padconf *padconf;
uint16_t reg_val;
if (!ti_scm_sc)
return (ENXIO);
/* find the pin in the devmap */
padconf = ti_scm_padconf_from_name(padname);
if (padconf == NULL)
return (EINVAL);
/* read the register value (16-bit reads) */
reg_val = ti_scm_read_2(ti_scm_sc, padconf->reg_off);
/* save the state */
if (state)
*state = (reg_val & ti_scm_dev.padconf_sate_mask);
/* save the mode */
if (muxmode)
*muxmode = padconf->muxmodes[(reg_val & ti_scm_dev.padconf_muxmode_mask)];
return (0);
}
/**
* ti_scm_padconf_set_gpiomode - converts a pad to GPIO mode.
* @gpio: the GPIO pin number (0-195)
* @state: the state to put the pad/pin in, i.e. PADCONF_PIN_???
*
*
*
* LOCKING:
* Internally locks it's own context.
*
* RETURNS:
* 0 on success.
* EINVAL if pin requested is outside valid range or already in use.
*/
int
ti_scm_padconf_set_gpiomode(uint32_t gpio, unsigned int state)
{
const struct ti_scm_padconf *padconf;
uint16_t reg_val;
if (!ti_scm_sc)
return (ENXIO);
/* find the gpio pin in the padconf array */
padconf = ti_scm_dev.padconf;
while (padconf->ballname != NULL) {
if (padconf->gpio_pin == gpio)
break;
padconf++;
}
if (padconf->ballname == NULL)
return (EINVAL);
/* populate the new value for the PADCONF register */
reg_val = (uint16_t)(state & ti_scm_dev.padconf_sate_mask);
/* set the mux mode */
reg_val |= (uint16_t)(padconf->gpio_mode & ti_scm_dev.padconf_muxmode_mask);
/* write the register value (16-bit writes) */
ti_scm_write_2(ti_scm_sc, padconf->reg_off, reg_val);
return (0);
}
/**
* ti_scm_padconf_get_gpiomode - gets the current GPIO mode of the pin
* @gpio: the GPIO pin number (0-195)
* @state: upon return will contain the state
*
*
*
* LOCKING:
* Internally locks it's own context.
*
* RETURNS:
* 0 on success.
* EINVAL if pin requested is outside valid range or not configured as GPIO.
*/
int
ti_scm_padconf_get_gpiomode(uint32_t gpio, unsigned int *state)
{
const struct ti_scm_padconf *padconf;
uint16_t reg_val;
if (!ti_scm_sc)
return (ENXIO);
/* find the gpio pin in the padconf array */
padconf = ti_scm_dev.padconf;
while (padconf->ballname != NULL) {
if (padconf->gpio_pin == gpio)
break;
padconf++;
}
if (padconf->ballname == NULL)
return (EINVAL);
/* read the current register settings */
reg_val = ti_scm_read_2(ti_scm_sc, padconf->reg_off);
/* check to make sure the pins is configured as GPIO in the first state */
if ((reg_val & ti_scm_dev.padconf_muxmode_mask) != padconf->gpio_mode)
return (EINVAL);
/* read and store the reset of the state, i.e. pull-up, pull-down, etc */
if (state)
*state = (reg_val & ti_scm_dev.padconf_sate_mask);
return (0);
}
/**
* ti_scm_padconf_init_from_hints - processes the hints for padconf
* @sc: the driver soft context
*
*
*
* LOCKING:
* Internally locks it's own context.
*
* RETURNS:
* 0 on success.
* EINVAL if pin requested is outside valid range or already in use.
*/
static int
ti_scm_padconf_init_from_fdt(struct ti_scm_softc *sc)
{
const struct ti_scm_padconf *padconf;
const struct ti_scm_padstate *padstates;
int err;
phandle_t node;
int len;
char *fdt_pad_config;
int i;
char *padname, *muxname, *padstate;
node = ofw_bus_get_node(sc->sc_dev);
len = OF_getproplen(node, "scm-pad-config");
OF_getprop_alloc(node, "scm-pad-config", 1, (void **)&fdt_pad_config);
i = len;
while (i > 0) {
padname = fdt_pad_config;
fdt_pad_config += strlen(padname) + 1;
i -= strlen(padname) + 1;
if (i <= 0)
break;
muxname = fdt_pad_config;
fdt_pad_config += strlen(muxname) + 1;
i -= strlen(muxname) + 1;
if (i <= 0)
break;
padstate = fdt_pad_config;
fdt_pad_config += strlen(padstate) + 1;
i -= strlen(padstate) + 1;
if (i < 0)
break;
padconf = ti_scm_dev.padconf;
while (padconf->ballname != NULL) {
if (strcmp(padconf->ballname, padname) == 0) {
padstates = ti_scm_dev.padstate;
err = 1;
while (padstates->state != NULL) {
if (strcmp(padstates->state, padstate) == 0) {
err = ti_scm_padconf_set_internal(sc,
padconf, muxname, padstates->reg);
}
padstates++;
}
if (err)
device_printf(sc->sc_dev, "err: failed to configure"
"pin \"%s\"\n", padconf->ballname);
}
padconf++;
}
}
return (0);
}
/*
* Device part of OMAP SCM driver
*/
static int
ti_scm_probe(device_t dev)
{
if (!ofw_bus_is_compatible(dev, "ti,scm"))
return (ENXIO);
device_set_desc(dev, "TI Control Module");
return (BUS_PROBE_DEFAULT);
}
/**
* ti_scm_attach - attaches the timer to the simplebus
* @dev: new device
*
* Reserves memory and interrupt resources, stores the softc structure
* globally and registers both the timecount and eventtimer objects.
*
* RETURNS
* Zero on sucess or ENXIO if an error occuried.
*/
static int
ti_scm_attach(device_t dev)
{
struct ti_scm_softc *sc = device_get_softc(dev);
if (ti_scm_sc)
return (ENXIO);
sc->sc_dev = dev;
if (bus_alloc_resources(dev, ti_scm_res_spec, sc->sc_res)) {
device_printf(dev, "could not allocate resources\n");
return (ENXIO);
}
/* Global timer interface */
sc->sc_bst = rman_get_bustag(sc->sc_res[0]);
sc->sc_bsh = rman_get_bushandle(sc->sc_res[0]);
ti_scm_sc = sc;
ti_scm_padconf_init_from_fdt(sc);
return (0);
}
int
ti_scm_reg_read_4(uint32_t reg, uint32_t *val)
{
if (!ti_scm_sc)
return (ENXIO);
*val = ti_scm_read_4(ti_scm_sc, reg);
return (0);
}
int
ti_scm_reg_write_4(uint32_t reg, uint32_t val)
{
if (!ti_scm_sc)
return (ENXIO);
ti_scm_write_4(ti_scm_sc, reg, val);
return (0);
}
static device_method_t ti_scm_methods[] = {
DEVMETHOD(device_probe, ti_scm_probe),
DEVMETHOD(device_attach, ti_scm_attach),
{ 0, 0 }
};
static driver_t ti_scm_driver = {
"ti_scm",
ti_scm_methods,
sizeof(struct ti_scm_softc),
};
static devclass_t ti_scm_devclass;
DRIVER_MODULE(ti_scm, simplebus, ti_scm_driver, ti_scm_devclass, 0, 0);

84
sys/arm/ti/ti_scm.h Normal file
View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2010
* Ben Gray <ben.r.gray@gmail.com>.
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ben Gray.
* 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 BEN GRAY ``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 BEN GRAY 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$
*/
/**
* Functions to configure the PIN multiplexing on the chip.
*
* This is different from the GPIO module in that it is used to configure the
* pins between modules not just GPIO input output.
*
*/
#ifndef _TI_SCM_H_
#define _TI_SCM_H_
struct ti_scm_padconf {
uint16_t reg_off;
uint16_t gpio_pin;
uint16_t gpio_mode;
const char *ballname;
const char *muxmodes[8];
};
struct ti_scm_padstate {
const char *state;
uint16_t reg;
};
struct ti_scm_device {
uint16_t padconf_muxmode_mask;
uint16_t padconf_sate_mask;
struct ti_scm_padstate *padstate;
struct ti_scm_padconf *padconf;
};
struct ti_scm_softc {
device_t sc_dev;
struct resource * sc_res[4];
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
};
int ti_scm_padconf_set(const char *padname, const char *muxmode,
unsigned int state);
int ti_scm_padconf_get(const char *padname, const char **muxmode,
unsigned int *state);
int ti_scm_padconf_set_gpiomode(uint32_t gpio, unsigned int state);
int ti_scm_padconf_get_gpiomode(uint32_t gpio, unsigned int *state);
int ti_scm_padconf_set_gpioflags(uint32_t gpio, uint32_t flags);
void ti_scm_padconf_get_gpioflags(uint32_t gpio, uint32_t *flags);
int ti_scm_reg_read_4(uint32_t reg, uint32_t *val);
int ti_scm_reg_write_4(uint32_t reg, uint32_t val);
#endif /* _TI_SCM_H_ */

1246
sys/arm/ti/ti_sdma.c Normal file

File diff suppressed because it is too large Load Diff

111
sys/arm/ti/ti_sdma.h Normal file
View File

@ -0,0 +1,111 @@
/*-
* Copyright (c) 2011
* Ben Gray <ben.r.gray@gmail.com>.
* 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 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 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$
*/
/**
* sDMA device driver interface for the TI SoC
*
* See the ti_sdma.c file for implementation details.
*
* Reference:
* OMAP35x Applications Processor
* Technical Reference Manual
* (omap35xx_techref.pdf)
*/
#ifndef _TI_DMA_H_
#define _TI_DMA_H_
#define TI_SDMA_ENDIAN_BIG 0x1
#define TI_SDMA_ENDIAN_LITTLE 0x0
#define TI_SDMA_BURST_NONE 0x0
#define TI_SDMA_BURST_16 0x1
#define TI_SDMA_BURST_32 0x2
#define TI_SDMA_BURST_64 0x3
#define TI_SDMA_DATA_8BITS_SCALAR 0x0
#define TI_SDMA_DATA_16BITS_SCALAR 0x1
#define TI_SDMA_DATA_32BITS_SCALAR 0x2
#define TI_SDMA_ADDR_CONSTANT 0x0
#define TI_SDMA_ADDR_POST_INCREMENT 0x1
#define TI_SDMA_ADDR_SINGLE_INDEX 0x2
#define TI_SDMA_ADDR_DOUBLE_INDEX 0x3
/**
* Status flags for the DMA callback
*
*/
#define TI_SDMA_STATUS_DROP (1UL << 1)
#define TI_SDMA_STATUS_HALF (1UL << 2)
#define TI_SDMA_STATUS_FRAME (1UL << 3)
#define TI_SDMA_STATUS_LAST (1UL << 4)
#define TI_SDMA_STATUS_BLOCK (1UL << 5)
#define TI_SDMA_STATUS_SYNC (1UL << 6)
#define TI_SDMA_STATUS_PKT (1UL << 7)
#define TI_SDMA_STATUS_TRANS_ERR (1UL << 8)
#define TI_SDMA_STATUS_SECURE_ERR (1UL << 9)
#define TI_SDMA_STATUS_SUPERVISOR_ERR (1UL << 10)
#define TI_SDMA_STATUS_MISALIGNED_ADRS_ERR (1UL << 11)
#define TI_SDMA_STATUS_DRAIN_END (1UL << 12)
#define TI_SDMA_SYNC_FRAME (1UL << 0)
#define TI_SDMA_SYNC_BLOCK (1UL << 1)
#define TI_SDMA_SYNC_PACKET (TI_SDMA_SYNC_FRAME | TI_SDMA_SYNC_BLOCK)
#define TI_SDMA_SYNC_TRIG_ON_SRC (1UL << 8)
#define TI_SDMA_SYNC_TRIG_ON_DST (1UL << 9)
#define TI_SDMA_IRQ_FLAG_DROP (1UL << 1)
#define TI_SDMA_IRQ_FLAG_HALF_FRAME_COMPL (1UL << 2)
#define TI_SDMA_IRQ_FLAG_FRAME_COMPL (1UL << 3)
#define TI_SDMA_IRQ_FLAG_START_LAST_FRAME (1UL << 4)
#define TI_SDMA_IRQ_FLAG_BLOCK_COMPL (1UL << 5)
#define TI_SDMA_IRQ_FLAG_ENDOF_PKT (1UL << 7)
#define TI_SDMA_IRQ_FLAG_DRAIN (1UL << 12)
int ti_sdma_activate_channel(unsigned int *ch,
void (*callback)(unsigned int ch, uint32_t status, void *data), void *data);
int ti_sdma_deactivate_channel(unsigned int ch);
int ti_sdma_start_xfer(unsigned int ch, unsigned int src_paddr,
unsigned long dst_paddr, unsigned int frmcnt, unsigned int elmcnt);
int ti_sdma_start_xfer_packet(unsigned int ch, unsigned int src_paddr,
unsigned long dst_paddr, unsigned int frmcnt, unsigned int elmcnt,
unsigned int pktsize);
int ti_sdma_stop_xfer(unsigned int ch);
int ti_sdma_enable_channel_irq(unsigned int ch, uint32_t flags);
int ti_sdma_disable_channel_irq(unsigned int ch);
int ti_sdma_get_channel_status(unsigned int ch, uint32_t *status);
int ti_sdma_set_xfer_endianess(unsigned int ch, unsigned int src, unsigned int dst);
int ti_sdma_set_xfer_burst(unsigned int ch, unsigned int src, unsigned int dst);
int ti_sdma_set_xfer_data_type(unsigned int ch, unsigned int type);
int ti_sdma_set_callback(unsigned int ch,
void (*callback)(unsigned int ch, uint32_t status, void *data), void *data);
int ti_sdma_sync_params(unsigned int ch, unsigned int trigger, unsigned int mode);
int ti_sdma_set_addr_mode(unsigned int ch, unsigned int src_mode, unsigned int dst_mode);
#endif /* _TI_SDMA_H_ */

133
sys/arm/ti/ti_sdmareg.h Normal file
View File

@ -0,0 +1,133 @@
/*-
* Copyright (c) 2011
* Ben Gray <ben.r.gray@gmail.com>.
* 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 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 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 __TI_SDMAREG_H__
#define __TI_SDMAREG_H__
/**
* The number of DMA channels possible on the controller.
*/
#define NUM_DMA_CHANNELS 32
#define NUM_DMA_IRQS 4
/**
* Register offsets
*/
#define DMA4_REVISION 0x0000
#define DMA4_IRQSTATUS_L(j) (0x0008 + ((j) * 0x4))
#define DMA4_IRQENABLE_L(j) (0x0018 + ((j) * 0x4))
#define DMA4_SYSSTATUS 0x0028
#define DMA4_OCP_SYSCONFIG 0x002C
#define DMA4_CAPS_0 0x0064
#define DMA4_CAPS_2 0x006C
#define DMA4_CAPS_3 0x0070
#define DMA4_CAPS_4 0x0074
#define DMA4_GCR 0x0078
#define DMA4_CCR(i) (0x0080 + ((i) * 0x60))
#define DMA4_CLNK_CTRL(i) (0x0084 + ((i) * 0x60))
#define DMA4_CICR(i) (0x0088 + ((i) * 0x60))
#define DMA4_CSR(i) (0x008C + ((i) * 0x60))
#define DMA4_CSDP(i) (0x0090 + ((i) * 0x60))
#define DMA4_CEN(i) (0x0094 + ((i) * 0x60))
#define DMA4_CFN(i) (0x0098 + ((i) * 0x60))
#define DMA4_CSSA(i) (0x009C + ((i) * 0x60))
#define DMA4_CDSA(i) (0x00A0 + ((i) * 0x60))
#define DMA4_CSE(i) (0x00A4 + ((i) * 0x60))
#define DMA4_CSF(i) (0x00A8 + ((i) * 0x60))
#define DMA4_CDE(i) (0x00AC + ((i) * 0x60))
#define DMA4_CDF(i) (0x00B0 + ((i) * 0x60))
#define DMA4_CSAC(i) (0x00B4 + ((i) * 0x60))
#define DMA4_CDAC(i) (0x00B8 + ((i) * 0x60))
#define DMA4_CCEN(i) (0x00BC + ((i) * 0x60))
#define DMA4_CCFN(i) (0x00C0 + ((i) * 0x60))
#define DMA4_COLOR(i) (0x00C4 + ((i) * 0x60))
/* The following register are only defined on OMAP44xx (and newer?) */
#define DMA4_CDP(i) (0x00D0 + ((i) * 0x60))
#define DMA4_CNDP(i) (0x00D4 + ((i) * 0x60))
#define DMA4_CCDN(i) (0x00D8 + ((i) * 0x60))
/**
* Various register field settings
*/
#define DMA4_CSDP_DATA_TYPE(x) (((x) & 0x3) << 0)
#define DMA4_CSDP_SRC_BURST_MODE(x) (((x) & 0x3) << 7)
#define DMA4_CSDP_DST_BURST_MODE(x) (((x) & 0x3) << 14)
#define DMA4_CSDP_SRC_ENDIANISM(x) (((x) & 0x1) << 21)
#define DMA4_CSDP_DST_ENDIANISM(x) (((x) & 0x1) << 19)
#define DMA4_CSDP_WRITE_MODE(x) (((x) & 0x3) << 16)
#define DMA4_CSDP_SRC_PACKED(x) (((x) & 0x1) << 6)
#define DMA4_CSDP_DST_PACKED(x) (((x) & 0x1) << 13)
#define DMA4_CCR_DST_ADDRESS_MODE(x) (((x) & 0x3) << 14)
#define DMA4_CCR_SRC_ADDRESS_MODE(x) (((x) & 0x3) << 12)
#define DMA4_CCR_READ_PRIORITY(x) (((x) & 0x1) << 6)
#define DMA4_CCR_WRITE_PRIORITY(x) (((x) & 0x1) << 26)
#define DMA4_CCR_SYNC_TRIGGER(x) ((((x) & 0x60) << 14) \
| ((x) & 0x1f))
#define DMA4_CCR_FRAME_SYNC(x) (((x) & 0x1) << 5)
#define DMA4_CCR_BLOCK_SYNC(x) (((x) & 0x1) << 18)
#define DMA4_CCR_SEL_SRC_DST_SYNC(x) (((x) & 0x1) << 24)
#define DMA4_CCR_PACKET_TRANS (DMA4_CCR_FRAME_SYNC(1) | \
DMA4_CCR_BLOCK_SYNC(1) )
#define DMA4_CSR_DROP (1UL << 1)
#define DMA4_CSR_HALF (1UL << 2)
#define DMA4_CSR_FRAME (1UL << 3)
#define DMA4_CSR_LAST (1UL << 4)
#define DMA4_CSR_BLOCK (1UL << 5)
#define DMA4_CSR_SYNC (1UL << 6)
#define DMA4_CSR_PKT (1UL << 7)
#define DMA4_CSR_TRANS_ERR (1UL << 8)
#define DMA4_CSR_SECURE_ERR (1UL << 9)
#define DMA4_CSR_SUPERVISOR_ERR (1UL << 10)
#define DMA4_CSR_MISALIGNED_ADRS_ERR (1UL << 11)
#define DMA4_CSR_DRAIN_END (1UL << 12)
#define DMA4_CSR_CLEAR_MASK (0xffe)
#define DMA4_CICR_DROP_IE (1UL << 1)
#define DMA4_CICR_HALF_IE (1UL << 2)
#define DMA4_CICR_FRAME_IE (1UL << 3)
#define DMA4_CICR_LAST_IE (1UL << 4)
#define DMA4_CICR_BLOCK_IE (1UL << 5)
#define DMA4_CICR_PKT_IE (1UL << 7)
#define DMA4_CICR_TRANS_ERR_IE (1UL << 8)
#define DMA4_CICR_SECURE_ERR_IE (1UL << 9)
#define DMA4_CICR_SUPERVISOR_ERR_IE (1UL << 10)
#define DMA4_CICR_MISALIGNED_ADRS_ERR_IE (1UL << 11)
#define DMA4_CICR_DRAIN_IE (1UL << 12)
/**
* The following H/W revision values were found be experimentation, TI don't
* publish the revision numbers. The TRM says "TI internal Data".
*/
#define DMA4_OMAP3_REV 0x00000040
#define DMA4_OMAP4_REV 0x00010900
#endif /* __TI_SDMAREG_H__ */

37
sys/arm/ti/ti_smc.S Normal file
View File

@ -0,0 +1,37 @@
/*-
* Copyright (c) 2012 Olivier Houchard. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <machine/armreg.h>
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
/* Issue a smc #0 call */
/* r0 and r1 contains the eventual arguments, r2 contains the function ID */
ENTRY(ti_smc0)
stmfd sp!, {r4-r12, lr}
mov r12, r2 /* the rom expects the function ID in r12 */
dsb
smc #0
ldmfd sp!, {r4-r12, pc}

33
sys/arm/ti/ti_smc.h Normal file
View File

@ -0,0 +1,33 @@
/*-
* Copyright (c) 2012 Olivier Houchard. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* $FreeBSD$
*/
#ifndef TI_SMC_H_
#define TI_SMC_H_
uint32_t ti_smc0(uint32_t r0, uint32_t r1, uint32_t function_id);
#endif /* TI_SMC_H_ */

41
sys/arm/ti/tivar.h Normal file
View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2010
* Ben Gray <ben.r.gray@gmail.com>.
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ben Gray.
* 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 BEN GRAY ``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 BEN GRAY 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 _TIVAR_H_
#define _TIVAR_H_
/* board-dependent reset function implementation */
extern void (*ti_cpu_reset)(void);
#endif /* _TIVAR_H_ */

464
sys/arm/ti/twl/twl.c Normal file
View File

@ -0,0 +1,464 @@
/*-
* Copyright (c) 2011
* Ben Gray <ben.r.gray@gmail.com>.
* 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 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 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$");
/*
* Texas Instruments TWL4030/TWL5030/TWL60x0/TPS659x0 Power Management and
* Audio CODEC devices.
*
* This code is based on the Linux TWL multifunctional device driver, which is
* copyright (C) 2005-2006 Texas Instruments, Inc.
*
* These chips are typically used as support ICs for the OMAP range of embedded
* ARM processes/SOC from Texas Instruments. They are typically used to control
* on board voltages, however some variants have other features like audio
* codecs, USB OTG transceivers, RTC, PWM, etc.
*
* This driver acts as a bus for more specific companion devices.
*
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/sysctl.h>
#include <sys/mutex.h>
#include <sys/malloc.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/frame.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <dev/iicbus/iicbus.h>
#include <dev/iicbus/iiconf.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include "arm/ti/twl/twl.h"
/* TWL device IDs */
#define TWL_DEVICE_UNKNOWN 0xffff
#define TWL_DEVICE_4030 0x4030
#define TWL_DEVICE_6025 0x6025
#define TWL_DEVICE_6030 0x6030
/* Each TWL device typically has more than one I2C address */
#define TWL_MAX_SUBADDRS 4
/* The maxium number of bytes that can be written in one call */
#define TWL_MAX_IIC_DATA_SIZE 63
/* The TWL devices typically use 4 I2C address for the different internal
* register sets, plus one SmartReflex I2C address.
*/
#define TWL_CHIP_ID0 0x48
#define TWL_CHIP_ID1 0x49
#define TWL_CHIP_ID2 0x4A
#define TWL_CHIP_ID3 0x4B
#define TWL_SMARTREFLEX_CHIP_ID 0x12
#define TWL_INVALID_CHIP_ID 0xff
struct twl_softc {
device_t sc_dev;
struct mtx sc_mtx;
unsigned int sc_type;
uint8_t sc_subaddr_map[TWL_MAX_SUBADDRS];
struct intr_config_hook sc_scan_hook;
device_t sc_vreg;
device_t sc_clks;
};
/**
* Macros for driver mutex locking
*/
#define TWL_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
#define TWL_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
#define TWL_LOCK_INIT(_sc) \
mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_dev), \
"twl", MTX_DEF)
#define TWL_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx);
#define TWL_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED);
#define TWL_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
/**
* twl_is_4030 - returns true if the device is TWL4030
* twl_is_6025 - returns true if the device is TWL6025
* twl_is_6030 - returns true if the device is TWL6030
* @sc: device soft context
*
* Returns a non-zero value if the device matches.
*
* RETURNS:
* Returns a non-zero value if the device matches, otherwise zero.
*/
int
twl_is_4030(device_t dev)
{
struct twl_softc *sc = device_get_softc(dev);
return (sc->sc_type == TWL_DEVICE_4030);
}
int
twl_is_6025(device_t dev)
{
struct twl_softc *sc = device_get_softc(dev);
return (sc->sc_type == TWL_DEVICE_6025);
}
int
twl_is_6030(device_t dev)
{
struct twl_softc *sc = device_get_softc(dev);
return (sc->sc_type == TWL_DEVICE_6030);
}
/**
* twl_read - read one or more registers from the TWL device
* @sc: device soft context
* @nsub: the sub-module to read from
* @reg: the register offset within the module to read
* @buf: buffer to store the bytes in
* @cnt: the number of bytes to read
*
* Reads one or more registers and stores the result in the suppled buffer.
*
* RETURNS:
* Zero on success or an error code on failure.
*/
int
twl_read(device_t dev, uint8_t nsub, uint8_t reg, uint8_t *buf, uint16_t cnt)
{
struct twl_softc *sc;
struct iic_msg msg[2];
uint8_t addr;
int rc;
sc = device_get_softc(dev);
TWL_LOCK(sc);
addr = sc->sc_subaddr_map[nsub];
TWL_UNLOCK(sc);
if (addr == TWL_INVALID_CHIP_ID)
return (EIO);
/* Set the address to read from */
msg[0].slave = addr;
msg[0].flags = IIC_M_WR | IIC_M_NOSTOP;
msg[0].len = 1;
msg[0].buf = &reg;
/* Read the data back */
msg[1].slave = addr;
msg[1].flags = IIC_M_RD;
msg[1].len = cnt;
msg[1].buf = buf;
rc = iicbus_transfer(dev, msg, 2);
if (rc != 0) {
device_printf(dev, "iicbus read failed (adr:0x%02x, reg:0x%02x)\n",
addr, reg);
return (EIO);
}
return (0);
}
/**
* twl_write - writes one or more registers to the TWL device
* @sc: device soft context
* @nsub: the sub-module to read from
* @reg: the register offset within the module to read
* @buf: data to write
* @cnt: the number of bytes to write
*
* Writes one or more registers.
*
* RETURNS:
* Zero on success or a negative error code on failure.
*/
int
twl_write(device_t dev, uint8_t nsub, uint8_t reg, uint8_t *buf, uint16_t cnt)
{
struct twl_softc *sc;
struct iic_msg msg;
uint8_t addr;
uint8_t tmp_buf[TWL_MAX_IIC_DATA_SIZE + 1];
int rc;
if (cnt > TWL_MAX_IIC_DATA_SIZE)
return (ENOMEM);
/* Set the register address as the first byte */
tmp_buf[0] = reg;
memcpy(&tmp_buf[1], buf, cnt);
sc = device_get_softc(dev);
TWL_LOCK(sc);
addr = sc->sc_subaddr_map[nsub];
TWL_UNLOCK(sc);
if (addr == TWL_INVALID_CHIP_ID)
return (EIO);
/* Setup the transfer and execute it */
msg.slave = addr;
msg.flags = IIC_M_WR;
msg.len = cnt + 1;
msg.buf = tmp_buf;
rc = iicbus_transfer(dev, &msg, 1);
if (rc != 0) {
device_printf(sc->sc_dev, "iicbus write failed (adr:0x%02x, reg:0x%02x)\n",
addr, reg);
return (EIO);
}
return (0);
}
/**
* twl_test_present - checks if a device with given address is present
* @sc: device soft context
* @addr: the address of the device to scan for
*
* Sends just the address byte and checks for an ACK. If no ACK then device
* is assumed to not be present.
*
* RETURNS:
* EIO if device is not present, otherwise 0 is returned.
*/
static int
twl_test_present(struct twl_softc *sc, uint8_t addr)
{
struct iic_msg msg;
uint8_t tmp;
/* Set the address to read from */
msg.slave = addr;
msg.flags = IIC_M_RD;
msg.len = 1;
msg.buf = &tmp;
if (iicbus_transfer(sc->sc_dev, &msg, 1) != 0)
return (EIO);
return (0);
}
/**
* twl_scan - scans the i2c bus for sub modules
* @dev: the twl device
*
* TWL devices don't just have one i2c slave address, rather they have up to
* 5 other addresses, each is for separate modules within the device. This
* function scans the bus for 4 possible sub-devices and stores the info
* internally.
*
*/
static void
twl_scan(void *dev)
{
struct twl_softc *sc;
unsigned i;
uint8_t devs[TWL_MAX_SUBADDRS];
uint8_t base = TWL_CHIP_ID0;
sc = device_get_softc((device_t)dev);
memset(devs, TWL_INVALID_CHIP_ID, TWL_MAX_SUBADDRS);
/* Try each of the addresses (0x48, 0x49, 0x4a & 0x4b) to determine which
* sub modules we have.
*/
for (i = 0; i < TWL_MAX_SUBADDRS; i++) {
if (twl_test_present(sc, (base + i)) == 0) {
devs[i] = (base + i);
device_printf(sc->sc_dev, "Found (sub)device at 0x%02x\n", (base + i));
}
}
TWL_LOCK(sc);
memcpy(sc->sc_subaddr_map, devs, TWL_MAX_SUBADDRS);
TWL_UNLOCK(sc);
/* Finished with the interrupt hook */
config_intrhook_disestablish(&sc->sc_scan_hook);
}
/**
* twl_probe -
* @dev: the twl device
*
* Scans the FDT for a match for the device, possible compatible device
* strings are; "ti,twl6030", "ti,twl6025", "ti,twl4030".
*
* The FDT compat string also determines the type of device (it is currently
* not possible to dynamically determine the device type).
*
*/
static int
twl_probe(device_t dev)
{
phandle_t node;
const char *compat;
int len, l;
struct twl_softc *sc;
if ((compat = ofw_bus_get_compat(dev)) == NULL)
return (ENXIO);
if ((node = ofw_bus_get_node(dev)) == 0)
return (ENXIO);
/* Get total 'compatible' prop len */
if ((len = OF_getproplen(node, "compatible")) <= 0)
return (ENXIO);
sc = device_get_softc(dev);
sc->sc_dev = dev;
sc->sc_type = TWL_DEVICE_UNKNOWN;
while (len > 0) {
if (strncasecmp(compat, "ti,twl6030", 10) == 0)
sc->sc_type = TWL_DEVICE_6030;
else if (strncasecmp(compat, "ti,twl6025", 10) == 0)
sc->sc_type = TWL_DEVICE_6025;
else if (strncasecmp(compat, "ti,twl4030", 10) == 0)
sc->sc_type = TWL_DEVICE_4030;
if (sc->sc_type != TWL_DEVICE_UNKNOWN)
break;
/* Slide to the next sub-string. */
l = strlen(compat) + 1;
compat += l;
len -= l;
}
switch (sc->sc_type) {
case TWL_DEVICE_4030:
device_set_desc(dev, "TI TWL4030/TPS659x0 Companion IC");
break;
case TWL_DEVICE_6025:
device_set_desc(dev, "TI TWL6025 Companion IC");
break;
case TWL_DEVICE_6030:
device_set_desc(dev, "TI TWL6030 Companion IC");
break;
case TWL_DEVICE_UNKNOWN:
default:
return (ENXIO);
}
return (0);
}
static int
twl_attach(device_t dev)
{
struct twl_softc *sc;
sc = device_get_softc(dev);
sc->sc_dev = dev;
TWL_LOCK_INIT(sc);
/* We have to wait until interrupts are enabled. I2C read and write
* only works if the interrupts are available.
*/
sc->sc_scan_hook.ich_func = twl_scan;
sc->sc_scan_hook.ich_arg = dev;
if (config_intrhook_establish(&sc->sc_scan_hook) != 0)
return (ENOMEM);
/* FIXME: should be in DTS file */
if ((sc->sc_vreg = device_add_child(dev, "twl_vreg", -1)) == NULL)
device_printf(dev, "could not allocate twl_vreg instance\n");
if ((sc->sc_clks = device_add_child(dev, "twl_clks", -1)) == NULL)
device_printf(dev, "could not allocate twl_clks instance\n");
return (bus_generic_attach(dev));
}
static int
twl_detach(device_t dev)
{
struct twl_softc *sc;
sc = device_get_softc(dev);
if (sc->sc_vreg)
device_delete_child(dev, sc->sc_vreg);
if (sc->sc_clks)
device_delete_child(dev, sc->sc_clks);
TWL_LOCK_DESTROY(sc);
return (0);
}
static device_method_t twl_methods[] = {
DEVMETHOD(device_probe, twl_probe),
DEVMETHOD(device_attach, twl_attach),
DEVMETHOD(device_detach, twl_detach),
{0, 0},
};
static driver_t twl_driver = {
"twl",
twl_methods,
sizeof(struct twl_softc),
};
static devclass_t twl_devclass;
DRIVER_MODULE(twl, iicbus, twl_driver, twl_devclass, 0, 0);
MODULE_VERSION(twl, 1);

39
sys/arm/ti/twl/twl.h Normal file
View File

@ -0,0 +1,39 @@
/*-
* Copyright (c) 2011
* Ben Gray <ben.r.gray@gmail.com>.
* 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 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 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 _TWL_H_
#define _TWL_H_
int twl_read(device_t dev, uint8_t nsub, uint8_t reg, uint8_t *buf, uint16_t cnt);
int twl_write(device_t dev, uint8_t nsub, uint8_t reg, uint8_t *buf, uint16_t cnt);
int twl_is_4030(device_t dev);
int twl_is_6025(device_t dev);
int twl_is_6030(device_t dev);
#endif /* _TWL_H_ */

675
sys/arm/ti/twl/twl_clks.c Normal file
View File

@ -0,0 +1,675 @@
/*-
* Copyright (c) 2012
* Ben Gray <bgray@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 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 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$");
/*
* Texas Instruments TWL4030/TWL5030/TWL60x0/TPS659x0 Power Management.
*
* This driver covers the external clocks, allows for enabling &
* disabling their output.
*
*
*
* FLATTENED DEVICE TREE (FDT)
* Startup override settings can be specified in the FDT, if they are they
* should be under the twl parent device and take the following form:
*
* external-clocks = "name1", "state1",
* "name2", "state2",
* etc;
*
* Each override should be a pair, the first entry is the name of the clock
* the second is the state to set, possible strings are either "on" or "off".
*
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/sysctl.h>
#include <sys/sx.h>
#include <sys/malloc.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/frame.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include "twl.h"
#include "twl_clks.h"
static int twl_clks_debug = 1;
/*
* Power Groups bits for the 4030 and 6030 devices
*/
#define TWL4030_P3_GRP 0x80 /* Peripherals, power group */
#define TWL4030_P2_GRP 0x40 /* Modem power group */
#define TWL4030_P1_GRP 0x20 /* Application power group (FreeBSD control) */
#define TWL6030_P3_GRP 0x04 /* Modem power group */
#define TWL6030_P2_GRP 0x02 /* Connectivity power group */
#define TWL6030_P1_GRP 0x01 /* Application power group (FreeBSD control) */
/*
* Register offsets within a clk regulator register set
*/
#define TWL_CLKS_GRP 0x00 /* Regulator GRP register */
#define TWL_CLKS_STATE 0x02 /* TWL6030 only */
/**
* Support voltage regulators for the different IC's
*/
struct twl_clock {
const char *name;
uint8_t subdev;
uint8_t regbase;
};
static const struct twl_clock twl4030_clocks[] = {
{ "32kclkout", 0, 0x8e },
{ NULL, 0, 0x00 }
};
static const struct twl_clock twl6030_clocks[] = {
{ "clk32kg", 0, 0xbc },
{ "clk32kao", 0, 0xb9 },
{ "clk32kaudio", 0, 0xbf },
{ NULL, 0, 0x00 }
};
#define TWL_CLKS_MAX_NAMELEN 32
struct twl_clk_entry {
LIST_ENTRY(twl_clk_entry) link;
struct sysctl_oid *oid;
char name[TWL_CLKS_MAX_NAMELEN];
uint8_t sub_dev; /* the sub-device number for the clock */
uint8_t reg_off; /* register base address of the clock */
};
struct twl_clks_softc {
device_t sc_dev; /* twl_clk device */
device_t sc_pdev; /* parent device (twl) */
struct sx sc_sx; /* internal locking */
struct intr_config_hook sc_init_hook;
LIST_HEAD(twl_clk_list, twl_clk_entry) sc_clks_list;
};
/**
* Macros for driver shared locking
*/
#define TWL_CLKS_XLOCK(_sc) sx_xlock(&(_sc)->sc_sx)
#define TWL_CLKS_XUNLOCK(_sc) sx_xunlock(&(_sc)->sc_sx)
#define TWL_CLKS_SLOCK(_sc) sx_slock(&(_sc)->sc_sx)
#define TWL_CLKS_SUNLOCK(_sc) sx_sunlock(&(_sc)->sc_sx)
#define TWL_CLKS_LOCK_INIT(_sc) sx_init(&(_sc)->sc_sx, "twl_clks")
#define TWL_CLKS_LOCK_DESTROY(_sc) sx_destroy(&(_sc)->sc_sx);
#define TWL_CLKS_ASSERT_LOCKED(_sc) sx_assert(&(_sc)->sc_sx, SA_LOCKED);
#define TWL_CLKS_LOCK_UPGRADE(_sc) \
do { \
while (!sx_try_upgrade(&(_sc)->sc_sx)) \
pause("twl_clks_ex", (hz / 100)); \
} while(0)
#define TWL_CLKS_LOCK_DOWNGRADE(_sc) sx_downgrade(&(_sc)->sc_sx);
/**
* twl_clks_read_1 - read single register from the TWL device
* twl_clks_write_1 - writes a single register in the TWL device
* @sc: device context
* @clk: the clock device we're reading from / writing to
* @off: offset within the clock's register set
* @val: the value to write or a pointer to a variable to store the result
*
* RETURNS:
* Zero on success or an error code on failure.
*/
static inline int
twl_clks_read_1(struct twl_clks_softc *sc, struct twl_clk_entry *clk,
uint8_t off, uint8_t *val)
{
return (twl_read(sc->sc_pdev, clk->sub_dev, clk->reg_off + off, val, 1));
}
static inline int
twl_clks_write_1(struct twl_clks_softc *sc, struct twl_clk_entry *clk,
uint8_t off, uint8_t val)
{
return (twl_write(sc->sc_pdev, clk->sub_dev, clk->reg_off + off, &val, 1));
}
/**
* twl_clks_is_enabled - determines if a clock is enabled
* @dev: TWL CLK device
* @name: the name of the clock
* @enabled: upon return will contain the 'enabled' state
*
* LOCKING:
* Internally the function takes and releases the TWL lock.
*
* RETURNS:
* Zero on success or a negative error code on failure.
*/
int
twl_clks_is_enabled(device_t dev, const char *name, int *enabled)
{
struct twl_clks_softc *sc = device_get_softc(dev);
struct twl_clk_entry *clk;
int found = 0;
int err;
uint8_t grp, state;
TWL_CLKS_SLOCK(sc);
LIST_FOREACH(clk, &sc->sc_clks_list, link) {
if (strcmp(clk->name, name) == 0) {
found = 1;
break;
}
}
if (!found) {
TWL_CLKS_SUNLOCK(sc);
return (EINVAL);
}
if (twl_is_4030(sc->sc_pdev)) {
err = twl_clks_read_1(sc, clk, TWL_CLKS_GRP, &grp);
if (!err)
*enabled = (grp & TWL4030_P1_GRP);
} else if (twl_is_6030(sc->sc_pdev) || twl_is_6025(sc->sc_pdev)) {
TWL_CLKS_LOCK_UPGRADE(sc);
/* Check the clock is in the application group */
if (twl_is_6030(sc->sc_pdev)) {
err = twl_clks_read_1(sc, clk, TWL_CLKS_GRP, &grp);
if (err) {
TWL_CLKS_LOCK_DOWNGRADE(sc);
goto done;
}
if (!(grp & TWL6030_P1_GRP)) {
TWL_CLKS_LOCK_DOWNGRADE(sc);
*enabled = 0; /* disabled */
goto done;
}
}
/* Read the application mode state and verify it's ON */
err = twl_clks_read_1(sc, clk, TWL_CLKS_STATE, &state);
if (!err)
*enabled = ((state & 0x0C) == 0x04);
TWL_CLKS_LOCK_DOWNGRADE(sc);
} else {
err = EINVAL;
}
done:
TWL_CLKS_SUNLOCK(sc);
return (err);
}
/**
* twl_clks_set_state - enables/disables a clock output
* @sc: device context
* @clk: the clock entry to enable/disable
* @enable: non-zero the clock is enabled, zero the clock is disabled
*
* LOCKING:
* The TWL CLK lock must be held before this function is called.
*
* RETURNS:
* Zero on success or an error code on failure.
*/
static int
twl_clks_set_state(struct twl_clks_softc *sc, struct twl_clk_entry *clk,
int enable)
{
int xlocked;
int err;
uint8_t grp;
TWL_CLKS_ASSERT_LOCKED(sc);
/* Upgrade the lock to exclusive because about to perform read-mod-write */
xlocked = sx_xlocked(&sc->sc_sx);
if (!xlocked)
TWL_CLKS_LOCK_UPGRADE(sc);
err = twl_clks_read_1(sc, clk, TWL_CLKS_GRP, &grp);
if (err)
goto done;
if (twl_is_4030(sc->sc_pdev)) {
/* On the TWL4030 we just need to ensure the clock is in the right
* power domain, don't need to turn on explicitly like TWL6030.
*/
if (enable)
grp |= TWL4030_P1_GRP;
else
grp &= ~(TWL4030_P1_GRP | TWL4030_P2_GRP | TWL4030_P3_GRP);
err = twl_clks_write_1(sc, clk, TWL_CLKS_GRP, grp);
} else if (twl_is_6030(sc->sc_pdev) || twl_is_6025(sc->sc_pdev)) {
/* Make sure the clock belongs to at least the APP power group */
if (twl_is_6030(sc->sc_pdev) && !(grp & TWL6030_P1_GRP)) {
grp |= TWL6030_P1_GRP;
err = twl_clks_write_1(sc, clk, TWL_CLKS_GRP, grp);
if (err)
goto done;
}
/* On TWL6030 we need to make sure we disable power for all groups */
if (twl_is_6030(sc->sc_pdev))
grp = TWL6030_P1_GRP | TWL6030_P2_GRP | TWL6030_P3_GRP;
else
grp = 0x00;
/* Set the state of the clock */
if (enable)
err = twl_clks_write_1(sc, clk, TWL_CLKS_STATE, (grp << 5) | 0x01);
else
err = twl_clks_write_1(sc, clk, TWL_CLKS_STATE, (grp << 5));
} else {
err = EINVAL;
}
done:
if (!xlocked)
TWL_CLKS_LOCK_DOWNGRADE(sc);
if ((twl_clks_debug > 1) && !err)
device_printf(sc->sc_dev, "%s : %sabled\n", clk->name,
enable ? "en" : "dis");
return (err);
}
/**
* twl_clks_disable - disables a clock output
* @dev: TWL clk device
* @name: the name of the clock
*
* LOCKING:
* Internally the function takes and releases the TWL lock.
*
* RETURNS:
* Zero on success or an error code on failure.
*/
int
twl_clks_disable(device_t dev, const char *name)
{
struct twl_clks_softc *sc = device_get_softc(dev);
struct twl_clk_entry *clk;
int err = EINVAL;
TWL_CLKS_SLOCK(sc);
LIST_FOREACH(clk, &sc->sc_clks_list, link) {
if (strcmp(clk->name, name) == 0) {
err = twl_clks_set_state(sc, clk, 0);
break;
}
}
TWL_CLKS_SUNLOCK(sc);
return (err);
}
/**
* twl_clks_enable - enables a clock output
* @dev: TWL clk device
* @name: the name of the clock
*
* LOCKING:
* Internally the function takes and releases the TWL CLKS lock.
*
* RETURNS:
* Zero on success or an error code on failure.
*/
int
twl_clks_enable(device_t dev, const char *name)
{
struct twl_clks_softc *sc = device_get_softc(dev);
struct twl_clk_entry *clk;
int err = EINVAL;
TWL_CLKS_SLOCK(sc);
LIST_FOREACH(clk, &sc->sc_clks_list, link) {
if (strcmp(clk->name, name) == 0) {
err = twl_clks_set_state(sc, clk, 1);
break;
}
}
TWL_CLKS_SUNLOCK(sc);
return (err);
}
/**
* twl_clks_sysctl_clock - reads the state of the clock
* @SYSCTL_HANDLER_ARGS: arguments for the callback
*
* Returns the clock status; disabled is zero and enabled is non-zero.
*
* LOCKING:
* It's expected the TWL lock is held while this function is called.
*
* RETURNS:
* EIO if device is not present, otherwise 0 is returned.
*/
static int
twl_clks_sysctl_clock(SYSCTL_HANDLER_ARGS)
{
struct twl_clks_softc *sc = (struct twl_clks_softc*)arg1;
int err;
int enabled = 0;
if ((err = twl_clks_is_enabled(sc->sc_dev, oidp->oid_name, &enabled)) != 0)
return err;
return sysctl_handle_int(oidp, &enabled, 0, req);
}
/**
* twl_clks_add_clock - adds single clock sysctls for the device
* @sc: device soft context
* @name: the name of the regulator
* @nsub: the number of the subdevice
* @regbase: the base address of the clocks registers
*
* Adds a single clock to the device and also a sysctl interface for
* querying it's status.
*
* LOCKING:
* It's expected the exclusive lock is held while this function is called.
*
* RETURNS:
* Pointer to the new clock entry on success, otherwise NULL on failure.
*/
static struct twl_clk_entry*
twl_clks_add_clock(struct twl_clks_softc *sc, const char *name,
uint8_t nsub, uint8_t regbase)
{
struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
struct twl_clk_entry *new;
TWL_CLKS_ASSERT_LOCKED(sc);
new = malloc(sizeof(struct twl_clk_entry), M_DEVBUF, M_NOWAIT | M_ZERO);
if (new == NULL)
return (NULL);
strncpy(new->name, name, TWL_CLKS_MAX_NAMELEN);
new->name[TWL_CLKS_MAX_NAMELEN - 1] = '\0';
new->sub_dev = nsub;
new->reg_off = regbase;
/* Add a sysctl entry for the clock */
new->oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, name,
CTLTYPE_INT | CTLFLAG_RD, sc, 0,
twl_clks_sysctl_clock, "I", "external clock");
/* Finally add the regulator to list of supported regulators */
LIST_INSERT_HEAD(&sc->sc_clks_list, new, link);
return (new);
}
/**
* twl_clks_add_clocks - populates the internal list of clocks
* @sc: device soft context
* @chip: the name of the chip used in the hints
* @clks the list of clocks supported by the device
*
* Loops over the list of clocks and adds them to the device context. Also
* scans the FDT to determine if there are any clocks that should be
* enabled/disabled automatically.
*
* LOCKING:
* Internally takes the exclusive lock while adding the clocks to the
* device context.
*
* RETURNS:
* Always returns 0.
*/
static int
twl_clks_add_clocks(struct twl_clks_softc *sc, const struct twl_clock *clks)
{
int err;
const struct twl_clock *walker;
struct twl_clk_entry *entry;
phandle_t child;
char rnames[256];
char *name, *state;
int len = 0, prop_len;
int enable;
TWL_CLKS_XLOCK(sc);
/* Add the regulators from the list */
walker = &clks[0];
while (walker->name != NULL) {
/* Add the regulator to the list */
entry = twl_clks_add_clock(sc, walker->name, walker->subdev,
walker->regbase);
if (entry == NULL)
continue;
walker++;
}
/* Check for any FDT settings that need to be applied */
child = ofw_bus_get_node(sc->sc_pdev);
if (child) {
prop_len = OF_getprop(child, "external-clocks", rnames, sizeof(rnames));
while (len < prop_len) {
name = rnames + len;
len += strlen(name) + 1;
if ((len >= prop_len) || (name[0] == '\0'))
break;
state = rnames + len;
len += strlen(state) + 1;
if (state[0] == '\0')
break;
enable = !strncmp(state, "on", 2);
LIST_FOREACH(entry, &sc->sc_clks_list, link) {
if (strcmp(entry->name, name) == 0) {
twl_clks_set_state(sc, entry, enable);
break;
}
}
}
}
TWL_CLKS_XUNLOCK(sc);
if (twl_clks_debug) {
LIST_FOREACH(entry, &sc->sc_clks_list, link) {
err = twl_clks_is_enabled(sc->sc_dev, entry->name, &enable);
if (!err)
device_printf(sc->sc_dev, "%s : %s\n", entry->name,
enable ? "on" : "off");
}
}
return (0);
}
/**
* twl_clks_init - initialises the list of clocks
* @dev: the twl_clks device
*
* This function is called as an intrhook once interrupts have been enabled,
* this is done so that the driver has the option to enable/disable a clock
* based on settings providied in the FDT.
*
* LOCKING:
* May takes the exclusive lock in the function.
*/
static void
twl_clks_init(void *dev)
{
struct twl_clks_softc *sc;
sc = device_get_softc((device_t)dev);
if (twl_is_4030(sc->sc_pdev))
twl_clks_add_clocks(sc, twl4030_clocks);
else if (twl_is_6030(sc->sc_pdev) || twl_is_6025(sc->sc_pdev))
twl_clks_add_clocks(sc, twl6030_clocks);
config_intrhook_disestablish(&sc->sc_init_hook);
}
static int
twl_clks_probe(device_t dev)
{
if (twl_is_4030(device_get_parent(dev)))
device_set_desc(dev, "TI TWL4030 PMIC External Clocks");
else if (twl_is_6025(device_get_parent(dev)) ||
twl_is_6030(device_get_parent(dev)))
device_set_desc(dev, "TI TWL6025/TWL6030 PMIC External Clocks");
else
return (ENXIO);
return (0);
}
static int
twl_clks_attach(device_t dev)
{
struct twl_clks_softc *sc;
sc = device_get_softc(dev);
sc->sc_dev = dev;
sc->sc_pdev = device_get_parent(dev);
TWL_CLKS_LOCK_INIT(sc);
LIST_INIT(&sc->sc_clks_list);
sc->sc_init_hook.ich_func = twl_clks_init;
sc->sc_init_hook.ich_arg = dev;
if (config_intrhook_establish(&sc->sc_init_hook) != 0)
return (ENOMEM);
return (0);
}
static int
twl_clks_detach(device_t dev)
{
struct twl_clks_softc *sc;
struct twl_clk_entry *clk;
struct twl_clk_entry *tmp;
sc = device_get_softc(dev);
TWL_CLKS_XLOCK(sc);
LIST_FOREACH_SAFE(clk, &sc->sc_clks_list, link, tmp) {
LIST_REMOVE(clk, link);
sysctl_remove_oid(clk->oid, 1, 0);
free(clk, M_DEVBUF);
}
TWL_CLKS_XUNLOCK(sc);
TWL_CLKS_LOCK_DESTROY(sc);
return (0);
}
static device_method_t twl_clks_methods[] = {
DEVMETHOD(device_probe, twl_clks_probe),
DEVMETHOD(device_attach, twl_clks_attach),
DEVMETHOD(device_detach, twl_clks_detach),
{0, 0},
};
static driver_t twl_clks_driver = {
"twl_clks",
twl_clks_methods,
sizeof(struct twl_clks_softc),
};
static devclass_t twl_clks_devclass;
DRIVER_MODULE(twl_clks, twl, twl_clks_driver, twl_clks_devclass, 0, 0);
MODULE_VERSION(twl_clks, 1);

38
sys/arm/ti/twl/twl_clks.h Normal file
View File

@ -0,0 +1,38 @@
/*-
* Copyright (c) 2012
* Ben Gray <bgray@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 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 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 _TWL_CLKS_H_
#define _TWL_CLKS_H_
int twl_clks_enable(device_t dev, const char *name);
int twl_clks_disable(device_t dev, const char *name);
int twl_clks_is_enabled(device_t dev, const char *name, int *enabled);
#endif /* _TWL_CLKS_H_ */

1053
sys/arm/ti/twl/twl_vreg.c Normal file

File diff suppressed because it is too large Load Diff

36
sys/arm/ti/twl/twl_vreg.h Normal file
View File

@ -0,0 +1,36 @@
/*-
* Copyright (c) 2011
* Ben Gray <ben.r.gray@gmail.com>.
* 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 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 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 _TWL_VREG_H_
#define _TWL_VREG_H_
int twl_vreg_get_voltage(device_t dev, const char *name, int *millivolts);
int twl_vreg_set_voltage(device_t dev, const char *name, int millivolts);
#endif /* _TWL_VREG_H_ */

1024
sys/arm/ti/usb/omap_ehci.c Normal file

File diff suppressed because it is too large Load Diff

264
sys/arm/ti/usb/omap_usb.h Normal file
View File

@ -0,0 +1,264 @@
/*
* Copyright (c) 2010
* Ben Gray <ben.r.gray@gmail.com>.
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ben Gray.
* 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 BEN GRAY ``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 BEN GRAY 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 _OMAP_USB_H_
#define _OMAP_USB_H_
/*
* USB TTL Module
*/
#define OMAP_USBTLL_REVISION 0x0000
#define OMAP_USBTLL_SYSCONFIG 0x0010
#define OMAP_USBTLL_SYSSTATUS 0x0014
#define OMAP_USBTLL_IRQSTATUS 0x0018
#define OMAP_USBTLL_IRQENABLE 0x001C
#define OMAP_USBTLL_TLL_SHARED_CONF 0x0030
#define OMAP_USBTLL_TLL_CHANNEL_CONF(i) (0x0040 + (0x04 * (i)))
#define OMAP_USBTLL_SAR_CNTX(i) (0x0400 + (0x04 * (i)))
#define OMAP_USBTLL_ULPI_VENDOR_ID_LO(i) (0x0800 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_VENDOR_ID_HI(i) (0x0801 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_PRODUCT_ID_LO(i) (0x0802 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_PRODUCT_ID_HI(i) (0x0803 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_FUNCTION_CTRL(i) (0x0804 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_FUNCTION_CTRL_SET(i) (0x0805 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_FUNCTION_CTRL_CLR(i) (0x0806 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_INTERFACE_CTRL(i) (0x0807 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_INTERFACE_CTRL_SET(i) (0x0808 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_INTERFACE_CTRL_CLR(i) (0x0809 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_OTG_CTRL(i) (0x080A + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_OTG_CTRL_SET(i) (0x080B + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_OTG_CTRL_CLR(i) (0x080C + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_EN_RISE(i) (0x080D + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_EN_RISE_SET(i) (0x080E + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_EN_RISE_CLR(i) (0x080F + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_EN_FALL(i) (0x0810 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_EN_FALL_SET(i) (0x0811 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_EN_FALL_CLR(i) (0x0812 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_STATUS(i) (0x0813 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_LATCH(i) (0x0814 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_DEBUG(i) (0x0815 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_SCRATCH_REGISTER(i) (0x0816 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_SCRATCH_REGISTER_SET(i) (0x0817 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_SCRATCH_REGISTER_CLR(i) (0x0818 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_EXTENDED_SET_ACCESS(i) (0x082F + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VCONTROL_EN(i) (0x0830 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VCONTROL_EN_SET(i) (0x0831 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VCONTROL_EN_CLR(i) (0x0832 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VCONTROL_STATUS(i) (0x0833 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VCONTROL_LATCH(i) (0x0834 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VSTATUS(i) (0x0835 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VSTATUS_SET(i) (0x0836 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VSTATUS_CLR(i) (0x0837 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_LATCH_NOCLR(i) (0x0838 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_VENDOR_INT_EN(i) (0x083B + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_VENDOR_INT_EN_SET(i) (0x083C + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_VENDOR_INT_EN_CLR(i) (0x083D + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_VENDOR_INT_STATUS(i) (0x083E + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_VENDOR_INT_LATCH(i) (0x083F + (0x100 * (i)))
/*
* USB Host Module
*/
/* UHH */
#define OMAP_USBHOST_UHH_REVISION 0x0000
#define OMAP_USBHOST_UHH_SYSCONFIG 0x0010
#define OMAP_USBHOST_UHH_SYSSTATUS 0x0014
#define OMAP_USBHOST_UHH_HOSTCONFIG 0x0040
#define OMAP_USBHOST_UHH_DEBUG_CSR 0x0044
/* EHCI */
#define OMAP_USBHOST_HCCAPBASE 0x0000
#define OMAP_USBHOST_HCSPARAMS 0x0004
#define OMAP_USBHOST_HCCPARAMS 0x0008
#define OMAP_USBHOST_USBCMD 0x0010
#define OMAP_USBHOST_USBSTS 0x0014
#define OMAP_USBHOST_USBINTR 0x0018
#define OMAP_USBHOST_FRINDEX 0x001C
#define OMAP_USBHOST_CTRLDSSEGMENT 0x0020
#define OMAP_USBHOST_PERIODICLISTBASE 0x0024
#define OMAP_USBHOST_ASYNCLISTADDR 0x0028
#define OMAP_USBHOST_CONFIGFLAG 0x0050
#define OMAP_USBHOST_PORTSC(i) (0x0054 + (0x04 * (i)))
#define OMAP_USBHOST_INSNREG00 0x0090
#define OMAP_USBHOST_INSNREG01 0x0094
#define OMAP_USBHOST_INSNREG02 0x0098
#define OMAP_USBHOST_INSNREG03 0x009C
#define OMAP_USBHOST_INSNREG04 0x00A0
#define OMAP_USBHOST_INSNREG05_UTMI 0x00A4
#define OMAP_USBHOST_INSNREG05_ULPI 0x00A4
#define OMAP_USBHOST_INSNREG06 0x00A8
#define OMAP_USBHOST_INSNREG07 0x00AC
#define OMAP_USBHOST_INSNREG08 0x00B0
#define OMAP_USBHOST_INSNREG04_DISABLE_UNSUSPEND (1 << 5)
#define OMAP_USBHOST_INSNREG05_ULPI_CONTROL_SHIFT 31
#define OMAP_USBHOST_INSNREG05_ULPI_PORTSEL_SHIFT 24
#define OMAP_USBHOST_INSNREG05_ULPI_OPSEL_SHIFT 22
#define OMAP_USBHOST_INSNREG05_ULPI_REGADD_SHIFT 16
#define OMAP_USBHOST_INSNREG05_ULPI_EXTREGADD_SHIFT 8
#define OMAP_USBHOST_INSNREG05_ULPI_WRDATA_SHIFT 0
/* TLL Register Set */
#define TLL_SYSCONFIG_CACTIVITY (1UL << 8)
#define TLL_SYSCONFIG_SIDLE_SMART_IDLE (2UL << 3)
#define TLL_SYSCONFIG_SIDLE_NO_IDLE (1UL << 3)
#define TLL_SYSCONFIG_SIDLE_FORCED_IDLE (0UL << 3)
#define TLL_SYSCONFIG_ENAWAKEUP (1UL << 2)
#define TLL_SYSCONFIG_SOFTRESET (1UL << 1)
#define TLL_SYSCONFIG_AUTOIDLE (1UL << 0)
#define TLL_SYSSTATUS_RESETDONE (1UL << 0)
#define TLL_SHARED_CONF_USB_90D_DDR_EN (1UL << 6)
#define TLL_SHARED_CONF_USB_180D_SDR_EN (1UL << 5)
#define TLL_SHARED_CONF_USB_DIVRATIO_MASK (7UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_128 (7UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_64 (6UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_32 (5UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_16 (4UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_8 (3UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_4 (2UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_2 (1UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_1 (0UL << 2)
#define TLL_SHARED_CONF_FCLK_REQ (1UL << 1)
#define TLL_SHARED_CONF_FCLK_IS_ON (1UL << 0)
#define TLL_CHANNEL_CONF_DRVVBUS (1UL << 16)
#define TLL_CHANNEL_CONF_CHRGVBUS (1UL << 15)
#define TLL_CHANNEL_CONF_ULPINOBITSTUFF (1UL << 11)
#define TLL_CHANNEL_CONF_ULPIAUTOIDLE (1UL << 10)
#define TLL_CHANNEL_CONF_UTMIAUTOIDLE (1UL << 9)
#define TLL_CHANNEL_CONF_ULPIDDRMODE (1UL << 8)
#define TLL_CHANNEL_CONF_ULPIOUTCLKMODE (1UL << 7)
#define TLL_CHANNEL_CONF_TLLFULLSPEED (1UL << 6)
#define TLL_CHANNEL_CONF_TLLCONNECT (1UL << 5)
#define TLL_CHANNEL_CONF_TLLATTACH (1UL << 4)
#define TLL_CHANNEL_CONF_UTMIISADEV (1UL << 3)
#define TLL_CHANNEL_CONF_CHANEN (1UL << 0)
/* UHH Register Set */
#define UHH_SYSCONFIG_MIDLEMODE_MASK (3UL << 12)
#define UHH_SYSCONFIG_MIDLEMODE_SMARTSTANDBY (2UL << 12)
#define UHH_SYSCONFIG_MIDLEMODE_NOSTANDBY (1UL << 12)
#define UHH_SYSCONFIG_MIDLEMODE_FORCESTANDBY (0UL << 12)
#define UHH_SYSCONFIG_CLOCKACTIVITY (1UL << 8)
#define UHH_SYSCONFIG_SIDLEMODE_MASK (3UL << 3)
#define UHH_SYSCONFIG_SIDLEMODE_SMARTIDLE (2UL << 3)
#define UHH_SYSCONFIG_SIDLEMODE_NOIDLE (1UL << 3)
#define UHH_SYSCONFIG_SIDLEMODE_FORCEIDLE (0UL << 3)
#define UHH_SYSCONFIG_ENAWAKEUP (1UL << 2)
#define UHH_SYSCONFIG_SOFTRESET (1UL << 1)
#define UHH_SYSCONFIG_AUTOIDLE (1UL << 0)
#define UHH_HOSTCONFIG_APP_START_CLK (1UL << 31)
#define UHH_HOSTCONFIG_P3_CONNECT_STATUS (1UL << 10)
#define UHH_HOSTCONFIG_P2_CONNECT_STATUS (1UL << 9)
#define UHH_HOSTCONFIG_P1_CONNECT_STATUS (1UL << 8)
#define UHH_HOSTCONFIG_ENA_INCR_ALIGN (1UL << 5)
#define UHH_HOSTCONFIG_ENA_INCR16 (1UL << 4)
#define UHH_HOSTCONFIG_ENA_INCR8 (1UL << 3)
#define UHH_HOSTCONFIG_ENA_INCR4 (1UL << 2)
#define UHH_HOSTCONFIG_AUTOPPD_ON_OVERCUR_EN (1UL << 1)
#define UHH_HOSTCONFIG_P1_ULPI_BYPASS (1UL << 0)
/* The following are on rev2 (OMAP44xx) of the EHCI only */
#define UHH_SYSCONFIG_IDLEMODE_MASK (3UL << 2)
#define UHH_SYSCONFIG_IDLEMODE_NOIDLE (1UL << 2)
#define UHH_SYSCONFIG_STANDBYMODE_MASK (3UL << 4)
#define UHH_SYSCONFIG_STANDBYMODE_NOSTDBY (1UL << 4)
#define UHH_HOSTCONFIG_P1_MODE_MASK (3UL << 16)
#define UHH_HOSTCONFIG_P1_MODE_ULPI_PHY (0UL << 16)
#define UHH_HOSTCONFIG_P1_MODE_UTMI_PHY (1UL << 16)
#define UHH_HOSTCONFIG_P1_MODE_HSIC (3UL << 16)
#define UHH_HOSTCONFIG_P2_MODE_MASK (3UL << 18)
#define UHH_HOSTCONFIG_P2_MODE_ULPI_PHY (0UL << 18)
#define UHH_HOSTCONFIG_P2_MODE_UTMI_PHY (1UL << 18)
#define UHH_HOSTCONFIG_P2_MODE_HSIC (3UL << 18)
#define ULPI_FUNC_CTRL_RESET (1 << 5)
/*-------------------------------------------------------------------------*/
/*
* Macros for Set and Clear
* See ULPI 1.1 specification to find the registers with Set and Clear offsets
*/
#define ULPI_SET(a) (a + 1)
#define ULPI_CLR(a) (a + 2)
/*-------------------------------------------------------------------------*/
/*
* Register Map
*/
#define ULPI_VENDOR_ID_LOW 0x00
#define ULPI_VENDOR_ID_HIGH 0x01
#define ULPI_PRODUCT_ID_LOW 0x02
#define ULPI_PRODUCT_ID_HIGH 0x03
#define ULPI_FUNC_CTRL 0x04
#define ULPI_IFC_CTRL 0x07
#define ULPI_OTG_CTRL 0x0a
#define ULPI_USB_INT_EN_RISE 0x0d
#define ULPI_USB_INT_EN_FALL 0x10
#define ULPI_USB_INT_STS 0x13
#define ULPI_USB_INT_LATCH 0x14
#define ULPI_DEBUG 0x15
#define ULPI_SCRATCH 0x16
/*
* Values of UHH_REVISION - Note: these are not given in the TRM but taken
* from the linux OMAP EHCI driver (thanks guys). It has been verified on
* a Panda and Beagle board.
*/
#define OMAP_EHCI_REV1 0x00000010 /* OMAP3 */
#define OMAP_EHCI_REV2 0x50700100 /* OMAP4 */
#define EHCI_VENDORID_OMAP3 0x42fa05
#define OMAP_EHCI_HC_DEVSTR "TI OMAP USB 2.0 controller"
#define EHCI_HCD_OMAP_MODE_UNKNOWN 0
#define EHCI_HCD_OMAP_MODE_PHY 1
#define EHCI_HCD_OMAP_MODE_TLL 2
#define EHCI_HCD_OMAP_MODE_HSIC 3
#endif /* _OMAP_USB_H_ */

View File

@ -0,0 +1,197 @@
/*-
* Copyright (c) 2012 Damjan Marion <dmarion@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$
*/
/dts-v1/;
/ {
model = "beaglebone";
compatible = "beaglebone", "ti,am335x";
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&AINTC>;
aliases {
soc = &SOC;
uart0 = &uart0;
};
memory {
device_type = "memory";
reg = < 0x80000000 0x10000000 >; /* 256MB RAM */
};
SOC: am335x {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
ranges;
bus-frequency = <0>;
AINTC: interrupt-controller@48200000 {
compatible = "ti,aintc";
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <1>;
reg = < 0x48200000 0x1000 >;
};
scm@44e10000 {
compatible = "ti,scm";
reg = < 0x44e10000 0x2000 >;
/* Set of triplets < padname, muxname, padstate> */
scm-pad-config =
/* I2C0 */
"I2C0_SDA", "I2C0_SDA","i2c",
"I2C0_SCL", "I2C0_SCL","i2c",
/* Ethernet */
"MII1_RX_ER", "gmii1_rxerr", "input_pulldown",
"MII1_TX_EN", "gmii1_txen", "output",
"MII1_RX_DV", "gmii1_rxdv", "input_pulldown",
"MII1_TXD3", "gmii1_txd3", "output",
"MII1_TXD2", "gmii1_txd2", "output",
"MII1_TXD1", "gmii1_txd1", "output",
"MII1_TXD0", "gmii1_txd0", "output",
"MII1_TX_CLK", "gmii1_txclk", "input_pulldown",
"MII1_RX_CLK", "gmii1_rxclk", "input_pulldown",
"MII1_RXD3", "gmii1_rxd3", "input_pulldown",
"MII1_RXD2", "gmii1_rxd2", "input_pulldown",
"MII1_RXD1", "gmii1_rxd1", "input_pulldown",
"MII1_RXD0", "gmii1_rxd0", "input_pulldown",
"MDIO", "mdio_data", "input_pullup",
"MDC", "mdio_clk", "output_pullup",
/* MMCSD0 */
"MMC0_CMD", "mmc0_cmd", "input_pullup",
"MMC0_CLK", "mmc0_clk", "input_pullup",
"MMC0_DAT0", "mmc0_dat0", "input_pullup",
"MMC0_DAT1", "mmc0_dat1", "input_pullup",
"MMC0_DAT2", "mmc0_dat2", "input_pullup",
"MMC0_DAT3", "mmc0_dat3", "input_pullup";
};
prcm@44E00000 {
compatible = "am335x,prcm";
#address-cells = <1>;
#size-cells = <1>;
reg = < 0x44E00000 0x1300 >;
};
dmtimers@44E05000 {
compatible = "ti,am335x-dmtimer";
#address-cells = <1>;
#size-cells = <1>;
reg = < 0x44E05000 0x1000
0x44E31000 0x1000
0x48040000 0x1000
0x48042000 0x1000
0x48044000 0x1000
0x48046000 0x1000
0x48048000 0x1000
0x4804A000 0x1000 >;
interrupts = < 66 67 68 69 92 93 94 95 >;
interrupt-parent = <&AINTC>;
};
GPIO: gpio {
#gpio-cells = <3>;
compatible = "ti,gpio";
gpio-controller;
reg =< 0x44E07000 0x1000
0x4804C000 0x1000
0x481AC000 0x1000
0x481AE000 0x1000 >;
interrupts = < 17 19 21 23 >;
interrupt-parent = <&AINTC>;
};
uart0: serial@44E09000 {
compatible = "ns16550";
reg = <0x44E09000 0x1000>;
reg-shift = <2>;
interrupts = < 72 >;
interrupt-parent = <&AINTC>;
clock-frequency = < 48000000 >; /* FIXME */
};
edma3@49000000 {
compatible = "ti,edma3";
reg =< 0x49000000 0x100000 /* Channel Controller Regs */
0x49800000 0x100000 /* Transfer Controller 0 Regs */
0x49900000 0x100000 /* Transfer Controller 1 Regs */
0x49a00000 0x100000 >; /* Transfer Controller 2 Regs */
interrupts = <12 13 14>;
interrupt-parent = <&AINTC>;
};
mmchs0@4809C000 {
compatible = "ti,mmchs";
reg =<0x48060000 0x1000 >;
interrupts = <64>;
interrupt-parent = <&AINTC>;
mmchs-device-id = <0>;
};
enet0: ethernet@4A100000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "ti,cpsw";
reg = <0x4A100000 0x3000>;
interrupts = <40 41 42 43>;
interrupt-parent = <&AINTC>;
phy-handle = <&phy0>;
mdio@0 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "ti,cpsw-mdio";
phy0: ethernet-phy@0 {
reg = <0x0>;
};
};
};
i2c0: i2c@44e0b000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "ti,i2c";
reg =< 0x44e0b000 0x1000 >;
interrupts = <70>;
interrupt-parent = <&AINTC>;
i2c-device-id = <0>;
pmic@24 {
compatible = "ti,am335x-pmic";
reg = <0x24>;
};
};
};
chosen {
stdin = "uart0";
stdout = "uart0";
};
};

View File

@ -0,0 +1,184 @@
/*-
* Copyright (c) 2011 The FreeBSD Foundation
* All rights reserved.
*
* Developed by Damjan Marion <damjan.marion@gmail.com>
*
* 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$
*/
/dts-v1/;
/ {
model = "pandaboard";
compatible = "pandaboard", "ti,omap4430";
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&GIC>;
aliases {
soc = &SOC;
uart3 = &uart3;
};
memory {
device_type = "memory";
reg = < 0x80000000 0x40000000 >; /* 1GB RAM at 0x0 */
};
SOC: omap4430 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
ranges;
bus-frequency = <0>;
GIC: interrupt-controller@48241000 {
compatible = "arm,gic";
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <1>;
reg = < 0x48241000 0x1000 >, /* Distributor Registers */
< 0x48240100 0x0100 >; /* CPU Interface Registers */
};
pl310@48242000 {
compatible = "arm,pl310";
reg = < 0x48242000 0x1000 >;
};
mp_tmr@48240200 {
compatible = "arm,mpcore-timers";
clock-frequency = < 504000000 >;
#address-cells = <1>;
#size-cells = <0>;
reg = < 0x48240200 0x100 >, /* Global Timer Registers */
< 0x48240600 0x100 >; /* Private Timer Registers */
interrupts = < 27 29 >;
interrupt-parent = < &GIC >;
};
uart3: serial@48020000 {
compatible = "ns16550";
reg = <0x48020000 0x1000>;
reg-shift = <2>;
interrupts = < 106 >;
interrupt-parent = <&GIC>;
clock-frequency = < 48000000 >; /* 48Mhz clock for all uarts */
/* (techref 17.3.1.1) */
};
scm@4a100000 {
compatible = "ti,scm";
reg = < 0x4a100000 0x1000 >;
/* Set of triplets < padname, muxname, padstate> */
scm-pad-config =
"ag19", "usbb1_ulpiphy_stp", "output",
"ae18", "usbb1_ulpiphy_clk", "input_pulldown",
"af19", "usbb1_ulpiphy_dir", "input_pulldown",
"ae19", "usbb1_ulpiphy_nxt", "input_pulldown",
"af18", "usbb1_ulpiphy_dat0", "input_pulldown",
"ag18", "usbb1_ulpiphy_dat1", "input_pulldown",
"ae17", "usbb1_ulpiphy_dat2", "input_pulldown",
"af17", "usbb1_ulpiphy_dat3", "input_pulldown",
"ah17", "usbb1_ulpiphy_dat4", "input_pulldown",
"ae16", "usbb1_ulpiphy_dat5", "input_pulldown",
"af16", "usbb1_ulpiphy_dat6", "input_pulldown",
"ag16", "usbb1_ulpiphy_dat7", "input_pulldown";
};
omap4_prcm@4a306000 {
compatible = "ti,omap4_prcm";
reg =< 0x4a306000 0x2000
0x4a004000 0x1000
0x4a008000 0x8000>;
};
GPIO: gpio {
#gpio-cells = <3>;
compatible = "ti,gpio";
gpio-controller;
reg =< 0x4a310000 0x1000
0x48055000 0x1000
0x48057000 0x1000
0x48059000 0x1000
0x4805b000 0x1000
0x4805d000 0x1000>;
interrupts = <61 62 63 64 65 66>;
interrupt-parent = <&GIC>;
};
ehci {
compatible = "ti,usb-ehci", "usb-ehci";
/*
* USB port PHY configuration is a tuple: <mode, reset, gpio_pin>
* mode is one of the following values:
* 0 - unknown
* 1 - PHY
* 2 - TLL
* 3 - HSIC
*
* reset indicates (if non-zero) if port reset is required
* gpio_pin - GPIO pin that is used to perform reset
*/
phy-config = < 1 0 0
0 0 0
0 0 0>;
reg = < 0x4a064c00 0x100 /* EHCI regs */
0x4a064000 0x700 /* UHH regs */
0x4a062000 0x1000>; /* TLL regs */
interrupts = <109>;
interrupt-parent = <&GIC>;
};
I2C1: i2c@x48070000 {
compatible = "ti,i2c";
reg =< 0x48070000 0x100 >;
interrupts = <88>;
interrupt-parent = <&GIC>;
i2c-device-id = <1>;
};
sdma@x48070000 {
compatible = "ti,sdma";
reg =< 0x4A056000 0x1000 >;
interrupts = <44 45 46 47>;
interrupt-parent = <&GIC>;
};
mmc@x4809C000 {
compatible = "ti,mmchs";
reg =<0x4809C000 0x1000 >;
interrupts = <115>;
interrupt-parent = <&GIC>;
mmchs-device-id = <1>;
};
};
chosen {
stdin = "uart3";
stdout = "uart3";
};
};

View File

@ -1730,5 +1730,6 @@ static driver_t mmc_driver = {
};
static devclass_t mmc_devclass;
DRIVER_MODULE(mmc, ti_mmchs, mmc_driver, mmc_devclass, NULL, NULL);
DRIVER_MODULE(mmc, at91_mci, mmc_driver, mmc_devclass, NULL, NULL);
DRIVER_MODULE(mmc, sdhci, mmc_driver, mmc_devclass, NULL, NULL);

View File

@ -72,6 +72,7 @@ SUBDIR= \
${_coff} \
${_coretemp} \
${_cp} \
${_cpsw} \
${_cpuctl} \
${_cpufreq} \
${_crypto} \
@ -735,6 +736,7 @@ _zfs= zfs
.if ${MACHINE_CPUARCH} == "arm"
_cfi= cfi
_cpsw= cpsw
.endif
.if ${MACHINE_CPUARCH} == "ia64"

View File

@ -0,0 +1,8 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../arm/ti/cpsw
KMOD= if_cpsw
SRCS= if_cpsw.c device_if.h bus_if.h ofw_bus_if.h miibus_if.h
.include <bsd.kmod.mk>