Add support for OMAP1-183 base hawkboard (HAWK) from Sughosh Ganu.

Minor cleanup (adding $NetBSD to headers, __KERNEL_RCSID to C files, etc).
This commit is contained in:
matt 2013-10-02 16:48:26 +00:00
parent 50c2794d8e
commit 386d762476
20 changed files with 4307 additions and 3 deletions

View File

@ -0,0 +1,57 @@
# $NetBSD: files.omapl1x,v 1.1 2013/10/02 16:48:26 matt Exp $
#
# Configuration info for Texas Instruments OMAP-L1x CPU support
# Based on files.omap2 and files.omap
#
include "arch/arm/pic/files.pic"
file arch/arm/arm32/irq_dispatch.S
# Memory size in megabytes
defparam opt_omapl1x.h MEMSIZE
device tipb { [addr=-1], [size=0], [intr=-1], [mult=1] } : bus_space_generic
attach tipb at mainbus
file arch/arm/omap/omapl1x_tipb.c tipb
# TIPB common files
file arch/arm/omap/omap_space.c tipb
file arch/arm/omap/omap_a2x_space.c tipb
file arch/arm/arm/bus_space_a2x.S tipb
file arch/arm/omap/omap_a4x_space.c tipb
file arch/arm/arm/bus_space_a4x.S tipb
file arch/arm/omap/omapl1x_bus_dma.c
#OMAPL1x Interrupt Controller
device omapl1xaintc: pic, pic_splfuncs #ARM Interrupt Controller
attach omapl1xaintc at tipb
file arch/arm/omap/omapl1x_aintc.c omapl1xaintc
# NS16550 compatible serial ports
attach com at tipb with omapl1xcom
file arch/arm/omap/omapl1x_com.c omapl1xcom
defparam opt_com.h OMAPL1X_COM_FREQ
defparam opt_com.h CONSADDR CONSPEED CONMODE
#OMAPL1x Timer
device omapl1xtimer
attach omapl1xtimer at tipb
defparam opt_timer.h OMAPL1X_TIMER0_FREQ
defparam opt_timer.h OMAPL1X_TIMER1_FREQ
defparam opt_timer.h OMAPL1X_TIMER2_FREQ
defparam opt_timer.h OMAPL1X_TIMER3_FREQ
file arch/arm/omap/omapl1x_timer.c
#PSC controller
device omapl1xpsc
attach omapl1xpsc at tipb
file arch/arm/omap/omapl1x_psc.c
# OHCI USB controller
attach ohci at tipb with omapl1xohci
file arch/arm/omap/omapl1x_ohci.c omapl1xohci
device emac: ether, ifnet, arp, mii, mii_phy
attach emac at tipb
file arch/arm/omap/omapl1x_emac.c emac

View File

@ -1,4 +1,4 @@
/* $NetBSD: omap_tipb.c,v 1.5 2011/07/01 20:30:21 dyoung Exp $ */
/* $NetBSD: omap_tipb.c,v 1.6 2013/10/02 16:48:26 matt Exp $ */
/*
* Autoconfiguration support for the Texas Instruments OMAP TIPB.
@ -97,7 +97,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: omap_tipb.c,v 1.5 2011/07/01 20:30:21 dyoung Exp $");
__KERNEL_RCSID(0, "$NetBSD: omap_tipb.c,v 1.6 2013/10/02 16:48:26 matt Exp $");
#include "locators.h"
@ -112,7 +112,10 @@ __KERNEL_RCSID(0, "$NetBSD: omap_tipb.c,v 1.5 2011/07/01 20:30:21 dyoung Exp $")
#include <arm/cpufunc.h>
#include <arm/mainbus/mainbus.h>
#include <arm/omap/omap_reg.h>
/*
* XXX. Do we really need this ? #include <arm/omap/omap_reg.h>
* Atleast commenting this makes it more generic.
*/
#include <arm/omap/omap_tipb.h>
struct tipb_softc {

View File

@ -0,0 +1,223 @@
/*
* Copyright (c) 2013 Linu Cherian
*
* 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 this list of conditions
* and the following disclaimer.
* 2. Redistributions in binary form must reproduce this list of conditions
* and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``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 ANY
* 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>
__KERNEL_RCSID(0, "$NetBSD: omapl1x_aintc.c,v 1.1 2013/10/02 16:48:26 matt Exp $");
#include "opt_omapl1x.h"
#define _INTR_PRIVATE
#include <sys/param.h>
#include <sys/evcnt.h>
#include <sys/device.h>
#include <sys/bus.h>
#include <uvm/uvm_extern.h>
#include <machine/intr.h>
#include <arm/cpu.h>
#include <arm/armreg.h>
#include <arm/cpufunc.h>
#include <arm/atomic.h>
#include <arm/omap/omapl1x_reg.h>
#include <arm/omap/omap_tipb.h>
static int omapl1xaintc_match(device_t, cfdata_t, void *);
static void omapl1xaintc_attach(device_t, device_t, void *);
static void omapl1xaintc_unblock_irqs(struct pic_softc *, size_t, uint32_t);
static void omapl1xaintc_block_irqs(struct pic_softc *, size_t, uint32_t);
static void omapl1xaintc_establish_irq(struct pic_softc *, struct intrsource *);
#define INTC_READ(sc, o) \
bus_space_read_4((sc)->sc_memt, (sc)->sc_memh, (o))
#define INTC_WRITE(sc, o, v) \
bus_space_write_4((sc)->sc_memt, (sc)->sc_memh, (o), v)
#define PICTOSOFTC(pic) \
((void *)((uintptr_t)(pic) - offsetof(struct omapl1xaintc_softc, sc_pic)))
static const struct pic_ops omapl1xaintc_picops = {
.pic_unblock_irqs = omapl1xaintc_unblock_irqs,
.pic_block_irqs = omapl1xaintc_block_irqs,
.pic_establish_irq = omapl1xaintc_establish_irq,
};
static struct omapl1xaintc_softc {
device_t sc_dev;
bus_space_tag_t sc_memt;
bus_space_handle_t sc_memh;
struct pic_softc sc_pic;
uint32_t sc_enabled_irqs[4];
} omapl1xaintc_softc = {
.sc_pic = {
.pic_ops = &omapl1xaintc_picops,
.pic_maxsources = 101,
.pic_name = "omapl1xaintc",
},
};
/* Host Side Interrupt Numbers */
#define HOST_IRQ 1
#define HOST_FIQ 0
CFATTACH_DECL_NEW(omapl1xaintc, 0, omapl1xaintc_match, omapl1xaintc_attach,
NULL, NULL);
static void
omapl1xaintc_unblock_irqs(struct pic_softc *pic, size_t irqbase, uint32_t irq_mask)
{
struct omapl1xaintc_softc * const sc = PICTOSOFTC(pic);
const size_t group = irqbase / 32;
KASSERT((irq_mask & sc->sc_enabled_irqs[group]) == 0);
sc->sc_enabled_irqs[group] |= irq_mask;
INTC_WRITE(sc, AINTC_ESR1 + group * 4, irq_mask);
}
static void
omapl1xaintc_block_irqs(struct pic_softc *pic, size_t irqbase, uint32_t irq_mask)
{
struct omapl1xaintc_softc * const sc = PICTOSOFTC(pic);
const size_t group = irqbase / 32;
INTC_WRITE(sc, AINTC_ECR1 + group * 4, irq_mask);
sc->sc_enabled_irqs[group] &= ~irq_mask;
}
/*
* Called with interrupts disabled
*/
static int
find_pending_irqs(struct omapl1xaintc_softc *sc, size_t group)
{
uint32_t pending = INTC_READ(sc, AINTC_SECR1 + group * 4);
KASSERT((sc->sc_enabled_irqs[group] & pending) == pending);
if (pending == 0)
return 0;
/* Clear what we have read */
INTC_WRITE(sc, AINTC_SECR1 + group * 4, pending);
return pic_mark_pending_sources(&sc->sc_pic, group * 32, pending);
}
void
omapl1xaintc_irq_handler(void *frame)
{
struct cpu_info * const ci = curcpu();
struct omapl1xaintc_softc * const sc = &omapl1xaintc_softc;
const int oldipl = ci->ci_cpl;
const uint32_t oldipl_mask = __BIT(oldipl);
int ipl_mask = 0;
ci->ci_data.cpu_nintr++;
if (sc->sc_enabled_irqs[0])
ipl_mask |= find_pending_irqs(sc, 0);
if (sc->sc_enabled_irqs[1])
ipl_mask |= find_pending_irqs(sc, 1);
if (sc->sc_enabled_irqs[2])
ipl_mask |= find_pending_irqs(sc, 2);
if (sc->sc_enabled_irqs[3])
ipl_mask |= find_pending_irqs(sc, 3);
/*
* Record the pending_ipls and deliver them if we can.
*/
if ((ipl_mask & ~oldipl_mask) > oldipl_mask)
pic_do_pending_ints(I32_bit, oldipl, frame);
}
void
omapl1xaintc_establish_irq(struct pic_softc *pic, struct intrsource *is)
{
KASSERT(is->is_irq < 101);
}
int
omapl1xaintc_match(device_t parent, cfdata_t cf, void *aux)
{
return 1;
}
void
omapl1xaintc_attach(device_t parent, device_t self, void *aux)
{
int i, error;
uint32_t group, num_irqs, num_regs;
struct tipb_attach_args * const ta = aux;
struct omapl1xaintc_softc * const sc = &omapl1xaintc_softc;
aprint_normal("\n");
num_irqs = PIC_MAXSOURCES;
sc->sc_memt = ta->tipb_iot;
error = bus_space_map(sc->sc_memt, ta->tipb_addr, ta->tipb_size, 0,
&sc->sc_memh);
if (error)
panic("failed to map interrupt registers: %d", error);
/* Clear global interrupt */
INTC_WRITE(sc, AINTC_GER, 0);
/* Clear all host interrupts */
INTC_WRITE(sc, AINTC_HIER, 0);
/* Disable all system interrupts */
for (i = 0, group = 0; i < num_irqs; i++, group = i/32)
INTC_WRITE(sc, AINTC_ECR1 + group * 4, ~0);
/* Clear all system interrupts status */
for (i = 0, group = 0; i < num_irqs; i++, group = i/32)
INTC_WRITE(sc, AINTC_SECR1 + group * 4, ~0);
/*
* Map all system interrupts to channel 7
* XXX Not sure about why channel 7. I'm just
* following what linux does here.
*/
num_regs = (num_irqs + 3) >> 2;
for (i = 0; i < num_regs; i++)
INTC_WRITE(sc, AINTC_CMR0 + i * 4, 0x07070707);
/* Enable Host side IRQ line */
INTC_WRITE(sc, AINTC_HIEISR, (unsigned long)HOST_IRQ);
/* Enable Global interrupt */
INTC_WRITE(sc, AINTC_GER, 0x1);
pic_add(&sc->sc_pic, 0);
enable_interrupts(I32_bit);
}

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2013 Linu Cherian
*
* 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 this list of conditions
* and the following disclaimer.
* 2. Redistributions in binary form must reproduce this list of conditions
* and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``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 ANY
* 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.
*/
/*
* Copyright (c) 2004 Jesse Off
* 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 The Fujitsu Component Limited nor the name of
* Genetec corporation may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY FUJITSU COMPONENT LIMITED AND GENETEC
* CORPORATION ``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 FUJITSU COMPONENT LIMITED OR GENETEC
* CORPORATION 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.
*/
/*
* bus_dma tag for omapl1x SOC's
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: omapl1x_bus_dma.c,v 1.1 2013/10/02 16:48:26 matt Exp $");
#include <sys/param.h>
#include <sys/types.h>
#include <sys/device.h>
#include <sys/systm.h>
#include <sys/extent.h>
#define _ARM32_BUS_DMA_PRIVATE
#include <sys/bus.h>
struct arm32_bus_dma_tag omapl1x_bus_dma_tag = {
_BUS_DMAMAP_FUNCS,
_BUS_DMAMEM_FUNCS,
_BUS_DMATAG_FUNCS,
};
struct arm32_dma_range omapl1x_dma_ranges[] = {
[0] = {
.dr_sysbase = 0x01E20000,
.dr_busbase = 0x01E20000,
.dr_len = 0x2000,
},
};
struct arm32_bus_dma_tag omapl1x_desc_dma_tag = {
._ranges = omapl1x_dma_ranges,
._nranges = __arraycount(omapl1x_dma_ranges),
_BUS_DMAMAP_FUNCS,
_BUS_DMAMEM_FUNCS,
_BUS_DMATAG_FUNCS,
};

View File

@ -0,0 +1,121 @@
/*
* Based on arch/arm/xscale/pxa2x0_com.c
*
* Copyright 2003 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Steve C. Woodford for Wasabi Systems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: omapl1x_com.c,v 1.1 2013/10/02 16:48:26 matt Exp $");
#include "opt_com.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/termios.h>
#include <sys/bus.h>
#include <machine/intr.h>
#include <arm/pic/picvar.h>
#include <dev/ic/comreg.h>
#include <dev/ic/comvar.h>
#include <arm/omap/omap_tipb.h>
#include <arm/omap/omapl1x_reg.h>
static int omapl1xcom_match(device_t, cfdata_t , void *);
static void omapl1xcom_attach(device_t, device_t, void *);
CFATTACH_DECL_NEW(omapl1xcom, sizeof(struct com_softc),
omapl1xcom_match, omapl1xcom_attach, NULL, NULL);
static int
omapl1xcom_match(device_t parent, cfdata_t cf, void *aux)
{
struct tipb_attach_args *tipb = aux;
bus_space_handle_t bh;
int rv;
if (tipb->tipb_addr == -1 || tipb->tipb_intr == -1)
panic("omapl1xcom must have addr and intr specified in config.");
if (tipb->tipb_size == 0)
tipb->tipb_size = OMAPL1X_UART_SIZE;
if (com_is_console(tipb->tipb_iot, tipb->tipb_addr, NULL))
return (1);
if (bus_space_map(tipb->tipb_iot, tipb->tipb_addr, tipb->tipb_size,
0, &bh))
return (0);
rv = comprobe1(tipb->tipb_iot, bh);
bus_space_unmap(tipb->tipb_iot, bh, tipb->tipb_size);
return (rv);
}
static void
omapl1xcom_attach(device_t parent, device_t self, void *aux)
{
struct com_softc *sc = device_private(self);
struct tipb_attach_args *tipb = aux;
bus_space_tag_t iot;
bus_space_handle_t ioh;
bus_addr_t iobase;
sc->sc_dev = self;
iot = tipb->tipb_iot;
iobase = tipb->tipb_addr;
sc->sc_frequency = OMAPL1X_COM_FREQ;
sc->sc_type = COM_TYPE_16550_NOERS;
if (com_is_console(iot, iobase, &ioh) == 0 &&
bus_space_map(iot, iobase, tipb->tipb_size, 0, &ioh)) {
panic(": can't map registers\n");
return;
}
COM_INIT_REGS(sc->sc_regs, iot, ioh, iobase);
com_attach_subr(sc);
aprint_naive("\n");
intr_establish(tipb->tipb_intr, IPL_SERIAL, IST_LEVEL_HIGH,
comintr, sc);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,38 @@
/* $NetBSD: omapl1x_intr.h,v 1.1 2013/10/02 16:48:26 matt Exp $ */
/*
* 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 this list of conditions
* and the following disclaimer.
* 2. Redistributions in binary form must reproduce this list of conditions
* and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``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 ANY
* 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.
*/
#ifndef _ARM_OMAP_OMAPL1X_INTR_H_
#define _ARM_OMAP_OMAPL1X_INTR_H_
#define ARM_IRQ_HANDLER _C_LABEL(omapl1xaintc_irq_handler)
#ifndef _LOCORE
#define OMAP_INTC_DEVICE "omapl1xaintc"
#define PIC_MAXSOURCES 101
void omapl1xaintc_irq_handler(void *);
#include <arm/pic/picvar.h>
#endif /* _LOCORE */
#endif /* _ARM_OMAP_OMAPL1X_INTR_H_ */

View File

@ -0,0 +1,67 @@
/* $NetBSD: omapl1x_misc.h,v 1.1 2013/10/02 16:48:26 matt Exp $ */
/*
* Copyright (c) 2013 Sughosh Ganu
*
* 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 this list of conditions
* and the following disclaimer.
* 2. Redistributions in binary form must reproduce this list of conditions
* and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``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 ANY
* 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.
*/
#ifndef _ARM_OMAP_OMAPL1X_MISC_H_
#define _ARM_OMAP_OMAPL1X_MISC_H_
#ifndef STATHZ
# define STATHZ 64
#endif
#define USB0REF_FREQ 0xf
#define USB0REF_FREQ_24M 0x2
#define USB0VBDTCTEN __BIT(4)
#define USB0SESNDEN __BIT(5)
#define USB0PHY_PLLON __BIT(6)
#define USB1SUSPENDM __BIT(7)
#define USB0OTGPWDN __BIT(9)
#define USB0PHYPWDN __BIT(10)
#define USB0PHYCLKMUX __BIT(11)
#define USB1PHYCLKMUX __BIT(12)
#define USB0OTGMODE __BITS(13,14)
#define RESET __BIT(15)
#define USB0PHYCLKGD __BIT(17)
#define SYSCFG_KICK0R_KEY 0x83E70B13
#define SYSCFG_KICK1R_KEY 0x95A4F1E0
#define PSC1_USB20_MODULE 0x1
#define PSC1_USB11_MODULE 0x2
struct omapl1x_syscfg {
bus_space_tag_t syscfg_iot; /* Bus tag */
bus_addr_t syscfg_addr; /* Address */
bus_space_handle_t syscfg_ioh;
bus_size_t syscfg_size;
};
void omapl1x_reset(void);
uint8_t omapl1x_lpsc_enable(uint32_t module);
uint8_t omapl1x_usbclk_enable(struct omapl1x_syscfg *syscfg);
uint64_t omapl1x_get_tc_freq(void);
#endif /* ARM_OMAP__OMAPL1X_MISC_H_ */

View File

@ -0,0 +1,166 @@
/*
* Copyright (c) 2013 Sughosh Ganu
*
* 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 this list of conditions
* and the following disclaimer.
* 2. Redistributions in binary form must reproduce this list of conditions
* and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``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 ANY
* 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.
*/
/*
* Copyright (c) 2005 David Gwynne <dlg@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "opt_omapl1x.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: omapl1x_ohci.c,v 1.1 2013/10/02 16:48:26 matt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdivar.h>
#include <dev/usb/usb_mem.h>
#include <dev/usb/ohcireg.h>
#include <dev/usb/ohcivar.h>
#include <arm/omap/omap_tipb.h>
#include <arm/omap/omapl1x_reg.h>
#include <arm/omap/omapl1x_misc.h>
struct omapl1xchipfg_softc {
void *sc_ih;
bus_addr_t sc_addr;
bus_addr_t sc_size;
};
struct omapl1xohci_softc {
ohci_softc_t sc;
void *sc_ih;
int sc_intr;
};
struct omapl1x_syscfg syscfg0;
static int omapl1xohci_match(struct device *, struct cfdata *, void *);
static void omapl1xohci_attach(struct device *, struct device *, void *);
CFATTACH_DECL_NEW(omapl1xohci, sizeof(struct omapl1xohci_softc),
omapl1xohci_match, omapl1xohci_attach, NULL, NULL);
static int
omapl1xohci_match (struct device *parent, struct cfdata *cf, void *aux)
{
return 1; /* XXX */
}
static void
omapl1xohci_attach (struct device *parent, struct device *self, void *aux)
{
struct omapl1xohci_softc *sc = device_private(self);
struct tipb_attach_args *tipb = aux;
usbd_status r;
/* Map OHCI registers */
if (bus_space_map(tipb->tipb_iot, tipb->tipb_addr, tipb->tipb_size, 0,
&sc->sc.ioh)) {
aprint_error_dev(self, "can't map ohci mem space\n");
return;
}
/* Enable the usb lpsc modules */
if (omapl1x_lpsc_enable(PSC1_USB20_MODULE) != 0) {
aprint_error_dev(self, "can't enable usb2.0 module\n");
return;
}
if (omapl1x_lpsc_enable(PSC1_USB11_MODULE) != 0) {
aprint_error_dev(self, "can't enable usb1.1 module\n");
return;
}
syscfg0.syscfg_iot = tipb->tipb_iot;
syscfg0.syscfg_addr = OMAPL1X_SYSCFG0_ADDR;
syscfg0.syscfg_size = OMAPL1X_SYSCFG0_SIZE;
/* Map syscfg registers. We want to use it for configuring cfgchip2 */
if (bus_space_map(syscfg0.syscfg_iot, syscfg0.syscfg_addr,
syscfg0.syscfg_size, 0, &syscfg0.syscfg_ioh)) {
aprint_error_dev(self, "can't map syscfg0 mem space\n");
return;
}
sc->sc.sc_dev = self;
sc->sc.sc_bus.hci_private = sc;
sc->sc_intr = tipb->tipb_intr;
sc->sc.iot = tipb->tipb_iot;
sc->sc.sc_addr = tipb->tipb_addr;
sc->sc.sc_size = tipb->tipb_size;
sc->sc.sc_bus.dmatag = tipb->tipb_dmac;
/* Disable interrupts, so we don't get any spurious ones. */
bus_space_write_4(sc->sc.iot, sc->sc.ioh, OHCI_INTERRUPT_DISABLE,
OHCI_ALL_INTRS);
/* provide clock to USB block */
if (!omapl1x_usbclk_enable(&syscfg0)) {
aprint_error_dev(self, "phy init failed\n");
return;
}
/* establish the interrupt. */
sc->sc_ih = intr_establish(sc->sc_intr, IPL_USB, IST_LEVEL_HIGH,
ohci_intr, sc);
if (sc->sc_ih == NULL) {
aprint_error_dev(self, "couldn't establish interrupt\n");
return;
}
strlcpy(sc->sc.sc_vendor, "OMAPL1X", sizeof sc->sc.sc_vendor);
r = ohci_init(&sc->sc);
if (r != USBD_NORMAL_COMPLETION) {
aprint_error_dev(self, "init failed, error=%d\n", r);
return;
}
/* Attach usb device. */
sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint);
/* Done accessing the syscfg0 registers */
bus_space_unmap(syscfg0.syscfg_iot, syscfg0.syscfg_ioh,
syscfg0.syscfg_size);
}

View File

@ -0,0 +1,134 @@
/*
* Copyright (c) 2013 Sughosh Ganu
*
* 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 this list of conditions
* and the following disclaimer.
* 2. Redistributions in binary form must reproduce this list of conditions
* and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``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 ANY
* 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_omapl1x.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: omapl1x_psc.c,v 1.1 2013/10/02 16:48:26 matt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <arm/omap/omap_tipb.h>
#include <arm/omap/omapl1x_reg.h>
#include <arm/omap/omapl1x_misc.h>
typedef struct omapl1xpsc_softc {
bus_space_tag_t sc_iot; /* Bus tag */
bus_addr_t sc_addr; /* Address */
bus_space_handle_t sc_ioh;
bus_size_t sc_size;
int sc_unit;
} omapl1xpsc_softc_t;
/*
* Currently, using only psc1 module, so
* a single softc pointer should suffice.
*/
static omapl1xpsc_softc_t *sc;
static uint8_t omapl1x_lpsc_set_state(uint32_t state, uint32_t module);
static int omapl1xpsc_match(struct device *parent, struct cfdata *cf, void *aux);
static void omapl1xpsc_attach(device_t parent, device_t self, void *aux);
#define MDCTL_NEXT_MASK 0x7
#define MODULE_STATE 0x3f
#define LPSC_STATE_ENABLE 0x3
#define PSC1_USB20_MODULE 0x1
#define PSC1_USB11_MODULE 0x2
CFATTACH_DECL_NEW(omapl1xpsc, sizeof(struct omapl1xpsc_softc),
omapl1xpsc_match, omapl1xpsc_attach, NULL, NULL);
static uint8_t
omapl1x_lpsc_set_state(uint32_t state, uint32_t module)
{
uint32_t val;
/* Wait for the GOSTAT[x] bit in PTSTAT to clear */
do {
val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, PTSTAT);
} while (val & 0x1);
/* Set the Next bit in MDCTL to the state */
val = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
MDCTL + module * 4);
val &= ~MDCTL_NEXT_MASK;
val |= state;
bus_space_write_4(sc->sc_iot, sc->sc_ioh, MDCTL + module * 4, val);
/* Set the GO bit in PTCMD to initiate the transition */
val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, PTCMD);
val |= 0x1;
bus_space_write_4(sc->sc_iot, sc->sc_ioh, PTCMD, val);
/* Wait for the GOSTAT[x] bit in PTSTAT to clear */
do {
val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, PTSTAT);
} while (val & 0x1);
/* Check if the STATE field in MDSTAT reflects the new state */
val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MDSTAT + module * 4);
return (val & MODULE_STATE) != state ? 1 : 0;
}
uint8_t
omapl1x_lpsc_enable(uint32_t module)
{
return omapl1x_lpsc_set_state(LPSC_STATE_ENABLE, module);
}
static int
omapl1xpsc_match(struct device *parent, struct cfdata *cf, void *aux)
{
return 1; /* XXX */
}
static void
omapl1xpsc_attach(device_t parent, device_t self, void *aux)
{
struct tipb_attach_args *tipb = aux;
sc = device_private(self);
sc->sc_iot = tipb->tipb_iot;
sc->sc_unit = self->dv_unit;
sc->sc_addr = tipb->tipb_addr;
sc->sc_size = tipb->tipb_size;
/* Map PSC registers */
if (bus_space_map(sc->sc_iot, sc->sc_addr, sc->sc_size,
0, &sc->sc_ioh)) {
aprint_error_dev(self, "can't map psc%d mem space\n",
sc->sc_unit);
return;
}
}

View File

@ -0,0 +1,182 @@
/* $NetBSD: omapl1x_reg.h,v 1.1 2013/10/02 16:48:26 matt Exp $ */
/*
* Copyright (c) 2013 Linu Cherian
*
* 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 this list of conditions
* and the following disclaimer.
* 2. Redistributions in binary form must reproduce this list of conditions
* and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``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 ANY
* 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.
*/
#ifndef _ARM_OMAP_OMAPL1X_REG_H_
#define _ARM_OMAP_OMAPL1X_REG_H_
#include "opt_omapl1x.h"
#ifndef MEMSIZE
#error Specify the amount of SDRAM in megabytes with the MEMSIZE option.
#endif
#define MEMSIZE_BYTES (MEMSIZE * 1024 * 1024)
/* OMAPL138 Memory Map */
#define OMAPL1X_TIMER_SIZE 0x1000
#define OMAPL1X_UART_SIZE 0x1000
#define OMAPL1X_AINTC_SIZE 0x2000
#define OMAPL1X_EMAC_SIZE 0x3000
#define OMAPL1X_SYSCFG0_ADDR 0x01c14000
#define OMAPL1X_SYSCFG0_SIZE 0x190
#define OMAPL1X_WDT_ADDR 0x01C21000
#define OMAPL1X_WDT_SIZE 0x80
/* Timer */
#define PID12 0x00
#define TIM12 0x10
#define TIM34 0x14
#define PRD12 0x18
#define PRD34 0x1c
#define TCR 0x20
#define TGCR 0x24
#define INTCTLSTAT 0x44
#define WDTCR 0x28
/* SYSCFG */
#define KICK0R 0x038
#define KICK1R 0x03C
#define CFGCHIP2 0x184
/* AINTC */
#define AINTC_REVID 0x0000
#define AINTC_CR 0x0004
#define AINTC_GER 0x0010
#define AINTC_GNLR 0x001C
#define AINTC_SISR 0x0020
#define AINTC_SICR 0x0024
#define AINTC_EISR 0x0028
#define AINTC_EICR 0x002C
#define AINTC_HIEISR 0x0034
#define AINTC_HIEICR 0x0038
#define AINTC_VBR 0x0050
#define AINTC_VSR 0x0054
#define AINTC_VNR 0x0058
#define AINTC_GPIR 0x0080
#define AINTC_GPVR 0x0084
#define AINTC_SRSR1 0x0200
#define AINTC_SRSR2 0x0204
#define AINTC_SRSR3 0x0208
#define AINTC_SRSR4 0x020C
#define AINTC_SECR1 0x0280
#define AINTC_SECR2 0x0284
#define AINTC_SECR3 0x0288
#define AINTC_SECR4 0x028C
#define AINTC_ESR1 0x0300
#define AINTC_ESR2 0x0304
#define AINTC_ESR3 0x0308
#define AINTC_ESR4 0x030C
#define AINTC_ECR1 0x0380
#define AINTC_ECR2 0x0384
#define AINTC_ECR3 0x0388
#define AINTC_ECR4 0x038c
/*
* FFFE E400h CMR0-CMR25 Channel
* Map Registers 0-25 Section
* 12.4.32 FFFE E464h
*/
#define AINTC_CMR0 0x0400
#define AINTC_HIPIR1 0x0900
#define AINTC_HIPIR2 0x0904
#define AINTC_HINLR1 0x1100
#define AINTC_HINLR2 0x1104
#define AINTC_HIER 0x1500
#define AINTC_HIPVR1 0x1600
#define AINTC_HIPVR2 0x1604
/* PSC */
#define PTSTAT 0x128
#define PTCMD 0x120
#define MDSTAT 0x800
#define MDCTL 0xA00
/* EMAC */
#define MAC_OFFSET 0x1000
#define MACTXCONTROL (MAC_OFFSET + 0x4)
#define MACTXTEARDOWN (MAC_OFFSET + 0x8)
#define MACRXCONTROL (MAC_OFFSET + 0x14)
#define MACRXTEARDOWN (MAC_OFFSET + 0x18)
#define MACTXINTMASKSET (MAC_OFFSET + 0x88)
#define MACTXINTMASKCLEAR (MAC_OFFSET + 0x8C)
#define MACINVECTOR (MAC_OFFSET + 0x90)
#define MACEOIVECTOR (MAC_OFFSET + 0x94)
#define MACRXINTMASKSET (MAC_OFFSET + 0xA8)
#define MACRXINTMASKCLEAR (MAC_OFFSET + 0xAC)
#define MACINTMASKSET (MAC_OFFSET + 0xB8)
#define MACRXMBPEN (MAC_OFFSET + 0x100)
#define MACRXUNICASTSET (MAC_OFFSET + 0x104)
#define MACRXUNICASTCLEAR (MAC_OFFSET + 0x108)
#define MACRXMAXLEN (MAC_OFFSET + 0x10C)
#define MACRXBUFOFFSET (MAC_OFFSET + 0x110)
#define MACCONTROL (MAC_OFFSET + 0x160)
#define MACSOFTRESET (MAC_OFFSET + 0x174)
#define MACSRCADDRLO (MAC_OFFSET + 0x1D0)
#define MACSRCADDRHI (MAC_OFFSET + 0x1D4)
#define MACHASH1 (MAC_OFFSET + 0x1D8)
#define MACHASH2 (MAC_OFFSET + 0x1DC)
#define MACADDRLO (MAC_OFFSET + 0x500)
#define MACADDRHI (MAC_OFFSET + 0x504)
#define MACINDEX (MAC_OFFSET + 0x508)
#define MAC_TX_HDP(p) (MAC_OFFSET + 0x600 + ((p) * 0x04))
#define MAC_TX_CP(p) (MAC_OFFSET + 0x640 + ((p) * 0x04))
#define MAC_RX_HDP(p) (MAC_OFFSET + 0x620 + ((p) * 0x04))
#define MAC_RX_CP(p) (MAC_OFFSET + 0x660 + ((p) * 0x04))
#define MAC_CR_OFFSET 0x0
#define MAC_CR_SOFT_RESET (MAC_CR_OFFSET + 0x04)
#define MAC_CR_INT_CONTROL (MAC_CR_OFFSET + 0x0c)
#define MAC_CR_C_RX_THRESH_EN(p) (MAC_CR_OFFSET + (0x10 * (p)) + 0x10)
#define MAC_CR_C_RX_EN(p) (MAC_CR_OFFSET + (0x10 * (p)) + 0x14)
#define MAC_CR_C_TX_EN(p) (MAC_CR_OFFSET + (0x10 * (p)) + 0x18)
#define MAC_CR_C_MISC_EN(p) (MAC_CR_OFFSET + (0x10 * (p)) + 0x1C)
#define MAC_CR_C_RX_THRESH_STAT(p) (MAC_CR_OFFSET + (0x10 * (p)) + 0x40)
#define MAC_CR_C_RX_STAT(p) (MAC_CR_OFFSET + (0x10 * (p)) + 0x44)
#define MAC_CR_C_TX_STAT(p) (MAC_CR_OFFSET + (0x10 * (p)) + 0x48)
#define MAC_CR_C_MISC_STAT(p) (MAC_CR_OFFSET + (0x10 * (p)) + 0x4C)
#define MAC_MDIO_OFFSET 0x2000
#define MACMDIOCONTROL (MAC_MDIO_OFFSET + 0x4)
#define MACMDIOUSERACCESS0 (MAC_MDIO_OFFSET + 0x80)
#define EMAC_CPPI_RAM_BASE 0x01E20000
#define EMAC_CPPI_RAM_SIZE 0x2000
#endif /* _ARM_OMAP_OMAPL1X_REG_H_ */

View File

@ -0,0 +1,552 @@
/*
* Copyright (c) 2013 Sughosh Ganu
*
* 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 this list of conditions
* and the following disclaimer.
* 2. Redistributions in binary form must reproduce this list of conditions
* and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``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 ANY
* 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>
__KERNEL_RCSID(0, "$NetBSD: omapl1x_timer.c,v 1.1 2013/10/02 16:48:26 matt Exp $");
#include "opt_timer.h"
#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/time.h>
#include <sys/timetc.h>
#include <sys/device.h>
#include <sys/bus.h>
#include <dev/clock_subr.h>
#include <machine/intr.h>
#include <arm/cpufunc.h>
#include <arm/pic/picvar.h>
#include <arm/omap/omap_tipb.h>
#include <arm/omap/omapl1x_reg.h>
#include <arm/omap/omapl1x_misc.h>
typedef struct timer_factors {
uint32_t tf_counts_per_usec;
uint32_t tf_period;
uint32_t tf_enamode;
uint32_t tf_ctr_reg;
uint32_t tf_prd_reg;
uint32_t tf_enamode_shift;
uint32_t tf_intr_prd_en_shift;
uint32_t tf_intr_prd_stat_shift;
} timer_factors_t;
typedef struct omapl1xtmr_softc {
struct device sc_dev;
uint sc_timerno;
uint sc_timer_freq;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
bus_addr_t sc_addr;
size_t sc_size;
int sc_intr;
timer_factors_t sc_tf;
uint sc_bot;
} omapl1xtmr_softc_t;
static struct omapl1x_wdt {
bus_space_tag_t wdt_iot; /* Bus tag */
bus_addr_t wdt_addr; /* Address */
bus_space_handle_t wdt_ioh;
bus_size_t wdt_size;
} wdt;
static int omapl1xtimer_match(device_t, struct cfdata *, void *);
static void omapl1xtimer_attach(device_t, device_t, void *);
static int omapl1xtimer_clockintr(void *frame);
static int omapl1xtimer_statintr(void *frame);
static void omapl1x_microtime_init(void);
static inline uint32_t omapl1x_get_timecount(struct timecounter *tc);
static inline void omapl1xtimer_stop(struct omapl1xtmr_softc *sc);
static inline uint32_t omapl1xtimer_read(struct omapl1xtmr_softc *sc);
static void omapl1xtimer_prd_intr_dis(struct omapl1xtmr_softc *sc);
static void omapl1xtimer_prd_intr_enb(struct omapl1xtmr_softc *sc);
static void omapl1xtimer_prd_intr_clr(struct omapl1xtmr_softc *sc);
static void omapl1xtimer_start(struct omapl1xtmr_softc *sc);
static void timer_factors(struct omapl1xtmr_softc *sc, int ints_per_sec,
uint8_t enamode);
static void timer_init(struct omapl1xtmr_softc *sc, int schz, uint8_t enamode,
boolean_t intr);
static struct timecounter omapl1x_timecounter = {
.tc_get_timecount = omapl1x_get_timecount,
.tc_counter_mask = 0xffffffff,
.tc_name = "gpt",
.tc_quality = 100,
.tc_priv = NULL
};
#ifdef OMAPL1X_TIMER_DEBUG
static void tfprint(uint, timer_factors_t *);
#endif
static uint32_t counts_per_usec;
static uint32_t counts_per_hz = ~0;
static struct omapl1xtmr_softc *clock_sc;
static struct omapl1xtmr_softc *stat_sc;
static struct omapl1xtmr_softc *ref_sc;
/* Timer modes */
#define TGCR_TIMMODE_64BIT 0x0
#define TGCR_TIMMODE_32BIT_UNCHANINED 0x1
#define TGCR_TIMMODE_64BIT_WDOG 0x2
#define TGCR_TIMMODE_32BIT_CHANINED 0x3
#define TGCR_TIMMODE_SHIFT 2
#define TGCR_RS_STOP 0x0
#define TGCR_RS_RUN 0x1
#define TGCR_RS_MASK 0x3
#define TGCR_RS_12_SHIFT 0
#define TGCR_RS_34_SHIFT 1
#define TCR_ENAMODE_DISABLE 0x0
#define TCR_ENAMODE_ONESHOT 0x1
#define TCR_ENAMODE_CONTINUOUS 0x2
#define TCR_ENAMODE_RELOAD 0x3
#define TCR_ENAMODE_MASK 0x3
#define TCR_ENAMODE_12_SHIFT 6
#define TCR_ENAMODE_34_SHIFT 22
#define INTR_PRD_12_EN_SHIFT 0
#define INTR_PRD_34_EN_SHIFT 16
#define INTR_PRD_12_STAT_SHIFT 1
#define INTR_PRD_34_STAT_SHIFT 17
/* Watchdog related macros */
#define WDTCR_WDTKEY1 0xA5C6
#define WDTCR_WDTKEY2 0xDA7E
#define WDTCR_WDKEY_SHIFT 16
#define WDTCR_WDEN_SHIFT 14
#define WDTCR_WDKEY_MASK 0xffff0000
CFATTACH_DECL_NEW(omapl1xtimer, sizeof(struct omapl1xtmr_softc),
omapl1xtimer_match, omapl1xtimer_attach, NULL, NULL);
static void
omapl1xtimer_prd_intr_dis (struct omapl1xtmr_softc *sc)
{
uint32_t val;
timer_factors_t *tfp = &sc->sc_tf;
val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, INTCTLSTAT);
val &= ~(1 << tfp->tf_intr_prd_en_shift);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, INTCTLSTAT, val);
}
static void
omapl1xtimer_prd_intr_enb (struct omapl1xtmr_softc *sc)
{
uint32_t val;
timer_factors_t *tfp = &sc->sc_tf;
val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, INTCTLSTAT);
val |= 1 << tfp->tf_intr_prd_en_shift;
bus_space_write_4(sc->sc_iot, sc->sc_ioh, INTCTLSTAT, val);
}
static void
omapl1xtimer_prd_intr_clr (struct omapl1xtmr_softc *sc)
{
uint32_t val;
timer_factors_t *tfp = &sc->sc_tf;
val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, INTCTLSTAT);
val |= 1 << tfp->tf_intr_prd_stat_shift;
bus_space_write_4(sc->sc_iot, sc->sc_ioh, INTCTLSTAT, val);
}
static inline uint32_t
omapl1xtimer_read (struct omapl1xtmr_softc *sc)
{
timer_factors_t *tfp = &sc->sc_tf;
return bus_space_read_4(sc->sc_iot, sc->sc_ioh, tfp->tf_ctr_reg);
}
static inline void
omapl1xtimer_stop (struct omapl1xtmr_softc *sc)
{
uint32_t val;
timer_factors_t *tfp = &sc->sc_tf;
val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, TCR);
val &= ~(TCR_ENAMODE_MASK << tfp->tf_enamode_shift);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, TCR, val);
}
static void
omapl1xtimer_start (struct omapl1xtmr_softc *sc)
{
uint32_t val, shift;
timer_factors_t *tfp = &sc->sc_tf;
/* get the timer to be used out of reset */
shift = sc->sc_bot ? TGCR_RS_12_SHIFT : TGCR_RS_34_SHIFT;
val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, TGCR);
val |= TGCR_RS_RUN << shift;
bus_space_write_4(sc->sc_iot, sc->sc_ioh, TGCR, val);
/* set the desired timer period */
bus_space_write_4(sc->sc_iot, sc->sc_ioh, tfp->tf_prd_reg,
tfp->tf_period);
/* set the selected enamode to get the timer running */
val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, TCR);
val |= tfp->tf_enamode << tfp->tf_enamode_shift;
bus_space_write_4(sc->sc_iot, sc->sc_ioh, TCR, val);
}
static inline uint32_t
omapl1x_get_timecount (struct timecounter *tc)
{
return omapl1xtimer_read(ref_sc);
}
int
omapl1xtimer_clockintr (void *frame)
{
struct omapl1xtmr_softc *sc = clock_sc;
omapl1xtimer_prd_intr_clr(sc);
hardclock(frame);
return 1;
}
int
omapl1xtimer_statintr (void *frame)
{
struct omapl1xtmr_softc *sc = stat_sc;
omapl1xtimer_prd_intr_clr(sc);
statclock(frame);
return 1;
}
static void
timer_init (struct omapl1xtmr_softc *sc, int schz, uint8_t enamode,
boolean_t intr)
{
int val = 0;
timer_factors(sc, schz, enamode);
omapl1xtimer_stop(sc);
omapl1xtimer_prd_intr_dis(sc);
omapl1xtimer_prd_intr_clr(sc);
/* Clear tcr, tgcr, timer counters and period registers */
bus_space_write_4(sc->sc_iot, sc->sc_ioh, TCR, 0);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, TGCR, 0);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, TIM12, 0);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, TIM34, 0);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, PRD12, 0);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, PRD34, 0);
if (intr)
omapl1xtimer_prd_intr_enb(sc);
/* Set timers to 32 bot unchained mode */
val = TGCR_TIMMODE_32BIT_UNCHANINED << TGCR_TIMMODE_SHIFT;
bus_space_write_4(sc->sc_iot, sc->sc_ioh, TGCR, val);
omapl1xtimer_start(sc);
}
static void
omapl1x_microtime_init (void)
{
if (ref_sc == NULL)
panic("microtime reference timer was not configured.");
timer_init(ref_sc, 0, TCR_ENAMODE_CONTINUOUS, FALSE);
}
void
setstatclockrate (int schz)
{
if (stat_sc == NULL)
panic("Statistics timer was not configured.");
timer_init(stat_sc, schz, TCR_ENAMODE_CONTINUOUS, TRUE);
}
/*
* clock_sc and stat_sc starts here
* ref_sc is initialized already by tipbtimer_attach
*/
void
cpu_initclocks(void)
{
if (clock_sc == NULL)
panic("Clock timer was not configured.");
if (stat_sc == NULL)
panic("Statistics timer was not configured.");
if (ref_sc == NULL)
panic("Microtime reference timer was not configured.");
/*
* We already have the timers running, but not generating interrupts.
* In addition, we've set stathz and profhz.
*/
printf("clock: hz=%d stathz=%d\n", hz, stathz);
/*
* The "cookie" parameter must be zero to pass the interrupt frame
* through to hardclock() and statclock().
*/
intr_establish(clock_sc->sc_intr, IPL_CLOCK, IST_LEVEL_HIGH,
omapl1xtimer_clockintr, 0);
intr_establish(stat_sc->sc_intr, IPL_HIGH, IST_LEVEL_HIGH,
omapl1xtimer_statintr, 0);
timer_init(clock_sc, hz, TCR_ENAMODE_CONTINUOUS, TRUE);
timer_init(stat_sc, stathz, TCR_ENAMODE_CONTINUOUS, TRUE);
omapl1x_timecounter.tc_frequency = omapl1x_get_tc_freq();
tc_init(&omapl1x_timecounter);
}
void
delay (u_int n)
{
struct omapl1xtmr_softc *sc = ref_sc;
uint32_t cur, last, delta, usecs;
if (sc == NULL)
panic("The timer must be initialized sooner.");
/*
* This works by polling the timer and counting the
* number of microseconds that go by.
*/
last = omapl1xtimer_read(sc);
delta = usecs = 0;
while (n > usecs) {
cur = omapl1xtimer_read(sc);
/* Check to see if the timer has wrapped around. */
if (last > cur)
delta += (cur + (counts_per_hz - last));
else
delta += (cur - last);
last = cur;
if (delta >= counts_per_usec) {
usecs += delta / counts_per_usec;
delta %= counts_per_usec;
}
}
}
static void
timer_factors (struct omapl1xtmr_softc *sc, int ints_per_sec, uint8_t enamode)
{
timer_factors_t *tfp = &sc->sc_tf;
const uint32_t us_per_sec = 1000000;
if (ints_per_sec == 0) {
tfp->tf_period = ~0U;
counts_per_usec = sc->sc_timer_freq / us_per_sec;
} else {
uint32_t count_freq;
count_freq = sc->sc_timer_freq;
count_freq /= ints_per_sec;
tfp->tf_period = count_freq;
}
tfp->tf_counts_per_usec = sc->sc_timer_freq / us_per_sec;
tfp->tf_enamode = enamode;
if (sc->sc_bot) {
tfp->tf_ctr_reg = TIM12;
tfp->tf_prd_reg = PRD12;
tfp->tf_enamode_shift = TCR_ENAMODE_12_SHIFT;
tfp->tf_intr_prd_en_shift = INTR_PRD_12_EN_SHIFT;
tfp->tf_intr_prd_stat_shift = INTR_PRD_12_STAT_SHIFT;
} else {
tfp->tf_ctr_reg = TIM34;
tfp->tf_prd_reg = PRD34;
tfp->tf_enamode_shift = TCR_ENAMODE_34_SHIFT;
tfp->tf_intr_prd_en_shift = INTR_PRD_34_EN_SHIFT;
tfp->tf_intr_prd_stat_shift = INTR_PRD_34_STAT_SHIFT;
}
#ifdef OMAPL1X_TIMER_DEBUG
tfprint(sc->sc_timerno, tfp);
Debugger();
#endif
}
#ifdef OMAPL1X_TIMER_DEBUG
void
tfprint (uint n, timer_factors_t *tfp)
{
printf("%s: timer# %d\n", __func__, n);
printf("\ttf_counts_per_usec: %#x\n", tfp->tf_counts_per_usec);
printf("\ttf_counter: %#x\n", tfp->period);
printf("\ttf_enamode: %#x\n", tfp->tf_enamode);
}
#endif
static int
omapl1xtimer_match (device_t parent, struct cfdata *match, void *aux)
{
return 1;
}
void
omapl1xtimer_attach (device_t parent, device_t self, void *aux)
{
struct omapl1xtmr_softc *sc = device_private(self);
struct tipb_attach_args *tipb = aux;
sc->sc_timerno = self->dv_unit;
sc->sc_iot = tipb->tipb_iot;
sc->sc_intr = tipb->tipb_intr;
sc->sc_addr = tipb->tipb_addr;
sc->sc_bot = 1; /* use the bottom timer in all cases */
sc->sc_size = OMAPL1X_TIMER_SIZE;
if (bus_space_map(sc->sc_iot, sc->sc_addr, sc->sc_size, 0, &sc->sc_ioh))
panic("%s: Cannot map registers", device_xname(self));
aprint_normal("\n");
aprint_naive("\n");
switch (sc->sc_timerno) {
case 0:
/*
* timer #0 is the system clock
* it gets started later
*/
clock_sc = sc;
sc->sc_timer_freq = OMAPL1X_TIMER0_FREQ;
break;
case 1:
/*
* timer #2 is the stat clock
* it gets started later
*/
profhz = stathz = STATHZ;
stat_sc = sc;
sc->sc_timer_freq = OMAPL1X_TIMER2_FREQ;
break;
case 2:
/*
* Timer #3 is used for microtime reference clock and for delay()
* autoloading, non-interrupting, just wraps around as an unsigned int.
* we start it now to make delay() available
*/
ref_sc = sc;
sc->sc_timer_freq = OMAPL1X_TIMER3_FREQ;
omapl1x_microtime_init();
break;
default:
panic("bad omapl1x timer number %d\n", sc->sc_timerno);
break;
}
wdt.wdt_iot = tipb->tipb_iot;
wdt.wdt_addr = OMAPL1X_WDT_ADDR;
wdt.wdt_size = OMAPL1X_WDT_SIZE;
/* Map WDT registers. We want to use it for reseting the chip */
if (bus_space_map(wdt.wdt_iot, wdt.wdt_addr,
wdt.wdt_size, 0, &wdt.wdt_ioh)) {
aprint_error_dev(self, "can't map wdt mem space\n");
return;
}
}
void
omapl1x_reset (void)
{
uint32_t val;
printf("\n");
delay(50000);
val = bus_space_read_4(wdt.wdt_iot, wdt.wdt_ioh, TGCR);
/*
* Get the timer out of reset and put it in
* watchdog timer mode.
*/
val |= ((TGCR_RS_RUN << TGCR_RS_12_SHIFT) |
(TGCR_RS_RUN << TGCR_RS_34_SHIFT));
val |= (TGCR_TIMMODE_64BIT_WDOG << TGCR_TIMMODE_SHIFT);
bus_space_write_4(wdt.wdt_iot, wdt.wdt_ioh, TGCR, val);
/* Init the counter and period registers */
bus_space_write_4(wdt.wdt_iot, wdt.wdt_ioh, TIM12, 0x0);
bus_space_write_4(wdt.wdt_iot, wdt.wdt_ioh, TIM34, 0x0);
bus_space_write_4(wdt.wdt_iot, wdt.wdt_ioh, PRD12, ~0);
bus_space_write_4(wdt.wdt_iot, wdt.wdt_ioh, PRD34, ~0);
val = bus_space_read_4(wdt.wdt_iot, wdt.wdt_ioh, WDTCR);
/*
* Now enable the wdt and write the WDKEY1 to get the
* wd in the Pre-active state.
*/
val |= (1 << WDTCR_WDEN_SHIFT);
val |= (WDTCR_WDTKEY1 << WDTCR_WDKEY_SHIFT);
bus_space_write_4(wdt.wdt_iot, wdt.wdt_ioh, WDTCR, val);
/*
* Now write the WDKEY2 to get the wd in the Active
* state.
*/
val = bus_space_read_4(wdt.wdt_iot, wdt.wdt_ioh, WDTCR);
val &= ~WDTCR_WDKEY_MASK;
val |= (WDTCR_WDTKEY2 << WDTCR_WDKEY_SHIFT);
bus_space_write_4(wdt.wdt_iot, wdt.wdt_ioh, WDTCR, val);
/*
* Write an invalid value to the WDKEY to trigger
* the wd timeout right away.
*/
val = bus_space_read_4(wdt.wdt_iot, wdt.wdt_ioh, WDTCR);
val &= ~WDTCR_WDKEY_MASK;
bus_space_write_4(wdt.wdt_iot, wdt.wdt_ioh, WDTCR, val);
while(1);
}

View File

@ -0,0 +1,255 @@
/*
* Autoconfiguration support for the Texas Instruments OMAP TIPB.
* Based on arm/xscale/pxa2x0.c which in turn was derived from
* arm/sa11x0/sa11x0.c. The code to do the early attach was initially derived
* from arch/sparc/dev/obio.c.
*
* Copyright (c) 2002, 2005 Genetec Corporation. All rights reserved.
* Written by Hiroyuki Bessho for Genetec Corporation.
*
* 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 for the NetBSD Project by
* Genetec Corporation.
* 4. The name of Genetec Corporation may not be used to endorse or
* promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``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 GENETEC CORPORATION
* 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.
*
* Copyright (c) 1997, 1998, 2001, The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by IWAMOTO Toshihiro, Ichiro FUKUHARA and Paul Kranenburg.
*
* 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Copyright (c) 1999
* Shin Takemura and PocketBSD Project. 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 the PocketBSD project
* and its contributors.
* 4. Neither the name of the project 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 REGENTS 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 REGENTS 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>
__KERNEL_RCSID(0, "$NetBSD: omapl1x_tipb.c,v 1.1 2013/10/02 16:48:26 matt Exp $");
#include "locators.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/kernel.h>
#include <sys/reboot.h>
#include <sys/bus.h>
#include <machine/cpu.h>
#include <arm/cpufunc.h>
#include <arm/mainbus/mainbus.h>
/*
* XXX. Do we really need this ? #include <arm/omap/omap_reg.h>
* Atleast commenting this makes it more generic.
*/
#include <arm/omap/omap_tipb.h>
#include <arm/omap/omap_var.h>
struct tipb_softc {
struct device sc_dev;
bus_dma_tag_t sc_dmac;
};
/* prototypes */
static int tipb_match(struct device *, struct cfdata *, void *);
static void tipb_attach(struct device *, struct device *, void *);
static int tipb_search(struct device *, struct cfdata *,
const int *, void *);
static int tipb_print(void *, const char *);
/* attach structures */
CFATTACH_DECL_NEW(tipb, sizeof(struct tipb_softc),
tipb_match, tipb_attach, NULL, NULL);
static int tipb_attached;
extern struct arm32_bus_dma_tag omapl1x_bus_dma_tag;
/*
* There are some devices that need to be set up before all the others. The
* earlies array contains their names. tipb_attach() and tipb_search() work
* together to attach these devices in the order they appear in this array
* before any other TIPB devices are attached.
*/
static const char * const earlies[] = {
OMAP_INTC_DEVICE,
"omapl1xtimer",
"omapl1xpsc",
NULL
};
static int
tipb_match(struct device *parent, struct cfdata *match, void *aux)
{
if (tipb_attached)
return 0;
return 1;
}
static void
tipb_attach(struct device *parent, struct device *self, void *aux)
{
struct tipb_softc *sc = (struct tipb_softc *)self;
tipb_attached = 1;
#if NOMAPDMAC > 0
#error DMA not implemented
sc->sc_dmac = &omap_bus_dma_tag;
#else
sc->sc_dmac = omap_bus_dma_init(&omapl1x_bus_dma_tag);
#endif
aprint_normal(": OMAP L1X Texas Instruments Peripheral Bus\n");
aprint_naive("\n");
/*
* There are some devices that need to be set up before all the
* others. The earlies array contains their names. Find them and
* attach them in the order they appear in the array.
*/
const char *const *earlyp;
for (earlyp = earlies; *earlyp != NULL; earlyp++)
/*
* The bus search function is passed an aux argument that
* "describes the device that has been found". The type of it
* is void *. However, I want to pass a constant string, so
* use __UNCONST to convince the compiler that this is ok.
*/
config_search_ia(tipb_search, self, "tipb",
__UNCONST(*earlyp));
/*
* Attach all other devices
*/
config_search_ia(tipb_search, self, "tipb", NULL);
}
static int
tipb_search(struct device *parent, struct cfdata *cf,
const int *ldesc, void *aux)
{
struct tipb_softc *sc = (struct tipb_softc *)parent;
struct tipb_attach_args aa;
const char *const name = (const char *const)aux;
/* Check whether we're looking for a specifically named device */
if (name != NULL && strcmp(name, cf->cf_name) != 0)
return (0);
switch (cf->cf_loc[TIPBCF_MULT]) {
case 1:
aa.tipb_iot = &omap_bs_tag;
break;
case 2:
aa.tipb_iot = &omap_a2x_bs_tag;
break;
case 4:
aa.tipb_iot = &omap_a4x_bs_tag;
break;
default:
panic("Unsupported TIPB multiplier.");
break;
}
aa.tipb_dmac = sc->sc_dmac;
aa.tipb_addr = cf->cf_loc[TIPBCF_ADDR];
aa.tipb_size = cf->cf_loc[TIPBCF_SIZE];
aa.tipb_intr = cf->cf_loc[TIPBCF_INTR];
aa.tipb_mult = cf->cf_loc[TIPBCF_MULT];
if (config_match(parent, cf, &aa))
config_attach(parent, cf, &aa, tipb_print);
return 0;
}
static int
tipb_print(void *aux, const char *name)
{
struct tipb_attach_args *sa = (struct tipb_attach_args*)aux;
if (sa->tipb_addr != TIPBCF_ADDR_DEFAULT) {
aprint_normal(" addr 0x%08lx", sa->tipb_addr);
if (sa->tipb_size > TIPBCF_SIZE_DEFAULT)
aprint_normal("-0x%08lx", sa->tipb_addr + sa->tipb_size-1);
}
if (sa->tipb_intr != TIPBCF_INTR_DEFAULT)
aprint_normal(" intr %d", sa->tipb_intr);
return (UNCONF);
}

176
sys/arch/evbarm/conf/HAWK Normal file
View File

@ -0,0 +1,176 @@
# $NetBSD: HAWK,v 1.1 2013/10/02 16:48:26 matt Exp $
#
# HAWK -- TI OMAPL138 based Board Kernel
#
include "arch/evbarm/conf/std.hawk"
# estimated number of users
maxusers 32
# Standard system options
options RTC_OFFSET=0 # hardware clock is this many mins. west of GMT
# CPU options
options CPU_ARM9E
# Architecture options
# File systems
file-system FFS # UFS
file-system MFS # memory file system
file-system NFS # Network file system
#file-system EXT2FS # second extended file system (linux)
file-system MSDOSFS # MS-DOS file system
#file-system FDESC # /dev/fd
#file-system KERNFS # /kern
#file-system NULLFS # loopback file system
#file-system PROCFS # /proc
file-system PTYFS # /dev/pts/N support
# File system options
#options NFSSERVER
options SOFTDEP
options WAPBL # File system journaling support - Experimental
# Networking options
#options GATEWAY # packet forwarding
options INET # IP + ICMP + TCP + UDP
#options INET6 # IPV6
#options IPSEC # IP security
#options IPSEC_DEBUG # debug for IP security
#options MROUTING # IP multicast routing
#options PIM # Protocol Independent Multicast
#options NETATALK # AppleTalk networking
#options PPP_BSDCOMP # BSD-Compress compression support for PPP
#options PPP_DEFLATE # Deflate compression support for PPP
#options PPP_FILTER # Active filter support for PPP (requires bpf)
#options TCP_DEBUG # Record last TCP_NDEBUG packets with SO_DEBUG
options NFS_BOOT_BOOTP
options NFS_BOOT_DHCP
#options NFS_BOOT_BOOTSTATIC
#options NFS_BOOTSTATIC_MYIP="\"192.168.1.5\""
#options NFS_BOOTSTATIC_GWIP="\"192.168.1.7\""
#options NFS_BOOTSTATIC_MASK="\"255.255.255.0\""
#options NFS_BOOTSTATIC_SERVADDR="\"192.168.1.7\""
#options NFS_BOOTSTATIC_SERVER="\"192.168.1.7:/export/client/root/\""
options NFS_BOOT_RWSIZE=1024
# Compatibility options
#options COMPAT_43 # 4.3BSD compatibility.
options COMPAT_40 # NetBSD 4.0 compatibility.
options COMPAT_30 # NetBSD 3.0 compatibility.
# Shared memory options
options SYSVMSG # System V-like message queues
options SYSVSEM # System V-like semaphores
options SYSVSHM # System V-like memory sharing
# Device options
#options MEMORY_DISK_HOOKS # boottime setup of ramdisk
#options MEMORY_DISK_ROOT_SIZE=34816 # Size in blocks
#options MEMORY_DISK_DYNAMIC
#options MINIROOTSIZE=1000 # Size in blocks
#options MEMORY_DISK_IS_ROOT # use memory disk as root
# Miscellaneous kernel options
options KTRACE # system call tracing, a la ktrace(1)
# Development and Debugging options
options DIAGNOSTIC # internally consistency checks
#options DEBUG
#options PGALLOC_VERBOSE
#options DEBUG_DMA
options VERBOSE_INIT_ARM # verbose bootstraping messages
options DDB # in-kernel debugger
options DDB_ONPANIC=1
options DDB_HISTORY_SIZE=100 # Enable history editing in DDB
#options KGDB
#makeoptions DEBUG="-g" # compile full symbol table
#options SYMTAB_SPACE=200000
## USB Debugging options
options USB_DEBUG
options OHCI_DEBUG
options UHUB_DEBUG
# Valid options for BOOT_ARGS:
options BOOT_ARGS="\"\""
config netbsd root on ? type ?
config netbsd-usb root on sd0e type ffs
config netbsd-emac root on emac0 type nfs
# The main bus device
mainbus0 at root
# The boot cpu
cpu0 at mainbus?
# Specify the memory size in megabytes.
options MEMSIZE=128
# Texas Instruments Peripheral Bus
tipb0 at mainbus?
# 16550 UART(s)
com0 at tipb? addr 0x01d0d000 size 0x1000 intr 61 mult 4 # UART2
options CONSADDR=0x01d0d000, CONSPEED=115200
options OMAPL1X_COM_FREQ=150000000
# ARM Interrupt Controller
omapl1xaintc0 at tipb? addr 0xfffee000 size 0x2000 intr 0
# Timer - Use timer 0, 2, 3 ; timer 1 is left unused
omapl1xtimer0 at tipb? addr 0x01c20000 size 0x1000 intr 21
options OMAPL1X_TIMER0_FREQ=24000000
omapl1xtimer1 at tipb? addr 0x01f0c000 size 0x1000 intr 68
options OMAPL1X_TIMER2_FREQ=120000000
omapl1xtimer2 at tipb? addr 0x01f0d000 size 0x1000 intr 96
options OMAPL1X_TIMER3_FREQ=120000000
#PSC
omapl1xpsc0 at tipb? addr 0x01e27000 size 0x1000
emac0 at tipb? addr 0x01e22000 size 0x3000 intr 33
ukphy* at mii? phy ?
# OHCI
ohci0 at tipb? addr 0x01e25000 size 0x1000 intr 59
usb* at ohci?
uhub* at usb?
uhub* at uhub? port ?
umass* at uhub? port ? configuration ? interface ?
scsibus* at umass?
# SCSI devices
sd* at scsibus? target ? lun ? # SCSI disk drives
# Pseudo-Devices
# disk/mass storage pseudo-devices
pseudo-device md 1 # memory disk device (ramdisk)
#pseudo-device vnd # disk-like interface to files
#pseudo-device fss 4 # file system snapshot device
# network pseudo-devices
pseudo-device bpfilter # Berkeley packet filter
pseudo-device loop # network loopback
#pseudo-device kttcp # network loopback
# miscellaneous pseudo-devices
pseudo-device pty # pseudo-terminals

View File

@ -0,0 +1,15 @@
# $NetBSD: files.hawk,v 1.1 2013/10/02 16:48:26 matt Exp $
#
# Hawk board configuration info
#
file arch/arm/arm32/arm32_boot.c
file arch/arm/arm32/arm32_kvminit.c
file arch/evbarm/hawk/hawk_machdep.c
# Kernel boot arguments
defparam opt_machdep.h BOOT_ARGS
# CPU support and integrated peripherals
include "arch/arm/omap/files.omapl1x"

View File

@ -0,0 +1,22 @@
# $NetBSD: mk.hawk,v 1.1 2013/10/02 16:48:26 matt Exp $
#
CFLAGS+=-mcpu=arm926ej-s
SYSTEM_FIRST_OBJ= hawk_start.o
SYSTEM_FIRST_SFILE= ${THISARM}/hawk/hawk_start.S
_OSRELEASE!= ${HOST_SH} $S/conf/osrelease.sh
MKUBOOTIMAGEARGS= -A arm -T kernel
MKUBOOTIMAGEARGS+= -a $(LOADADDRESS) -e $(LOADADDRESS)
MKUBOOTIMAGEARGS+= -n "NetBSD/$(BOARDTYPE) ${_OSRELEASE}"
MKUBOOTIMAGEARGS_NONE= ${MKUBOOTIMAGEARGS} -C none
SYSTEM_LD_TAIL_EXTRA+=; \
echo ${OBJCOPY} -S -O binary $@ $@.bin; \
${OBJCOPY} -S -O binary $@ $@.bin; \
echo ${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS_NONE} $@.bin $@.ub; \
${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS_NONE} $@.bin $@.ub
EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.bin@}
EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.ub@}

View File

@ -0,0 +1,25 @@
# $NetBSD: std.hawk,v 1.1 2013/10/02 16:48:26 matt Exp $
#
# standard NetBSD/evbarm for hawk options
machine evbarm arm
include "conf/std" # MI standard options
include "arch/arm/conf/std.arm" # arch standard options
# Pull in omapl1x config definitions.
include "arch/evbarm/conf/files.hawk"
options EXEC_ELF32
options EXEC_SCRIPT
# To support easy transit to ../arch/arm/arm32
options ARM32
options KERNEL_BASE_EXT=0xc0000000
makeoptions KERNEL_BASE_PHYS=0xc0200000
makeoptions KERNEL_BASE_VIRT=0xc0200000
makeoptions LOADADDRESS="0xc0200000"
makeoptions BOARDTYPE="hawk"
makeoptions BOARDMKFRAG="${THISARM}/conf/mk.hawk"
options ARM_INTR_IMPL="<arch/arm/omap/omapl1x_intr.h>"

View File

@ -0,0 +1,45 @@
/* $NetBSD: hawk.h,v 1.1 2013/10/02 16:48:26 matt Exp $ */
/*
* Copyright (c) 2013 Linu Cherian
*
* 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 this list of conditions
* and the following disclaimer.
* 2. Redistributions in binary form must reproduce this list of conditions
* and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``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 ANY
* 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.
*/
#ifndef _EVBARM_HAWK_HAWK_H
#define _EVBARM_HAWK_HAWK_H
/* OMAPL138 Memory Map */
#define OMAPL138_MEM_BASE 0xC0000000
#define OMAPL138_IO_BASE 0x01D00000 /* for static 1MB mapping */
/*
* Kernel VM space: 192MB at KERNEL_VM_BASE
*/
#define KERNEL_VM_BASE ((KERNEL_BASE + 0x01800000) & ~(0x400000-1))
#define KERNEL_VM_SIZE 0x0C000000
/*
* We devmap IO starting at KERNEL_VM_BASE + KERNEL_VM_SIZE
*/
#define OMAPL1X_KERNEL_IO_VBASE (KERNEL_VM_BASE + KERNEL_VM_SIZE)
#endif /* _EVBARM_HAWK_HAWK_H */

View File

@ -0,0 +1,465 @@
/*
* Copyright (c) 2013 Linu Cherian
* Copyright (c) 2013 Sughosh Ganu
*
* 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 this list of conditions
* and the following disclaimer.
* 2. Redistributions in binary form must reproduce this list of conditions
* and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``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 ANY
* 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>
__KERNEL_RCSID(0, "$NetBSD: hawk_machdep.c,v 1.1 2013/10/02 16:48:26 matt Exp $");
#include "opt_timer.h"
#include "opt_machdep.h"
#include "opt_ddb.h"
#include "opt_kgdb.h"
#include "opt_md.h"
#include "opt_com.h"
#include <sys/types.h>
#include <sys/param.h>
#include <sys/device.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/exec.h>
#include <sys/proc.h>
#include <sys/msgbuf.h>
#include <sys/reboot.h>
#include <sys/termios.h>
#include <sys/ksyms.h>
#include <sys/bus.h>
#include <uvm/uvm_extern.h>
#include <sys/conf.h>
#include <dev/cons.h>
#include <dev/md.h>
#include <machine/db_machdep.h>
#include <ddb/db_sym.h>
#include <ddb/db_extern.h>
#ifdef KGDB
#include <sys/kgdb.h>
#endif
#include <machine/bootconfig.h>
#include <machine/autoconf.h>
#include <arm/armreg.h>
#include <arm/locore.h>
#include <arm/undefined.h>
#include <arm/arm32/machdep.h>
#include <arm/omap/omapl1x_reg.h>
#include <arm/omap/omapl1x_misc.h>
#include <arm/omap/omap_tipb.h>
#include <arm/omap/omap_var.h>
#include <evbarm/hawk/hawk.h>
#include <prop/proplib.h>
BootConfig bootconfig; /* Boot config storage */
static char bootargs[MAX_BOOT_STRING];
char *boot_args = NULL;
u_int uboot_args[4] = { 0 };
static struct arm32_dma_range omapl1x_dma_ranges[4];
extern char KERNEL_BASE_phys[];
void consinit(void);
#ifdef KGDB
static void kgdb_port_init(void);
#endif
#include "com.h"
#if NCOM > 0
#include <dev/ic/comreg.h>
#include <dev/ic/comvar.h>
#endif
#define ETHER_ADDR_LEN 6
static void hawk_device_register(device_t self, void *aux);
static int get_mac_addr(char *opts, const char *opt, char *enaddr);
static void convert_mac_addr(char *addrstr, char *enaddr);
/*
* void cpu_reboot(int howto, char *bootstr)
*
* Reboots the system
*
* Deal with any syncing, unmounting, dumping and shutdown hooks,
* then reset the CPU.
*/
void
cpu_reboot(int howto, char *bootstr)
{
#ifdef DIAGNOSTIC
/* info */
printf("boot: howto=%08x curproc=%p\n", howto, curproc);
#endif
/*
* If we are still cold then hit the air brakes
* and crash to earth fast
*/
if (cold) {
doshutdownhooks();
printf("The operating system has halted.\n");
printf("Please press any key to reboot.\n\n");
cngetc();
printf("rebooting...\n");
goto reset;
}
/* Disable console buffering */
/* cnpollc(1);*/
/*
* If RB_NOSYNC was not specified sync the discs.
* Note: Unless cold is set to 1 here, syslogd will die during the
* unmount. It looks like syslogd is getting woken up only to find
* that it cannot page part of the binary in as the filesystem has
* been unmounted.
*/
if (!(howto & RB_NOSYNC))
bootsync();
/* Say NO to interrupts */
splhigh();
/* Do a dump if requested. */
if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
dumpsys();
/* Run any shutdown hooks */
doshutdownhooks();
/* Make sure IRQ's are disabled */
IRQdisable;
if (howto & RB_HALT) {
printf("The operating system has halted.\n");
printf("Please press any key to reboot.\n\n");
cngetc();
}
printf("rebooting...\n");
reset:
/*
* On Davinci processor, the reset is done
* through watchdog timeout.
*/
omapl1x_reset();
/*NOTREACHED*/
}
/*
* Static device mappings. These peripheral registers are mapped at
* fixed virtual addresses very early in initarm() so that we can use
* them while booting the kernel, and stay at the same address
* throughout whole kernel's life time.
*
* We use this table twice; once with bootstrap page table, and once
* with kernel's page table which we build up in initarm().
*
* Since we map these registers into the bootstrap page table using
* pmap_devmap_bootstrap() which calls pmap_map_chunk(), we map
* registers segment-aligned and segment-rounded in order to avoid
* using the 2nd page tables.
*/
#define _A(a) ((a) & ~L1_S_OFFSET)
#define _S(s) (((s) + L1_S_SIZE - 1) & ~(L1_S_SIZE-1))
static const struct pmap_devmap devmap[] = {
{
.pd_va = _A(OMAPL1X_KERNEL_IO_VBASE),
.pd_pa = _A(OMAPL138_IO_BASE),
.pd_size = L1_S_SIZE,
.pd_prot = VM_PROT_READ|VM_PROT_WRITE,
.pd_cache = PTE_NOCACHE
},
{0}
};
#undef _A
#undef _S
static void
convert_mac_addr (char *addrstr, char *enaddr)
{
char *end;
int i;
for (i = 0; i < ETHER_ADDR_LEN; ++i) {
enaddr[i] = addrstr ? strtoul(addrstr, &end, 16) : 0;
if (addrstr)
addrstr = (*end) ? end + 1 : end;
}
}
static int
get_mac_addr (char *opts, const char *opt, char *enaddr)
{
char *ptr;
char *optstart;
ptr = opts;
while (*ptr) {
/* Find start of option */
while (*ptr == ' ' || *ptr == '\t' || *ptr == ';')
++ptr;
if (*ptr == '\0')
break;
/* Find the end of option */
optstart = ptr;
while (*ptr != 0 && *ptr != ' ' && *ptr != '\t' && *ptr != '=')
++ptr;
if (*ptr == '=') {
/* compare the option */
if (strncmp(optstart, opt, (ptr - optstart)) == 0) {
if (*ptr =='=')
++ptr;
convert_mac_addr(ptr, enaddr);
return 1;
}
}
/* skip to next option */
while (*ptr != ' ' && *ptr != '\t' && *ptr != ';' &&
*ptr != '\0') {
++ptr;
}
}
return 0;
}
static void
hawk_device_register (device_t self, void *aux)
{
uint8_t enaddr[ETHER_ADDR_LEN] = { 0 };
prop_data_t pd;
if (device_is_a(self, "emac")) {
/* Get the mac address from the u-boot args */
if (get_mac_addr(bootargs, "mac-address", enaddr)) {
pd = prop_data_create_data(enaddr, ETHER_ADDR_LEN);
KASSERT(pd != NULL);
if (prop_dictionary_set(device_properties(self),
"mac-address", pd) == false) {
printf("Unable to set mac-address property for %s\n",
device_xname(self));
}
prop_object_release(pd);
}
}
}
/*
* u_int initarm(...)
*
* Initial entry point on startup. This gets called before main() is
* entered.
* It should be responsible for setting up everything that must be
* in place when main is called.
* This includes
* Taking a copy of the boot configuration structure.
* Initialising the physical console so characters can be printed.
* Setting up page tables for the kernel
* Relocating the kernel to the bottom of physical memory
*/
u_int
initarm(void *arg)
{
vaddr_t addr;
paddr_t emac_cppi_start, emac_cppi_end;
/*
* Heads up ... Setup the CPU / MMU / TLB functions
*/
if (set_cpufuncs())
panic("cpu not recognized!");
/* map some peripheral registers */
pmap_devmap_register(devmap);
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
consinit();
printf("\nuboot arg = %#x, %#x, %#x, %#x\n",
uboot_args[0], uboot_args[1], uboot_args[2], uboot_args[3]);
strlcpy(bootargs, (char *)uboot_args[3], sizeof(bootargs));
/* Talk to the user */
#define BDSTR(s) _BDSTR(s)
#define _BDSTR(s) #s
printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n");
#ifdef VERBOSE_INIT_ARM
printf("initarm: Configuring system ...\n");
#endif
/* Fake bootconfig structure for the benefit of pmap.c. */
bootconfig.dramblocks = 1;
bootconfig.dram[0].address = OMAPL138_MEM_BASE;
bootconfig.dram[0].pages = MEMSIZE_BYTES / PAGE_SIZE;
arm32_bootmem_init(bootconfig.dram[0].address,
bootconfig.dram[0].pages * PAGE_SIZE, (uintptr_t)KERNEL_BASE_phys);
arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_HIGH, 0, devmap,
false);
#ifdef VERBOSE_INIT_ARM
printf("done.\n");
#endif
#ifdef BOOTHOWTO
boothowto |= BOOTHOWTO;
#endif
/* we've a specific device_register routine */
evbarm_device_register = hawk_device_register;
addr = initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0);
/*
* Now add the emac's cppi ram to the vm pool
* XXX Not sure if there is a better place to
* do this.
*/
emac_cppi_start = EMAC_CPPI_RAM_BASE;
emac_cppi_end = EMAC_CPPI_RAM_BASE + EMAC_CPPI_RAM_SIZE;
uvm_page_physload(atop(emac_cppi_start), atop(emac_cppi_end),
atop(emac_cppi_start), atop(emac_cppi_end),
VM_FREELIST_ISADMA);
return addr;
}
#ifndef CONSADDR
#error Specify the address of the console UART with the CONSADDR option.
#endif
#ifndef CONSPEED
#define CONSPEED 115200
#endif
#ifndef CONMODE
#define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
#endif
static const vaddr_t consaddr = CONSADDR;
static const int conspeed = CONSPEED;
static const int conmode = CONMODE;
void
consinit(void)
{
static int consinit_called = 0;
if (consinit_called != 0)
return;
consinit_called = 1;
if (comcnattach(&omap_a4x_bs_tag, consaddr, conspeed,
OMAPL1X_COM_FREQ, COM_TYPE_16550_NOERS, conmode))
panic("Serial console can not be initialized.");
}
bus_dma_tag_t
omap_bus_dma_init(struct arm32_bus_dma_tag *dma_tag_template)
{
int i;
struct arm32_bus_dma_tag *dmat;
for (i = 0; i < bootconfig.dramblocks; i++) {
omapl1x_dma_ranges[i].dr_sysbase = bootconfig.dram[i].address;
omapl1x_dma_ranges[i].dr_busbase = bootconfig.dram[i].address;
omapl1x_dma_ranges[i].dr_len = bootconfig.dram[i].pages *
PAGE_SIZE;
}
dmat = dma_tag_template;
dmat->_ranges = omapl1x_dma_ranges;
dmat->_nranges = bootconfig.dramblocks;
return dmat;
}
uint8_t
omapl1x_usbclk_enable(struct omapl1x_syscfg *syscfg)
{
uint32_t timeout;
volatile uint32_t phyclkgd, cfgchip2;
timeout = 0x3ffffff;
/*
* Write the key sequences to the KICKnR registers to unclock the
* access to the SYSCFG module registers
*/
bus_space_write_4(syscfg->syscfg_iot, syscfg->syscfg_ioh, KICK0R,
SYSCFG_KICK0R_KEY);
bus_space_write_4(syscfg->syscfg_iot, syscfg->syscfg_ioh, KICK1R,
SYSCFG_KICK1R_KEY);
cfgchip2 = bus_space_read_4(syscfg->syscfg_iot, syscfg->syscfg_ioh,
CFGCHIP2);
cfgchip2 &= ~USB0REF_FREQ;
cfgchip2 |= (USB0REF_FREQ_24M | USB0PHY_PLLON | USB1SUSPENDM |
USB0PHYCLKMUX | USB0VBDTCTEN | USB0SESNDEN);
cfgchip2 &= ~(USB0OTGMODE | USB0OTGPWDN | USB0PHYPWDN |
USB1PHYCLKMUX | RESET);
bus_space_write_4(syscfg->syscfg_iot, syscfg->syscfg_ioh, CFGCHIP2,
cfgchip2);
cfgchip2 = bus_space_read_4(syscfg->syscfg_iot, syscfg->syscfg_ioh,
CFGCHIP2);
do {
phyclkgd = bus_space_read_4(syscfg->syscfg_iot,
syscfg->syscfg_ioh, CFGCHIP2);
if (phyclkgd & USB0PHYCLKGD) {
return 1;
}
} while (--timeout);
return 0;
}
u_int64_t
omapl1x_get_tc_freq (void)
{
return (u_int64_t)OMAPL1X_TIMER3_FREQ;
}

View File

@ -0,0 +1,254 @@
/*
* Machine dependant startup code for OMAPL138 based Hawk board.
* Based on omap_start.S
*
*
* Copyright (c) 2002, 2003 Genetec Corporation. All rights reserved.
* Written by Hiroyuki Bessho for Genetec Corporation.
*
* 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 Genetec Corporation may not be used to endorse or
* promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``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 GENETEC CORPORATION
* 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.
*
* Copyright (c) 2003
* Ichiro FUKUHARA <ichiro@ichiro.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 ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD 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.
*
* Copyright (c) 2007 Microsoft
* 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 Microsoft
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTERS 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.
*/
/*
* Machine dependant startup code for OMAPL138 based Hawk board.
* Based on omap_start.S
*/
#include <machine/asm.h>
#include <arm/armreg.h>
#include "assym.h"
#include <arm/omap/omapl1x_reg.h>
#include <evbarm/hawk/hawk.h>
/*
* Kernel start routine for HAWK boards.
* At this point, this code has been loaded into the very beginning of SDRAM
* and the MMU is off, which implies the data cache is off.
*/
.section .start,"ax",%progbits
.global _C_LABEL(hawk_start)
_C_LABEL(hawk_start):
/*
* Save any arguments u-boot passed us.
*/
ldr r4, .Luboot_args
stmia r4, {r0-r3}
/* Move into supervisor mode and disable IRQs/FIQs. */
mrs r0, cpsr
bic r0, r0, #PSR_MODE
orr r0, r0, #(I32_bit | F32_bit | PSR_SVC32_MODE)
msr cpsr, r0
/*
* Set up a preliminary mapping in the MMU to allow us to run
* at KERNEL_BASE with caches on.
*/
/* Build page table from scratch */
ldr r0, Ltemp_l1_table
mov r1, r0 /* Save the page table address. */
/* Zero the entire table so all virtual addresses are invalid. */
mov r2, #L1_TABLE_SIZE /* in bytes */
mov r3, #0
mov r4, r3
mov r5, r3
mov r6, r3
mov r7, r3
mov r8, r3
mov r10, r3
mov r11, r3
1: stmia r1!, {r3-r8,r10-r11}
stmia r1!, {r3-r8,r10-r11}
stmia r1!, {r3-r8,r10-r11}
stmia r1!, {r3-r8,r10-r11}
subs r2, r2, #(4 * 4 * 8) /* bytes per loop */
bne 1b
/* Now create our entries per the mmu_init_table. */
l1table .req r0
va .req r1
pa .req r2
n_sec .req r3
attr .req r4
itable .req r5
l1sfrm .req r6
adr itable, mmu_init_table
ldr l1sfrm, Ll1_s_frame
b 3f
2: str pa, [l1table, va]
add va, va, #4
add pa, pa, #(L1_S_SIZE)
adds n_sec, n_sec, #-1
bhi 2b
3: ldmia itable!, {va,pa,n_sec,attr}
/* Convert va to l1 offset: va = 4 * (va >> L1_S_SHIFT) */
mov va, va, LSR #L1_S_SHIFT
mov va, va, LSL #2
/* Convert pa to l1 entry: pa = (pa & L1_S_FRAME) | attr */
and pa, pa, l1sfrm
orr pa, pa, attr
cmp n_sec, #0
bne 2b
.unreq va
.unreq pa
.unreq n_sec
.unreq attr
.unreq itable
.unreq l1table
.unreq l1sfrm
/*
* In theory, because the MMU is off, we shouldn't need all of this,
* but let's not take any chances and do a typical sequence to set
* the Translation Table Base.
*/
mcr p15, 0, r0, c7, c5, 0 /* Invalidate I cache */
1: mrc p15, 0, r15, c7, c14, 3 /* Test, clean, invalidate D cache. */
bne 1b
mcr p15, 0, r0, c7, c10, 4 /* Drain the write buffers. */
mcr p15, 0, r0, c2, c0, 0 /* Set Translation Table Base */
mcr p15, 0, r0, c8, c7, 0 /* Invalidate TLBs */
/* Set the Domain Access register. Very important! */
mov r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT)
mcr p15, 0, r0, c3, c0, 0
/*
* Enable the MMU.
*/
ldr r0, Lcpsr
mcr p15, 0, r0, c1, c0, 0
/*
* Ensure that the coprocessor has finished turning on the MMU.
*/
mrc p15, 0, r0, c2, c0, 0 /* Read an arbitrary value. */
mov r0, r0 /* Stall until read completes. */
/*
* Jump to start in locore.S, which in turn will call initarm and main.
*/
ldr pc, Lstart /* Jump to start (flushes pipeline). */
/* NOTREACHED */
.Luboot_args:
.word uboot_args
Lstart:
.word start
Ll1_s_frame:
.word L1_S_FRAME
Ltemp_l1_table:
/* Put the temporary L1 translation table at the end of SDRAM. */
.word OMAPL138_MEM_BASE + MEMSIZE_BYTES - L1_TABLE_SIZE
Lcpsr:
/* What we want to have the CPSR be when we jump to start. */
.word CPU_CONTROL_MMU_ENABLE | \
CPU_CONTROL_AFLT_ENABLE | \
CPU_CONTROL_DC_ENABLE | \
CPU_CONTROL_WBUF_ENABLE | \
CPU_CONTROL_32BP_ENABLE | \
CPU_CONTROL_32BD_ENABLE | \
CPU_CONTROL_LABT_ENABLE | \
CPU_CONTROL_SYST_ENABLE | \
CPU_CONTROL_IC_ENABLE
/* We'll modify va and pa at run time so we can use relocatable addresses. */
#define MMU_INIT(va,pa,n_sec,attr) \
.word va ; \
.word pa ; \
.word n_sec ; \
.word attr ;
mmu_init_table:
/* Map SDRAM where we're executing from VA==PA, read-only */
MMU_INIT(KERNEL_BASE_phys, KERNEL_BASE_phys,
1,
L1_S_PROTO | L1_S_AP_KR)
/* Map KERNEL_BASE VA to SDRAM PA, write-back cacheable */
MMU_INIT(KERNEL_BASE, OMAPL138_MEM_BASE,
(MEMSIZE_BYTES + L1_S_SIZE - 1) / L1_S_SIZE,
L1_S_PROTO | L1_S_AP_KRW | L1_S_B | L1_S_C)
/* Mapping to cover console */
MMU_INIT(OMAPL1X_KERNEL_IO_VBASE, OMAPL138_IO_BASE,
1,
L1_S_PROTO | L1_S_AP_KRW)
/* end of table */
MMU_INIT(0, 0, 0, 0)