1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-01 08:27:59 +00:00

Remove Atmel AT91RM9200 and AT91SAM9 support.

The last known robust version of this code base was FreeBSD 8.2. There
are no users of this on current, and all users of it have abandoned
this platform or are in legacy mode with a prior version of FreeBSD.

All known users on arm@ approved this removal, and there were no
objections.

Differential Revision: https://reviews.freebsd.org/D16312
This commit is contained in:
Warner Losh 2018-07-27 18:28:22 +00:00
parent de26ba4d82
commit 58d5c51106
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=336770
120 changed files with 1 additions and 25692 deletions

View File

@ -1,373 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2005 Olivier Houchard. All rights reserved.
* Copyright (c) 2010 Greg Ansley. 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 "opt_platform.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/module.h>
#include <sys/devmap.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <vm/pmap.h>
#include <vm/vm_page.h>
#include <vm/vm_extern.h>
#include <machine/armreg.h>
#define _ARM32_BUS_DMA_PRIVATE
#include <machine/bus.h>
#include <machine/intr.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91_pmcvar.h>
#include <arm/at91/at91_aicreg.h>
uint32_t at91_master_clock;
struct arm32_dma_range *
bus_dma_get_range(void)
{
return (NULL);
}
int
bus_dma_get_range_nb(void)
{
return (0);
}
#ifndef FDT
static struct at91_softc *at91_softc;
static void at91_eoi(void *);
static int
at91_probe(device_t dev)
{
device_set_desc(dev, soc_info.name);
return (BUS_PROBE_NOWILDCARD);
}
static void
at91_identify(driver_t *drv, device_t parent)
{
BUS_ADD_CHILD(parent, 0, "atmelarm", 0);
}
static void
at91_cpu_add_builtin_children(device_t dev, const struct cpu_devs *walker)
{
int i;
for (i = 0; walker->name; i++, walker++) {
at91_add_child(dev, i, walker->name, walker->unit,
walker->mem_base, walker->mem_len, walker->irq0,
walker->irq1, walker->irq2);
}
}
static int
at91_attach(device_t dev)
{
struct at91_softc *sc = device_get_softc(dev);
arm_post_filter = at91_eoi;
at91_softc = sc;
sc->sc_st = arm_base_bs_tag;
sc->sc_sh = AT91_BASE;
sc->sc_aic_sh = AT91_BASE + AT91_SYS_BASE;
sc->dev = dev;
sc->sc_irq_rman.rm_type = RMAN_ARRAY;
sc->sc_irq_rman.rm_descr = "AT91 IRQs";
if (rman_init(&sc->sc_irq_rman) != 0 ||
rman_manage_region(&sc->sc_irq_rman, 1, 31) != 0)
panic("at91_attach: failed to set up IRQ rman");
sc->sc_mem_rman.rm_type = RMAN_ARRAY;
sc->sc_mem_rman.rm_descr = "AT91 Memory";
if (rman_init(&sc->sc_mem_rman) != 0)
panic("at91_attach: failed to set up memory rman");
/*
* Manage the physical space, defined as being everything that isn't
* DRAM.
*/
if (rman_manage_region(&sc->sc_mem_rman, 0, PHYSADDR - 1) != 0)
panic("at91_attach: failed to set up memory rman");
if (rman_manage_region(&sc->sc_mem_rman, PHYSADDR + (256 << 20),
0xfffffffful) != 0)
panic("at91_attach: failed to set up memory rman");
/*
* Add this device's children...
*/
at91_cpu_add_builtin_children(dev, soc_info.soc_data->soc_children);
soc_info.soc_data->soc_clock_init();
bus_generic_probe(dev);
bus_generic_attach(dev);
enable_interrupts(PSR_I | PSR_F);
return (0);
}
static struct resource *
at91_alloc_resource(device_t dev, device_t child, int type, int *rid,
rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
{
struct at91_softc *sc = device_get_softc(dev);
struct resource_list_entry *rle;
struct at91_ivar *ivar = device_get_ivars(child);
struct resource_list *rl = &ivar->resources;
bus_space_handle_t bsh;
if (device_get_parent(child) != dev)
return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
type, rid, start, end, count, flags));
rle = resource_list_find(rl, type, *rid);
if (rle == NULL)
return (NULL);
if (rle->res)
panic("Resource rid %d type %d already in use", *rid, type);
if (RMAN_IS_DEFAULT_RANGE(start, end)) {
start = rle->start;
count = ulmax(count, rle->count);
end = ulmax(rle->end, start + count - 1);
}
switch (type)
{
case SYS_RES_IRQ:
rle->res = rman_reserve_resource(&sc->sc_irq_rman,
start, end, count, flags, child);
break;
case SYS_RES_MEMORY:
rle->res = rman_reserve_resource(&sc->sc_mem_rman,
start, end, count, flags, child);
if (rle->res != NULL) {
bus_space_map(arm_base_bs_tag, start,
rman_get_size(rle->res), 0, &bsh);
rman_set_bustag(rle->res, arm_base_bs_tag);
rman_set_bushandle(rle->res, bsh);
}
break;
}
if (rle->res) {
rle->start = rman_get_start(rle->res);
rle->end = rman_get_end(rle->res);
rle->count = count;
rman_set_rid(rle->res, *rid);
}
return (rle->res);
}
static struct resource_list *
at91_get_resource_list(device_t dev, device_t child)
{
struct at91_ivar *ivar;
ivar = device_get_ivars(child);
return (&(ivar->resources));
}
static int
at91_release_resource(device_t dev, device_t child, int type,
int rid, struct resource *r)
{
struct resource_list *rl;
struct resource_list_entry *rle;
rl = at91_get_resource_list(dev, child);
if (rl == NULL)
return (EINVAL);
rle = resource_list_find(rl, type, rid);
if (rle == NULL)
return (EINVAL);
rman_release_resource(r);
rle->res = NULL;
return (0);
}
static int
at91_setup_intr(device_t dev, device_t child,
struct resource *ires, int flags, driver_filter_t *filt,
driver_intr_t *intr, void *arg, void **cookiep)
{
int error;
if (rman_get_start(ires) == AT91_IRQ_SYSTEM && filt == NULL)
panic("All system interrupt ISRs must be FILTER");
error = BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags,
filt, intr, arg, cookiep);
if (error)
return (error);
return (0);
}
static int
at91_teardown_intr(device_t dev, device_t child, struct resource *res,
void *cookie)
{
struct at91_softc *sc = device_get_softc(dev);
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_IDCR,
1 << rman_get_start(res));
return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie));
}
static int
at91_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
#if 0
rman_res_t p;
int error;
if (type == SYS_RES_MEMORY) {
error = bus_space_map(rman_get_bustag(r),
rman_get_bushandle(r), rman_get_size(r), 0, &p);
if (error)
return (error);
rman_set_bushandle(r, p);
}
#endif
return (rman_activate_resource(r));
}
static int
at91_print_child(device_t dev, device_t child)
{
struct at91_ivar *ivars;
struct resource_list *rl;
int retval = 0;
ivars = device_get_ivars(child);
rl = &ivars->resources;
retval += bus_print_child_header(dev, child);
retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#jx");
retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx");
retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%jd");
if (device_get_flags(dev))
retval += printf(" flags %#x", device_get_flags(dev));
retval += bus_print_child_footer(dev, child);
return (retval);
}
static void
at91_eoi(void *unused)
{
bus_space_write_4(at91_softc->sc_st, at91_softc->sc_aic_sh,
IC_EOICR, 0);
}
void
at91_add_child(device_t dev, int prio, const char *name, int unit,
bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2)
{
device_t kid;
struct at91_ivar *ivar;
kid = device_add_child_ordered(dev, prio, name, unit);
if (kid == NULL) {
printf("Can't add child %s%d ordered\n", name, unit);
return;
}
ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
if (ivar == NULL) {
device_delete_child(dev, kid);
printf("Can't add alloc ivar\n");
return;
}
device_set_ivars(kid, ivar);
resource_list_init(&ivar->resources);
if (irq0 != -1) {
bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1);
if (irq0 != AT91_IRQ_SYSTEM)
at91_pmc_clock_add(device_get_nameunit(kid), irq0, 0);
}
if (irq1 != 0)
bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1);
if (irq2 != 0)
bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1);
/*
* Special case for on-board devices. These have their address
* defined relative to AT91_PA_BASE in all the register files we
* have. We could change this, but that's a lot of effort which
* will be obsoleted when FDT arrives.
*/
if (addr != 0 && addr < 0x10000000 && addr >= 0x0f000000)
addr += AT91_PA_BASE;
if (addr != 0)
bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
}
static device_method_t at91_methods[] = {
DEVMETHOD(device_probe, at91_probe),
DEVMETHOD(device_attach, at91_attach),
DEVMETHOD(device_identify, at91_identify),
DEVMETHOD(bus_alloc_resource, at91_alloc_resource),
DEVMETHOD(bus_setup_intr, at91_setup_intr),
DEVMETHOD(bus_teardown_intr, at91_teardown_intr),
DEVMETHOD(bus_activate_resource, at91_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_get_resource_list,at91_get_resource_list),
DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
DEVMETHOD(bus_release_resource, at91_release_resource),
DEVMETHOD(bus_print_child, at91_print_child),
{0, 0},
};
static driver_t at91_driver = {
"atmelarm",
at91_methods,
sizeof(struct at91_softc),
};
static devclass_t at91_devclass;
DRIVER_MODULE(atmelarm, nexus, at91_driver, at91_devclass, 0, 0);
#endif

View File

@ -1,184 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2014 M. Warner Losh.
*
* 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 "opt_platform.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/resource.h>
#include <sys/systm.h>
#include <sys/rman.h>
#include <machine/armreg.h>
#include <machine/bus.h>
#include <machine/frame.h>
#include <machine/intr.h>
#include <machine/resource.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91_aicreg.h>
#ifdef FDT
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#endif
static struct aic_softc {
struct resource *mem_res; /* Memory resource */
void *intrhand; /* Interrupt handle */
device_t sc_dev;
} *sc;
static inline uint32_t
RD4(struct aic_softc *sc, bus_size_t off)
{
return (bus_read_4(sc->mem_res, off));
}
static inline void
WR4(struct aic_softc *sc, bus_size_t off, uint32_t val)
{
bus_write_4(sc->mem_res, off, val);
}
void
arm_mask_irq(uintptr_t nb)
{
WR4(sc, IC_IDCR, 1 << nb);
}
int
arm_get_next_irq(int last __unused)
{
int status;
int irq;
irq = RD4(sc, IC_IVR);
status = RD4(sc, IC_ISR);
if (status == 0) {
WR4(sc, IC_EOICR, 1);
return (-1);
}
return (irq);
}
void
arm_unmask_irq(uintptr_t nb)
{
WR4(sc, IC_IECR, 1 << nb);
WR4(sc, IC_EOICR, 0);
}
static int
at91_aic_probe(device_t dev)
{
#ifdef FDT
if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-aic"))
return (ENXIO);
#endif
device_set_desc(dev, "AIC");
return (0);
}
static int
at91_aic_attach(device_t dev)
{
int i, rid, err = 0;
device_printf(dev, "Attach %d\n", bus_current_pass);
sc = device_get_softc(dev);
sc->sc_dev = dev;
rid = 0;
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (sc->mem_res == NULL)
panic("couldn't allocate register resources");
/*
* Setup the interrupt table.
*/
if (soc_info.soc_data == NULL || soc_info.soc_data->soc_irq_prio == NULL)
panic("Interrupt priority table missing\n");
for (i = 0; i < 32; i++) {
WR4(sc, IC_SVR + i * 4, i);
/* Priority. */
WR4(sc, IC_SMR + i * 4, soc_info.soc_data->soc_irq_prio[i]);
if (i < 8)
WR4(sc, IC_EOICR, 1);
}
WR4(sc, IC_SPU, 32);
/* No debug. */
WR4(sc, IC_DCR, 0);
/* Disable and clear all interrupts. */
WR4(sc, IC_IDCR, 0xffffffff);
WR4(sc, IC_ICCR, 0xffffffff);
enable_interrupts(PSR_I | PSR_F);
return (err);
}
static void
at91_aic_new_pass(device_t dev)
{
device_printf(dev, "Pass %d\n", bus_current_pass);
}
static device_method_t at91_aic_methods[] = {
DEVMETHOD(device_probe, at91_aic_probe),
DEVMETHOD(device_attach, at91_aic_attach),
DEVMETHOD(bus_new_pass, at91_aic_new_pass),
DEVMETHOD_END
};
static driver_t at91_aic_driver = {
"at91_aic",
at91_aic_methods,
sizeof(struct aic_softc),
};
static devclass_t at91_aic_devclass;
#ifdef FDT
EARLY_DRIVER_MODULE(at91_aic, simplebus, at91_aic_driver, at91_aic_devclass,
NULL, NULL, BUS_PASS_INTERRUPT);
#else
EARLY_DRIVER_MODULE(at91_aic, atmelarm, at91_aic_driver, at91_aic_devclass,
NULL, NULL, BUS_PASS_INTERRUPT);
#endif

View File

@ -1,53 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2009 Sylvestre Gallon. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* $FreeBSD$ */
#ifndef ARM_AT91_AT91_AICREG_H
#define ARM_AT91_AT91_AICREG_H
/* Interrupt Controller */
#define IC_SMR (0) /* Source mode register */
#define IC_SVR (128) /* Source vector register */
#define IC_IVR (256) /* IRQ vector register */
#define IC_FVR (260) /* FIQ vector register */
#define IC_ISR (264) /* Interrupt status register */
#define IC_IPR (268) /* Interrupt pending register */
#define IC_IMR (272) /* Interrupt status register */
#define IC_CISR (276) /* Core interrupt status register */
#define IC_IECR (288) /* Interrupt enable command register */
#define IC_IDCR (292) /* Interrupt disable command register */
#define IC_ICCR (296) /* Interrupt clear command register */
#define IC_ISCR (300) /* Interrupt set command register */
#define IC_EOICR (304) /* End of interrupt command register */
#define IC_SPU (308) /* Spurious vector register */
#define IC_DCR (312) /* Debug control register */
#define IC_FFER (320) /* Fast forcing enable register */
#define IC_FFDR (324) /* Fast forcing disable register */
#define IC_FFSR (328) /* Fast forcing status register */
#endif /*ARM_AT91_AT91_AICREG_H*/

View File

@ -1,281 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2008 Deglitch Networks, Stanislav Sedov
* 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.
*
* Driver for the AT91RM9200 CompactFlash controller operating in a
* common memory mode. Interrupts are driven by polling. The driver
* implements an ATA bridge and attached ATA channel driver on top
* of it.
* NOTE WELL: this driver uses polling mode. To achieve an acceptable
* operating speed you will probably want to use HZ=2000 in kernel
* config.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#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/sema.h>
#include <sys/taskqueue.h>
#include <vm/uma.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <sys/ata.h>
#include <dev/ata/ata-all.h>
#include <ata_if.h>
struct at91_cfata_softc {
device_t dev;
struct resource *mem_res;
struct resource irq;
void (*isr_cb)(void *);
void *isr_arg;
struct callout tick;
};
static int at91_cfata_detach(device_t dev);
static void at91_cfata_callout(void *arg);
static int
at91_cfata_probe(device_t dev)
{
device_set_desc_copy(dev, "AT91RM9200 CompactFlash controller");
return (0);
}
static int
at91_cfata_attach(device_t dev)
{
struct at91_cfata_softc *sc;
int rid, error;
sc = device_get_softc(dev);
sc->dev = dev;
rid = 0;
error = 0;
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (sc->mem_res == NULL)
return (ENOMEM);
/* XXX: init CF controller? */
callout_init(&sc->tick, 1); /* Callout to poll the device. */
device_add_child(dev, "ata", -1);
bus_generic_attach(dev);
return (0);
}
static int
at91_cfata_detach(device_t dev)
{
struct at91_cfata_softc *sc;
sc = device_get_softc(dev);
bus_generic_detach(sc->dev);
if (sc->mem_res != NULL) {
bus_release_resource(dev, SYS_RES_MEMORY,
rman_get_rid(sc->mem_res), sc->mem_res);
sc->mem_res = NULL;
}
return (0);
}
static struct resource *
ata_at91_alloc_resource(device_t dev, device_t child, int type, int *rid,
rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
{
struct at91_cfata_softc *sc = device_get_softc(dev);
KASSERT(type == SYS_RES_IRQ && *rid == ATA_IRQ_RID,
("[at91_cfata, %d]: illegal resource request (type %u rid %u)",
__LINE__, type, *rid));
return (&sc->irq);
}
static int
ata_at91_release_resource(device_t dev, device_t child, int type, int rid,
struct resource *r)
{
KASSERT(type == SYS_RES_IRQ && rid == ATA_IRQ_RID,
("[at91_cfata, %d]: illegal resource request (type %u rid %u)",
__LINE__, type, rid));
return (0);
}
static int
ata_at91_setup_intr(device_t dev, device_t child, struct resource *irq,
int flags, driver_filter_t *filt,
driver_intr_t *function, void *argument, void **cookiep)
{
struct at91_cfata_softc *sc = device_get_softc(dev);
KASSERT(sc->isr_cb == NULL,
("[at91_cfata, %d]: overwriting the old handler", __LINE__));
sc->isr_cb = function;
sc->isr_arg = argument;
*cookiep = sc;
callout_reset(&sc->tick, 1, at91_cfata_callout, sc);
return (0);
}
static int
ata_at91_teardown_intr(device_t dev, device_t child, struct resource *irq,
void *cookie)
{
struct at91_cfata_softc *sc = device_get_softc(dev);
sc->isr_cb = NULL;
sc->isr_arg = NULL;
return (0);
}
static void
at91_cfata_callout(void *arg)
{
struct at91_cfata_softc *sc;
sc = (struct at91_cfata_softc *)arg;
if (sc->isr_cb != NULL)
sc->isr_cb(sc->isr_arg);
callout_reset(&sc->tick, 1, at91_cfata_callout, sc);
}
static int
at91_channel_probe(device_t dev)
{
struct ata_channel *ch = device_get_softc(dev);
ch->unit = 0;
ch->flags |= ATA_USE_16BIT | ATA_NO_SLAVE;
device_set_desc_copy(dev, "ATA channel 0");
return (ata_probe(dev));
}
static int
at91_channel_attach(device_t dev)
{
struct at91_cfata_softc *sc = device_get_softc(device_get_parent(dev));
struct ata_channel *ch = device_get_softc(dev);
int i;
for (i = 0; i < ATA_MAX_RES; i++)
ch->r_io[i].res = sc->mem_res;
/*
* CF+ Specification.
* 6.1.3 Memory Mapped Addressing.
*/
ch->r_io[ATA_DATA].offset = 0x00;
ch->r_io[ATA_FEATURE].offset = 0x01;
ch->r_io[ATA_COUNT].offset = 0x02;
ch->r_io[ATA_SECTOR].offset = 0x03;
ch->r_io[ATA_CYL_LSB].offset = 0x04;
ch->r_io[ATA_CYL_MSB].offset = 0x05;
ch->r_io[ATA_DRIVE].offset = 0x06;
ch->r_io[ATA_COMMAND].offset = 0x07;
ch->r_io[ATA_ERROR].offset = 0x01;
ch->r_io[ATA_IREASON].offset = 0x02;
ch->r_io[ATA_STATUS].offset = 0x07;
ch->r_io[ATA_ALTSTAT].offset = 0x0e;
ch->r_io[ATA_CONTROL].offset = 0x0e;
/* Should point at the base of registers. */
ch->r_io[ATA_IDX_ADDR].offset = 0x0;
ata_generic_hw(dev);
return (ata_attach(dev));
}
static device_method_t at91_cfata_methods[] = {
/* Device interface. */
DEVMETHOD(device_probe, at91_cfata_probe),
DEVMETHOD(device_attach, at91_cfata_attach),
DEVMETHOD(device_detach, at91_cfata_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
/* ATA bus methods. */
DEVMETHOD(bus_alloc_resource, ata_at91_alloc_resource),
DEVMETHOD(bus_release_resource, ata_at91_release_resource),
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
DEVMETHOD(bus_deactivate_resource,
bus_generic_deactivate_resource),
DEVMETHOD(bus_setup_intr, ata_at91_setup_intr),
DEVMETHOD(bus_teardown_intr, ata_at91_teardown_intr),
{ 0, 0 }
};
devclass_t at91_cfata_devclass;
static driver_t at91_cfata_driver = {
"at91_cfata",
at91_cfata_methods,
sizeof(struct at91_cfata_softc),
};
DRIVER_MODULE(at91_cfata, atmelarm, at91_cfata_driver, at91_cfata_devclass, 0,
0);
MODULE_VERSION(at91_cfata, 1);
MODULE_DEPEND(at91_cfata, ata, 1, 1, 1);
/*
* ATA channel driver.
*/
static device_method_t at91_channel_methods[] = {
/* device interface */
DEVMETHOD(device_probe, at91_channel_probe),
DEVMETHOD(device_attach, at91_channel_attach),
DEVMETHOD(device_detach, ata_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, ata_suspend),
DEVMETHOD(device_resume, ata_resume),
{ 0, 0 }
};
driver_t at91_channel_driver = {
"ata",
at91_channel_methods,
sizeof(struct ata_channel),
};
DRIVER_MODULE(ata, at91_cfata, at91_channel_driver, ata_devclass, 0, 0);

View File

@ -1,121 +0,0 @@
/*-
* Copyright (c) 2014 M. Warner Losh.
*
* 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$");
#define _ARM32_BUS_DMA_PRIVATE
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/devmap.h>
#include <vm/vm.h>
#include <machine/intr.h>
#include <machine/machdep.h>
#include <machine/platform.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91soc.h>
#include <arm/at91/at91_aicreg.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <machine/fdt.h>
extern const struct devmap_entry at91_devmap[];
#ifndef INTRNG
static int
fdt_aic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
int *pol)
{
int offset;
if (ofw_bus_node_is_compatible(node, "atmel,at91rm9200-aic"))
offset = 0;
else
return (ENXIO);
*interrupt = fdt32_to_cpu(intr[0]) + offset;
*trig = INTR_TRIGGER_CONFORM;
*pol = INTR_POLARITY_CONFORM;
return (0);
}
fdt_pic_decode_t fdt_pic_table[] = {
&fdt_aic_decode_ic,
NULL
};
#endif
static void
at91_eoi(void *unused)
{
uint32_t *eoicr = (uint32_t *)(0xdffff000 + IC_EOICR);
*eoicr = 0;
}
vm_offset_t
platform_lastaddr(void)
{
return (devmap_lastaddr());
}
void
platform_probe_and_attach(void)
{
arm_post_filter = at91_eoi;
at91_soc_id();
}
int
platform_devmap_init(void)
{
// devmap_add_entry(0xfff00000, 0x00100000); /* 1MB - uart, aic and timers*/
devmap_register_table(at91_devmap);
return (0);
}
void
platform_gpio_init(void)
{
}
void
platform_late_init(void)
{
}

View File

@ -1,298 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2014 M. Warner Losh.
*
* 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 ARM_AT91_AT91_GPIO_H
#define ARM_AT91_AT91_GPIO_H
typedef uint32_t at91_pin_t;
#define AT91_PIN_NONE 0xfffffffful /* No pin / Not GPIO controlled */
/*
* Map Atmel PIO pins to a unique number. They are just numbered sequentially.
*/
#define AT91_PIN_PA0 (at91_pin_t)0
#define AT91_PIN_PA1 (at91_pin_t)1
#define AT91_PIN_PA2 (at91_pin_t)2
#define AT91_PIN_PA3 (at91_pin_t)3
#define AT91_PIN_PA4 (at91_pin_t)4
#define AT91_PIN_PA5 (at91_pin_t)5
#define AT91_PIN_PA6 (at91_pin_t)6
#define AT91_PIN_PA7 (at91_pin_t)7
#define AT91_PIN_PA8 (at91_pin_t)8
#define AT91_PIN_PA9 (at91_pin_t)9
#define AT91_PIN_PA10 (at91_pin_t)10
#define AT91_PIN_PA11 (at91_pin_t)11
#define AT91_PIN_PA12 (at91_pin_t)12
#define AT91_PIN_PA13 (at91_pin_t)13
#define AT91_PIN_PA14 (at91_pin_t)14
#define AT91_PIN_PA15 (at91_pin_t)15
#define AT91_PIN_PA16 (at91_pin_t)16
#define AT91_PIN_PA17 (at91_pin_t)17
#define AT91_PIN_PA18 (at91_pin_t)18
#define AT91_PIN_PA19 (at91_pin_t)19
#define AT91_PIN_PA20 (at91_pin_t)20
#define AT91_PIN_PA21 (at91_pin_t)21
#define AT91_PIN_PA22 (at91_pin_t)22
#define AT91_PIN_PA23 (at91_pin_t)23
#define AT91_PIN_PA24 (at91_pin_t)24
#define AT91_PIN_PA25 (at91_pin_t)25
#define AT91_PIN_PA26 (at91_pin_t)26
#define AT91_PIN_PA27 (at91_pin_t)27
#define AT91_PIN_PA28 (at91_pin_t)28
#define AT91_PIN_PA29 (at91_pin_t)29
#define AT91_PIN_PA30 (at91_pin_t)30
#define AT91_PIN_PA31 (at91_pin_t)31
#define AT91_PIN_PB0 (at91_pin_t)32
#define AT91_PIN_PB1 (at91_pin_t)33
#define AT91_PIN_PB2 (at91_pin_t)34
#define AT91_PIN_PB3 (at91_pin_t)35
#define AT91_PIN_PB4 (at91_pin_t)36
#define AT91_PIN_PB5 (at91_pin_t)37
#define AT91_PIN_PB6 (at91_pin_t)38
#define AT91_PIN_PB7 (at91_pin_t)39
#define AT91_PIN_PB8 (at91_pin_t)40
#define AT91_PIN_PB9 (at91_pin_t)41
#define AT91_PIN_PB10 (at91_pin_t)42
#define AT91_PIN_PB11 (at91_pin_t)43
#define AT91_PIN_PB12 (at91_pin_t)44
#define AT91_PIN_PB13 (at91_pin_t)45
#define AT91_PIN_PB14 (at91_pin_t)46
#define AT91_PIN_PB15 (at91_pin_t)47
#define AT91_PIN_PB16 (at91_pin_t)48
#define AT91_PIN_PB17 (at91_pin_t)49
#define AT91_PIN_PB18 (at91_pin_t)50
#define AT91_PIN_PB19 (at91_pin_t)51
#define AT91_PIN_PB20 (at91_pin_t)52
#define AT91_PIN_PB21 (at91_pin_t)53
#define AT91_PIN_PB22 (at91_pin_t)54
#define AT91_PIN_PB23 (at91_pin_t)55
#define AT91_PIN_PB24 (at91_pin_t)56
#define AT91_PIN_PB25 (at91_pin_t)57
#define AT91_PIN_PB26 (at91_pin_t)58
#define AT91_PIN_PB27 (at91_pin_t)59
#define AT91_PIN_PB28 (at91_pin_t)60
#define AT91_PIN_PB29 (at91_pin_t)61
#define AT91_PIN_PB30 (at91_pin_t)62
#define AT91_PIN_PB31 (at91_pin_t)63
#define AT91_PIN_PC0 (at91_pin_t)64
#define AT91_PIN_PC1 (at91_pin_t)65
#define AT91_PIN_PC2 (at91_pin_t)66
#define AT91_PIN_PC3 (at91_pin_t)67
#define AT91_PIN_PC4 (at91_pin_t)68
#define AT91_PIN_PC5 (at91_pin_t)69
#define AT91_PIN_PC6 (at91_pin_t)70
#define AT91_PIN_PC7 (at91_pin_t)71
#define AT91_PIN_PC8 (at91_pin_t)72
#define AT91_PIN_PC9 (at91_pin_t)73
#define AT91_PIN_PC10 (at91_pin_t)74
#define AT91_PIN_PC11 (at91_pin_t)75
#define AT91_PIN_PC12 (at91_pin_t)76
#define AT91_PIN_PC13 (at91_pin_t)77
#define AT91_PIN_PC14 (at91_pin_t)78
#define AT91_PIN_PC15 (at91_pin_t)79
#define AT91_PIN_PC16 (at91_pin_t)80
#define AT91_PIN_PC17 (at91_pin_t)81
#define AT91_PIN_PC18 (at91_pin_t)82
#define AT91_PIN_PC19 (at91_pin_t)83
#define AT91_PIN_PC20 (at91_pin_t)84
#define AT91_PIN_PC21 (at91_pin_t)85
#define AT91_PIN_PC22 (at91_pin_t)86
#define AT91_PIN_PC23 (at91_pin_t)87
#define AT91_PIN_PC24 (at91_pin_t)88
#define AT91_PIN_PC25 (at91_pin_t)89
#define AT91_PIN_PC26 (at91_pin_t)90
#define AT91_PIN_PC27 (at91_pin_t)91
#define AT91_PIN_PC28 (at91_pin_t)92
#define AT91_PIN_PC29 (at91_pin_t)93
#define AT91_PIN_PC30 (at91_pin_t)94
#define AT91_PIN_PC31 (at91_pin_t)95
#define AT91_PIN_PD0 (at91_pin_t)96
#define AT91_PIN_PD1 (at91_pin_t)97
#define AT91_PIN_PD2 (at91_pin_t)98
#define AT91_PIN_PD3 (at91_pin_t)99
#define AT91_PIN_PD4 (at91_pin_t)100
#define AT91_PIN_PD5 (at91_pin_t)101
#define AT91_PIN_PD6 (at91_pin_t)102
#define AT91_PIN_PD7 (at91_pin_t)103
#define AT91_PIN_PD8 (at91_pin_t)104
#define AT91_PIN_PD9 (at91_pin_t)105
#define AT91_PIN_PD10 (at91_pin_t)106
#define AT91_PIN_PD11 (at91_pin_t)107
#define AT91_PIN_PD12 (at91_pin_t)108
#define AT91_PIN_PD13 (at91_pin_t)109
#define AT91_PIN_PD14 (at91_pin_t)110
#define AT91_PIN_PD15 (at91_pin_t)111
#define AT91_PIN_PD16 (at91_pin_t)112
#define AT91_PIN_PD17 (at91_pin_t)113
#define AT91_PIN_PD18 (at91_pin_t)114
#define AT91_PIN_PD19 (at91_pin_t)115
#define AT91_PIN_PD20 (at91_pin_t)116
#define AT91_PIN_PD21 (at91_pin_t)117
#define AT91_PIN_PD22 (at91_pin_t)118
#define AT91_PIN_PD23 (at91_pin_t)119
#define AT91_PIN_PD24 (at91_pin_t)120
#define AT91_PIN_PD25 (at91_pin_t)121
#define AT91_PIN_PD26 (at91_pin_t)122
#define AT91_PIN_PD27 (at91_pin_t)123
#define AT91_PIN_PD28 (at91_pin_t)124
#define AT91_PIN_PD29 (at91_pin_t)125
#define AT91_PIN_PD30 (at91_pin_t)126
#define AT91_PIN_PD31 (at91_pin_t)127
#define AT91_PIN_PE0 (at91_pin_t)128
#define AT91_PIN_PE1 (at91_pin_t)129
#define AT91_PIN_PE2 (at91_pin_t)130
#define AT91_PIN_PE3 (at91_pin_t)131
#define AT91_PIN_PE4 (at91_pin_t)132
#define AT91_PIN_PE5 (at91_pin_t)133
#define AT91_PIN_PE6 (at91_pin_t)134
#define AT91_PIN_PE7 (at91_pin_t)135
#define AT91_PIN_PE8 (at91_pin_t)136
#define AT91_PIN_PE9 (at91_pin_t)137
#define AT91_PIN_PE10 (at91_pin_t)138
#define AT91_PIN_PE11 (at91_pin_t)139
#define AT91_PIN_PE12 (at91_pin_t)140
#define AT91_PIN_PE13 (at91_pin_t)141
#define AT91_PIN_PE14 (at91_pin_t)142
#define AT91_PIN_PE15 (at91_pin_t)143
#define AT91_PIN_PE16 (at91_pin_t)144
#define AT91_PIN_PE17 (at91_pin_t)145
#define AT91_PIN_PE18 (at91_pin_t)146
#define AT91_PIN_PE19 (at91_pin_t)147
#define AT91_PIN_PE20 (at91_pin_t)148
#define AT91_PIN_PE21 (at91_pin_t)149
#define AT91_PIN_PE22 (at91_pin_t)150
#define AT91_PIN_PE23 (at91_pin_t)151
#define AT91_PIN_PE24 (at91_pin_t)152
#define AT91_PIN_PE25 (at91_pin_t)153
#define AT91_PIN_PE26 (at91_pin_t)154
#define AT91_PIN_PE27 (at91_pin_t)155
#define AT91_PIN_PE28 (at91_pin_t)156
#define AT91_PIN_PE29 (at91_pin_t)157
#define AT91_PIN_PE30 (at91_pin_t)158
#define AT91_PIN_PE31 (at91_pin_t)159
#define AT91_PIN_PF0 (at91_pin_t)160
#define AT91_PIN_PF1 (at91_pin_t)161
#define AT91_PIN_PF2 (at91_pin_t)162
#define AT91_PIN_PF3 (at91_pin_t)163
#define AT91_PIN_PF4 (at91_pin_t)164
#define AT91_PIN_PF5 (at91_pin_t)165
#define AT91_PIN_PF6 (at91_pin_t)166
#define AT91_PIN_PF7 (at91_pin_t)167
#define AT91_PIN_PF8 (at91_pin_t)168
#define AT91_PIN_PF9 (at91_pin_t)169
#define AT91_PIN_PF10 (at91_pin_t)170
#define AT91_PIN_PF11 (at91_pin_t)171
#define AT91_PIN_PF12 (at91_pin_t)172
#define AT91_PIN_PF13 (at91_pin_t)173
#define AT91_PIN_PF14 (at91_pin_t)174
#define AT91_PIN_PF15 (at91_pin_t)175
#define AT91_PIN_PF16 (at91_pin_t)176
#define AT91_PIN_PF17 (at91_pin_t)177
#define AT91_PIN_PF18 (at91_pin_t)178
#define AT91_PIN_PF19 (at91_pin_t)179
#define AT91_PIN_PF20 (at91_pin_t)180
#define AT91_PIN_PF21 (at91_pin_t)181
#define AT91_PIN_PF22 (at91_pin_t)182
#define AT91_PIN_PF23 (at91_pin_t)183
#define AT91_PIN_PF24 (at91_pin_t)184
#define AT91_PIN_PF25 (at91_pin_t)185
#define AT91_PIN_PF26 (at91_pin_t)186
#define AT91_PIN_PF27 (at91_pin_t)187
#define AT91_PIN_PF28 (at91_pin_t)188
#define AT91_PIN_PF29 (at91_pin_t)189
#define AT91_PIN_PF30 (at91_pin_t)190
#define AT91_PIN_PF31 (at91_pin_t)191
#define AT91_PIN_PG0 (at91_pin_t)192
#define AT91_PIN_PG1 (at91_pin_t)193
#define AT91_PIN_PG2 (at91_pin_t)194
#define AT91_PIN_PG3 (at91_pin_t)195
#define AT91_PIN_PG4 (at91_pin_t)196
#define AT91_PIN_PG5 (at91_pin_t)197
#define AT91_PIN_PG6 (at91_pin_t)198
#define AT91_PIN_PG7 (at91_pin_t)199
#define AT91_PIN_PG8 (at91_pin_t)200
#define AT91_PIN_PG9 (at91_pin_t)201
#define AT91_PIN_PG10 (at91_pin_t)202
#define AT91_PIN_PG11 (at91_pin_t)203
#define AT91_PIN_PG12 (at91_pin_t)204
#define AT91_PIN_PG13 (at91_pin_t)205
#define AT91_PIN_PG14 (at91_pin_t)206
#define AT91_PIN_PG15 (at91_pin_t)207
#define AT91_PIN_PG16 (at91_pin_t)208
#define AT91_PIN_PG17 (at91_pin_t)209
#define AT91_PIN_PG18 (at91_pin_t)210
#define AT91_PIN_PG19 (at91_pin_t)211
#define AT91_PIN_PG20 (at91_pin_t)212
#define AT91_PIN_PG21 (at91_pin_t)213
#define AT91_PIN_PG22 (at91_pin_t)214
#define AT91_PIN_PG23 (at91_pin_t)215
#define AT91_PIN_PG24 (at91_pin_t)216
#define AT91_PIN_PG25 (at91_pin_t)217
#define AT91_PIN_PG26 (at91_pin_t)218
#define AT91_PIN_PG27 (at91_pin_t)219
#define AT91_PIN_PG28 (at91_pin_t)220
#define AT91_PIN_PG29 (at91_pin_t)221
#define AT91_PIN_PG30 (at91_pin_t)222
#define AT91_PIN_PG31 (at91_pin_t)223
#define AT91_PIN_PH0 (at91_pin_t)224
#define AT91_PIN_PH1 (at91_pin_t)225
#define AT91_PIN_PH2 (at91_pin_t)226
#define AT91_PIN_PH3 (at91_pin_t)227
#define AT91_PIN_PH4 (at91_pin_t)228
#define AT91_PIN_PH5 (at91_pin_t)229
#define AT91_PIN_PH6 (at91_pin_t)230
#define AT91_PIN_PH7 (at91_pin_t)231
#define AT91_PIN_PH8 (at91_pin_t)232
#define AT91_PIN_PH9 (at91_pin_t)233
#define AT91_PIN_PH10 (at91_pin_t)234
#define AT91_PIN_PH11 (at91_pin_t)235
#define AT91_PIN_PH12 (at91_pin_t)236
#define AT91_PIN_PH13 (at91_pin_t)237
#define AT91_PIN_PH14 (at91_pin_t)238
#define AT91_PIN_PH15 (at91_pin_t)239
#define AT91_PIN_PH16 (at91_pin_t)240
#define AT91_PIN_PH17 (at91_pin_t)241
#define AT91_PIN_PH18 (at91_pin_t)242
#define AT91_PIN_PH19 (at91_pin_t)243
#define AT91_PIN_PH20 (at91_pin_t)244
#define AT91_PIN_PH21 (at91_pin_t)245
#define AT91_PIN_PH22 (at91_pin_t)246
#define AT91_PIN_PH23 (at91_pin_t)247
#define AT91_PIN_PH24 (at91_pin_t)248
#define AT91_PIN_PH25 (at91_pin_t)249
#define AT91_PIN_PH26 (at91_pin_t)250
#define AT91_PIN_PH27 (at91_pin_t)251
#define AT91_PIN_PH28 (at91_pin_t)252
#define AT91_PIN_PH29 (at91_pin_t)253
#define AT91_PIN_PH30 (at91_pin_t)254
#define AT91_PIN_PH31 (at91_pin_t)255
#endif /* ARM_AT91_AT91_GPIO_H */

View File

@ -1,689 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* 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.
*
* RiscBSD kernel project
*
* machdep.c
*
* Machine dependent functions for kernel setup
*
* This file needs a lot of work.
*
* Created : 17/09/94
*/
#include "opt_kstack_pages.h"
#include "opt_platform.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#define _ARM32_BUS_DMA_PRIVATE
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/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 <sys/devmap.h>
#include <machine/physmem.h>
#include <machine/reg.h>
#include <machine/cpu.h>
#include <machine/board.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_map.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/at91/at91board.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91soc.h>
#include <arm/at91/at91_usartreg.h>
#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91sam9g20reg.h>
#include <arm/at91/at91sam9g45reg.h>
#ifndef MAXCPU
#define MAXCPU 1
#endif
/* Page table for mapping proc0 zero page */
#define KERNEL_PT_SYS 0
#define KERNEL_PT_KERN 1
#define KERNEL_PT_KERN_NUM 22
/* L2 table for mapping after kernel */
#define KERNEL_PT_AFKERNEL KERNEL_PT_KERN + KERNEL_PT_KERN_NUM
#define KERNEL_PT_AFKERNEL_NUM 5
/* this should be evenly divisable by PAGE_SIZE / L2_TABLE_SIZE_REAL (or 4) */
#define NUM_KERNEL_PTS (KERNEL_PT_AFKERNEL + KERNEL_PT_AFKERNEL_NUM)
struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
/* Static device mappings. */
const struct devmap_entry at91_devmap[] = {
/*
* Map the critical on-board devices. The interrupt vector at
* 0xffff0000 makes it impossible to map them PA == VA, so we map all
* 0xfffxxxxx addresses to 0xdffxxxxx. This covers all critical devices
* on all members of the AT91SAM9 and AT91RM9200 families.
*/
{
0xdff00000,
0xfff00000,
0x00100000,
},
/* There's a notion that we should do the rest of these lazily. */
/*
* We can't just map the OHCI registers VA == PA, because
* AT91xx_xxx_BASE belongs to the userland address space.
* We could just choose a different virtual address, but a better
* solution would probably be to just use pmap_mapdev() to allocate
* KVA, as we don't need the OHCI controller before the vm
* initialization is done. However, the AT91 resource allocation
* system doesn't know how to use pmap_mapdev() yet.
* Care must be taken to ensure PA and VM address do not overlap
* between entries.
*/
{
/*
* Add the ohci controller, and anything else that might be
* on this chip select for a VA/PA mapping.
*/
/* Internal Memory 1MB */
AT91RM92_OHCI_VA_BASE,
AT91RM92_OHCI_BASE,
0x00100000,
},
{
/* CompactFlash controller. Portion of EBI CS4 1MB */
AT91RM92_CF_VA_BASE,
AT91RM92_CF_BASE,
0x00100000,
},
/*
* The next two should be good for the 9260, 9261 and 9G20 since
* addresses mapping is the same.
*/
{
/* Internal Memory 1MB */
AT91SAM9G20_OHCI_VA_BASE,
AT91SAM9G20_OHCI_BASE,
0x00100000,
},
{
/* EBI CS3 256MB */
AT91SAM9G20_NAND_VA_BASE,
AT91SAM9G20_NAND_BASE,
AT91SAM9G20_NAND_SIZE,
},
/*
* The next should be good for the 9G45.
*/
{
/* Internal Memory 1MB */
AT91SAM9G45_OHCI_VA_BASE,
AT91SAM9G45_OHCI_BASE,
0x00100000,
},
{ 0, 0, 0, }
};
#ifdef LINUX_BOOT_ABI
static int membanks;
static int memsize[];
#endif
long
at91_ramsize(void)
{
uint32_t cr, mdr, mr, *SDRAMC;
int banks, rows, cols, bw;
#ifdef LINUX_BOOT_ABI
/*
* If we found any ATAGs that were for memory, return the first bank.
*/
if (membanks > 0)
return (memsize[0]);
#endif
if (at91_is_rm92()) {
SDRAMC = (uint32_t *)(AT91_BASE + AT91RM92_SDRAMC_BASE);
cr = SDRAMC[AT91RM92_SDRAMC_CR / 4];
mr = SDRAMC[AT91RM92_SDRAMC_MR / 4];
banks = (cr & AT91RM92_SDRAMC_CR_NB_4) ? 2 : 1;
rows = ((cr & AT91RM92_SDRAMC_CR_NR_MASK) >> 2) + 11;
cols = (cr & AT91RM92_SDRAMC_CR_NC_MASK) + 8;
bw = (mr & AT91RM92_SDRAMC_MR_DBW_16) ? 1 : 2;
} else if (at91_cpu_is(AT91_T_SAM9G45)) {
SDRAMC = (uint32_t *)(AT91_BASE + AT91SAM9G45_DDRSDRC0_BASE);
cr = SDRAMC[AT91SAM9G45_DDRSDRC_CR / 4];
mdr = SDRAMC[AT91SAM9G45_DDRSDRC_MDR / 4];
banks = 0;
rows = ((cr & AT91SAM9G45_DDRSDRC_CR_NR_MASK) >> 2) + 11;
cols = (cr & AT91SAM9G45_DDRSDRC_CR_NC_MASK) + 8;
bw = (mdr & AT91SAM9G45_DDRSDRC_MDR_DBW_16) ? 1 : 2;
/* Fix the calculation for DDR memory */
mdr &= AT91SAM9G45_DDRSDRC_MDR_MASK;
if (mdr & AT91SAM9G45_DDRSDRC_MDR_LPDDR1 ||
mdr & AT91SAM9G45_DDRSDRC_MDR_DDR2) {
/* The cols value is 1 higher for DDR */
cols += 1;
/* DDR has 4 internal banks. */
banks = 2;
}
} else {
/*
* This should be good for the 9260, 9261, 9G20, 9G35 and 9X25
* as addresses and registers are the same.
*/
SDRAMC = (uint32_t *)(AT91_BASE + AT91SAM9G20_SDRAMC_BASE);
cr = SDRAMC[AT91SAM9G20_SDRAMC_CR / 4];
mr = SDRAMC[AT91SAM9G20_SDRAMC_MR / 4];
banks = (cr & AT91SAM9G20_SDRAMC_CR_NB_4) ? 2 : 1;
rows = ((cr & AT91SAM9G20_SDRAMC_CR_NR_MASK) >> 2) + 11;
cols = (cr & AT91SAM9G20_SDRAMC_CR_NC_MASK) + 8;
bw = (cr & AT91SAM9G20_SDRAMC_CR_DBW_16) ? 1 : 2;
}
return (1 << (cols + rows + banks + bw));
}
static const char *soc_type_name[] = {
[AT91_T_CAP9] = "at91cap9",
[AT91_T_RM9200] = "at91rm9200",
[AT91_T_SAM9260] = "at91sam9260",
[AT91_T_SAM9261] = "at91sam9261",
[AT91_T_SAM9263] = "at91sam9263",
[AT91_T_SAM9G10] = "at91sam9g10",
[AT91_T_SAM9G20] = "at91sam9g20",
[AT91_T_SAM9G45] = "at91sam9g45",
[AT91_T_SAM9N12] = "at91sam9n12",
[AT91_T_SAM9RL] = "at91sam9rl",
[AT91_T_SAM9X5] = "at91sam9x5",
[AT91_T_NONE] = "UNKNOWN"
};
static const char *soc_subtype_name[] = {
[AT91_ST_NONE] = "UNKNOWN",
[AT91_ST_RM9200_BGA] = "at91rm9200_bga",
[AT91_ST_RM9200_PQFP] = "at91rm9200_pqfp",
[AT91_ST_SAM9XE] = "at91sam9xe",
[AT91_ST_SAM9G45] = "at91sam9g45",
[AT91_ST_SAM9M10] = "at91sam9m10",
[AT91_ST_SAM9G46] = "at91sam9g46",
[AT91_ST_SAM9M11] = "at91sam9m11",
[AT91_ST_SAM9G15] = "at91sam9g15",
[AT91_ST_SAM9G25] = "at91sam9g25",
[AT91_ST_SAM9G35] = "at91sam9g35",
[AT91_ST_SAM9X25] = "at91sam9x25",
[AT91_ST_SAM9X35] = "at91sam9x35",
};
struct at91_soc_info soc_info;
/*
* Read the SoC ID from the CIDR register and try to match it against the
* values we know. If we find a good one, we return true. If not, we
* return false. When we find a good one, we also find the subtype
* and CPU family.
*/
static int
at91_try_id(uint32_t dbgu_base)
{
uint32_t socid;
soc_info.cidr = *(volatile uint32_t *)(AT91_BASE + dbgu_base +
DBGU_C1R);
socid = soc_info.cidr & ~AT91_CPU_VERSION_MASK;
soc_info.type = AT91_T_NONE;
soc_info.subtype = AT91_ST_NONE;
soc_info.family = (soc_info.cidr & AT91_CPU_FAMILY_MASK) >> 20;
soc_info.exid = *(volatile uint32_t *)(AT91_BASE + dbgu_base +
DBGU_C2R);
switch (socid) {
case AT91_CPU_CAP9:
soc_info.type = AT91_T_CAP9;
break;
case AT91_CPU_RM9200:
soc_info.type = AT91_T_RM9200;
break;
case AT91_CPU_SAM9XE128:
case AT91_CPU_SAM9XE256:
case AT91_CPU_SAM9XE512:
case AT91_CPU_SAM9260:
soc_info.type = AT91_T_SAM9260;
if (soc_info.family == AT91_FAMILY_SAM9XE)
soc_info.subtype = AT91_ST_SAM9XE;
break;
case AT91_CPU_SAM9261:
soc_info.type = AT91_T_SAM9261;
break;
case AT91_CPU_SAM9263:
soc_info.type = AT91_T_SAM9263;
break;
case AT91_CPU_SAM9G10:
soc_info.type = AT91_T_SAM9G10;
break;
case AT91_CPU_SAM9G20:
soc_info.type = AT91_T_SAM9G20;
break;
case AT91_CPU_SAM9G45:
soc_info.type = AT91_T_SAM9G45;
break;
case AT91_CPU_SAM9N12:
soc_info.type = AT91_T_SAM9N12;
break;
case AT91_CPU_SAM9RL64:
soc_info.type = AT91_T_SAM9RL;
break;
case AT91_CPU_SAM9X5:
soc_info.type = AT91_T_SAM9X5;
break;
default:
return (0);
}
switch (soc_info.type) {
case AT91_T_SAM9G45:
switch (soc_info.exid) {
case AT91_EXID_SAM9G45:
soc_info.subtype = AT91_ST_SAM9G45;
break;
case AT91_EXID_SAM9G46:
soc_info.subtype = AT91_ST_SAM9G46;
break;
case AT91_EXID_SAM9M10:
soc_info.subtype = AT91_ST_SAM9M10;
break;
case AT91_EXID_SAM9M11:
soc_info.subtype = AT91_ST_SAM9M11;
break;
}
break;
case AT91_T_SAM9X5:
switch (soc_info.exid) {
case AT91_EXID_SAM9G15:
soc_info.subtype = AT91_ST_SAM9G15;
break;
case AT91_EXID_SAM9G25:
soc_info.subtype = AT91_ST_SAM9G25;
break;
case AT91_EXID_SAM9G35:
soc_info.subtype = AT91_ST_SAM9G35;
break;
case AT91_EXID_SAM9X25:
soc_info.subtype = AT91_ST_SAM9X25;
break;
case AT91_EXID_SAM9X35:
soc_info.subtype = AT91_ST_SAM9X35;
break;
}
break;
default:
break;
}
/*
* Disable interrupts in the DBGU unit...
*/
*(volatile uint32_t *)(AT91_BASE + dbgu_base + USART_IDR) = 0xffffffff;
/*
* Save the name for later...
*/
snprintf(soc_info.name, sizeof(soc_info.name), "%s%s%s",
soc_type_name[soc_info.type],
soc_info.subtype == AT91_ST_NONE ? "" : " subtype ",
soc_info.subtype == AT91_ST_NONE ? "" :
soc_subtype_name[soc_info.subtype]);
/*
* try to get the matching CPU support.
*/
soc_info.soc_data = at91_match_soc(soc_info.type, soc_info.subtype);
soc_info.dbgu_base = AT91_BASE + dbgu_base;
return (1);
}
void
at91_soc_id(void)
{
if (!at91_try_id(AT91_DBGU0))
at91_try_id(AT91_DBGU1);
}
#ifdef ARM_MANY_BOARD
/* likely belongs in arm/arm/machdep.c, but since board_init is still at91 only... */
SET_DECLARE(arm_board_set, const struct arm_board);
/* Not yet fully functional, but enough to build ATMEL config */
static long
board_init(void)
{
return -1;
}
#endif
#ifndef FDT
/* Physical and virtual addresses for some global pages */
struct pv_addr msgbufpv;
struct pv_addr kernelstack;
struct pv_addr systempage;
struct pv_addr irqstack;
struct pv_addr abtstack;
struct pv_addr undstack;
void *
initarm(struct arm_boot_params *abp)
{
struct pv_addr kernel_l1pt;
struct pv_addr dpcpu;
int i;
u_int l1pagetable;
vm_offset_t freemempos;
vm_offset_t afterkern;
uint32_t memsize;
vm_offset_t lastaddr;
lastaddr = parse_boot_param(abp);
arm_physmem_kernaddr = abp->abp_physaddr;
set_cpufuncs();
pcpu0_init();
/* Do basic tuning, hz etc */
init_param1();
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 + (abp->abp_physaddr - 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 < NUM_KERNEL_PTS; ++i) {
if (!(i % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) {
valloc_pages(kernel_pt_table[i],
L2_TABLE_SIZE / PAGE_SIZE);
} else {
kernel_pt_table[i].pv_va = freemempos -
(i % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) *
L2_TABLE_SIZE_REAL;
kernel_pt_table[i].pv_pa =
kernel_pt_table[i].pv_va - KERNVIRTADDR +
abp->abp_physaddr;
}
}
/*
* 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);
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;
/* Map the L2 pages tables in the L1 page table */
pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH,
&kernel_pt_table[KERNEL_PT_SYS]);
for (i = 0; i < KERNEL_PT_KERN_NUM; i++)
pmap_link_l2pt(l1pagetable, KERNBASE + i * L1_S_SIZE,
&kernel_pt_table[KERNEL_PT_KERN + i]);
pmap_map_chunk(l1pagetable, KERNBASE, PHYSADDR,
rounddown2(((uint32_t)lastaddr - KERNBASE) + PAGE_SIZE, PAGE_SIZE),
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
afterkern = round_page(rounddown2(lastaddr + L1_S_SIZE, L1_S_SIZE));
for (i = 0; i < KERNEL_PT_AFKERNEL_NUM; i++) {
pmap_link_l2pt(l1pagetable, afterkern + i * L1_S_SIZE,
&kernel_pt_table[KERNEL_PT_AFKERNEL + i]);
}
/* Map the vector page. */
pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
/* Map the DPCPU pages */
pmap_map_chunk(l1pagetable, dpcpu.pv_va, dpcpu.pv_pa, DPCPU_SIZE,
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
/* Map the stack pages */
pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa,
IRQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa,
ABT_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa,
UND_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa,
kstack_pages * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
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, msgbufpv.pv_va, msgbufpv.pv_pa,
msgbufsize, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
for (i = 0; i < NUM_KERNEL_PTS; ++i) {
pmap_map_chunk(l1pagetable, kernel_pt_table[i].pv_va,
kernel_pt_table[i].pv_pa, L2_TABLE_SIZE,
VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
}
devmap_bootstrap(l1pagetable, at91_devmap);
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) | DOMAIN_CLIENT);
cpu_setttb(kernel_l1pt.pv_pa);
cpu_tlb_flushID();
cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2));
at91_soc_id();
/*
* Initialize all the clocks, so that the console can work. We can only
* do this if at91_soc_id() was able to fill in the support data. Even
* if we can't init the clocks, still try to do a console init so we can
* try to print the error message about missing soc support. There's a
* chance the printf will work if the bootloader set up the DBGU.
*/
if (soc_info.soc_data != NULL) {
soc_info.soc_data->soc_clock_init();
at91_pmc_init_clock();
}
cninit();
if (soc_info.soc_data == NULL)
printf("Warning: No soc support for %s found.\n", soc_info.name);
memsize = board_init();
if (memsize == -1) {
printf("board_init() failed, cannot determine ram size; "
"assuming 16MB\n");
memsize = 16 * 1024 * 1024;
}
/* Enable MMU (set SCTLR), and do other cpu-specific setup. */
cpu_control(CPU_CONTROL_MMU_ENABLE, CPU_CONTROL_MMU_ENABLE);
cpu_setup();
/*
* 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.
*/
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 cpu_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();
undefined_init();
init_proc0(kernelstack.pv_va);
arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
pmap_curmaxkvaddr = afterkern + L1_S_SIZE * (KERNEL_PT_KERN_NUM - 1);
/* Always use the 256MB of KVA we have available between the kernel and devices */
vm_max_kernel_address = KERNVIRTADDR + (256 << 20);
pmap_bootstrap(freemempos, &kernel_l1pt);
msgbufp = (void*)msgbufpv.pv_va;
msgbufinit(msgbufp, msgbufsize);
mutex_init();
/*
* Add the physical ram we have available.
*
* Exclude the kernel, and all the things we allocated which immediately
* follow the kernel, from the VM allocation pool but not from crash
* dumps. virtual_avail is a global variable which tracks the kva we've
* "allocated" while setting up pmaps.
*
* Prepare the list of physical memory available to the vm subsystem.
*/
arm_physmem_hardware_region(PHYSADDR, memsize);
arm_physmem_exclude_region(abp->abp_physaddr,
virtual_avail - KERNVIRTADDR, EXFLAG_NOALLOC);
arm_physmem_init_kernel_globals();
init_param2(physmem);
kdb_init();
return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
sizeof(struct pcb)));
}
#endif
/*
* These functions are handled elsewhere, so make them nops here.
*/
void
cpu_startprofclock(void)
{
}
void
cpu_stopprofclock(void)
{
}
void
cpu_initclocks(void)
{
}
void
DELAY(int n)
{
TSENTER();
if (soc_info.soc_data)
soc_info.soc_data->soc_delay(n);
TSEXIT();
}
void
cpu_reset(void)
{
if (soc_info.soc_data)
soc_info.soc_data->soc_reset();
while (1)
continue;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,158 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2006 Berndt Walter. All rights reserved.
* Copyright (c) 2006 M. Warner Losh.
*
* 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 ARM_AT91_AT91_MCIREG_H
#define ARM_AT91_AT91_MCIREG_H
#define MMC_MAX 30
#define MCI_CR 0x00 /* MCI Control Register */
#define MCI_MR 0x04 /* MCI Mode Register */
#define MCI_DTOR 0x08 /* MCI Data Timeout Register */
#define MCI_SDCR 0x0c /* MCI SD Card Register */
#define MCI_ARGR 0x10 /* MCI Argument Register */
#define MCI_CMDR 0x14 /* MCI Command Register */
#define MCI_RSPR 0x20 /* MCI Response Registers - 4 of them */
#define MCI_RDR 0x30 /* MCI Receive Data Register */
#define MCI_TDR 0x34 /* MCI Transmit Data Register */
#define MCI_SR 0x40 /* MCI Status Register */
#define MCI_IER 0x44 /* MCI Interrupt Enable Register */
#define MCI_IDR 0x48 /* MCI Interrupt Disable Register */
#define MCI_IMR 0x4c /* MCI Interrupt Mask Register */
/* -------- MCI_CR : (MCI Offset: 0x0) MCI Control Register -------- */
#define MCI_CR_MCIEN (0x1u << 0) /* (MCI) Multimedia Interface Enable */
#define MCI_CR_MCIDIS (0x1u << 1) /* (MCI) Multimedia Interface Disable */
#define MCI_CR_PWSEN (0x1u << 2) /* (MCI) Power Save Mode Enable */
#define MCI_CR_PWSDIS (0x1u << 3) /* (MCI) Power Save Mode Disable */
#define MCI_CR_SWRST (0x1u << 7) /* (MCI) Software Reset */
/* -------- MCI_MR : (MCI Offset: 0x4) MCI Mode Register -------- */
#define MCI_MR_CLKDIV (0xffu << 0) /* (MCI) Clock Divider */
#define MCI_MR_PWSDIV (0x3fu << 8) /* (MCI) Power Saving Divider */
#define MCI_MR_RDPROOF (0x1u << 11) /* (MCI) Read Proof Enable */
#define MCI_MR_WRPROOF (0x1u << 12) /* (MCI) Write Proof Enable */
#define MCI_MR_PDCFBYTE (0x1u << 13) /* (MCI) PDC Force Byte Transfer */
#define MCI_MR_PDCPADV (0x1u << 14) /* (MCI) PDC Padding Value */
#define MCI_MR_PDCMODE (0x1u << 15) /* (MCI) PDC Oriented Mode */
#define MCI_MR_BLKLEN 0x3fff0000ul /* (MCI) Data Block Length */
/* -------- MCI_DTOR : (MCI Offset: 0x8) MCI Data Timeout Register -------- */
#define MCI_DTOR_DTOCYC (0xfu << 0) /* (MCI) Data Timeout Cycle Number */
#define MCI_DTOR_DTOMUL (0x7u << 4) /* (MCI) Data Timeout Multiplier */
#define MCI_DTOR_DTOMUL_1 (0x0u << 4) /* (MCI) DTOCYC x 1 */
#define MCI_DTOR_DTOMUL_16 (0x1u << 4) /* (MCI) DTOCYC x 16 */
#define MCI_DTOR_DTOMUL_128 (0x2u << 4) /* (MCI) DTOCYC x 128 */
#define MCI_DTOR_DTOMUL_256 (0x3u << 4) /* (MCI) DTOCYC x 256 */
#define MCI_DTOR_DTOMUL_1k (0x4u << 4) /* (MCI) DTOCYC x 1024 */
#define MCI_DTOR_DTOMUL_4k (0x5u << 4) /* (MCI) DTOCYC x 4096 */
#define MCI_DTOR_DTOMUL_64k (0x6u << 4) /* (MCI) DTOCYC x 65536 */
#define MCI_DTOR_DTOMUL_1M (0x7u << 4) /* (MCI) DTOCYC x 1048576 */
/* -------- MCI_SDCR : (MCI Offset: 0xc) MCI SD Card Register -------- */
#define MCI_SDCR_SDCSEL (0x1u << 0) /* (MCI) SD Card Selector */
#define MCI_SDCR_SDCBUS (0x1u << 7) /* (MCI) SD Card Bus Width */
/* -------- MCI_CMDR : (MCI Offset: 0x14) MCI Command Register -------- */
#define MCI_CMDR_CMDNB (0x1Fu << 0) /* (MCI) Command Number */
#define MCI_CMDR_RSPTYP (0x3u << 6) /* (MCI) Response Type */
#define MCI_CMDR_RSPTYP_NO (0x0u << 6) /* (MCI) No response */
#define MCI_CMDR_RSPTYP_48 (0x1u << 6) /* (MCI) 48-bit response */
#define MCI_CMDR_RSPTYP_136 (0x2u << 6) /* (MCI) 136-bit response */
#define MCI_CMDR_SPCMD (0x7u << 8) /* (MCI) Special CMD */
#define MCI_CMDR_SPCMD_NONE (0x0u << 8) /* (MCI) Not a special CMD */
#define MCI_CMDR_SPCMD_INIT (0x1u << 8) /* (MCI) Initialization CMD */
#define MCI_CMDR_SPCMD_SYNC (0x2u << 8) /* (MCI) Synchronized CMD */
#define MCI_CMDR_SPCMD_IT_CMD (0x4u << 8) /* (MCI) Interrupt command */
#define MCI_CMDR_SPCMD_IT_REP (0x5u << 8) /* (MCI) Interrupt response */
#define MCI_CMDR_OPDCMD (0x1u << 11) /* (MCI) Open Drain Command */
#define MCI_CMDR_MAXLAT (0x1u << 12) /* (MCI) Maximum Latency for Command to respond */
#define MCI_CMDR_TRCMD (0x3u << 16) /* (MCI) Transfer CMD */
#define MCI_CMDR_TRCMD_NO (0x0u << 16) /* (MCI) No transfer */
#define MCI_CMDR_TRCMD_START (0x1u << 16) /* (MCI) Start transfer */
#define MCI_CMDR_TRCMD_STOP (0x2u << 16) /* (MCI) Stop transfer */
#define MCI_CMDR_TRDIR (0x1u << 18) /* (MCI) Transfer Direction */
#define MCI_CMDR_TRTYP (0x3u << 19) /* (MCI) Transfer Type */
#define MCI_CMDR_TRTYP_BLOCK (0x0u << 19) /* (MCI) Block Transfer type */
#define MCI_CMDR_TRTYP_MULTIPLE (0x1u << 19) /* (MCI) Multiple Block transfer type */
#define MCI_CMDR_TRTYP_STREAM (0x2u << 19) /* (MCI) Stream transfer type */
/* -------- MCI_SR : (MCI Offset: 0x40) MCI Status Register -------- */
#define MCI_SR_CMDRDY (0x1u << 0) /* (MCI) Command Ready flag */
#define MCI_SR_RXRDY (0x1u << 1) /* (MCI) RX Ready flag */
#define MCI_SR_TXRDY (0x1u << 2) /* (MCI) TX Ready flag */
#define MCI_SR_BLKE (0x1u << 3) /* (MCI) Data Block Transfer Ended flag */
#define MCI_SR_DTIP (0x1u << 4) /* (MCI) Data Transfer in Progress flag */
#define MCI_SR_NOTBUSY (0x1u << 5) /* (MCI) Data Line Not Busy flag */
#define MCI_SR_ENDRX (0x1u << 6) /* (MCI) End of RX Buffer flag */
#define MCI_SR_ENDTX (0x1u << 7) /* (MCI) End of TX Buffer flag */
#define MCI_SR_RXBUFF (0x1u << 14) /* (MCI) RX Buffer Full flag */
#define MCI_SR_TXBUFE (0x1u << 15) /* (MCI) TX Buffer Empty flag */
#define MCI_SR_RINDE (0x1u << 16) /* (MCI) Response Index Error flag */
#define MCI_SR_RDIRE (0x1u << 17) /* (MCI) Response Direction Error flag */
#define MCI_SR_RCRCE (0x1u << 18) /* (MCI) Response CRC Error flag */
#define MCI_SR_RENDE (0x1u << 19) /* (MCI) Response End Bit Error flag */
#define MCI_SR_RTOE (0x1u << 20) /* (MCI) Response Time-out Error flag */
#define MCI_SR_DCRCE (0x1u << 21) /* (MCI) data CRC Error flag */
#define MCI_SR_DTOE (0x1u << 22) /* (MCI) Data timeout Error flag */
#define MCI_SR_OVRE (0x1u << 30) /* (MCI) Overrun flag */
#define MCI_SR_UNRE (0x1u << 31) /* (MCI) Underrun flag */
/* TXRDY,DTIP,ENDTX,TXBUFE,RTOE */
#define MCI_SR_BITSTRING \
"\020" \
"\001CMDRDY" \
"\002RXRDY" \
"\003TXRDY" \
"\004BLKE" \
"\005DTIP" \
"\006NOTBUSY" \
"\007ENDRX" \
"\010ENDTX" \
"\017RXBUFF" \
"\020TXBUFE" \
"\021RINDE" \
"\022RDIRE" \
"\023RCRCE" \
"\024RENDE" \
"\025RTOE" \
"\026DCRCE" \
"\027DTOE" \
"\037OVRE" \
"\040UNRE"
/* -------- MCI_IER : (MCI Offset: 0x44) MCI Interrupt Enable Register -------- */
/* -------- MCI_IDR : (MCI Offset: 0x48) MCI Interrupt Disable Register -------- */
/* -------- MCI_IMR : (MCI Offset: 0x4c) MCI Interrupt Mask Register -------- */
#define MCI_SR_ERROR (MCI_SR_UNRE | MCI_SR_OVRE | MCI_SR_DTOE | \
MCI_SR_DCRCE | MCI_SR_RTOE | MCI_SR_RENDE | \
MCI_SR_RCRCE | MCI_SR_RDIRE | MCI_SR_RINDE)
#define AT91C_BUS_WIDTH_1BIT 0x00
#define AT91C_BUS_WIDTH_4BITS 0x02
#endif /* ARM_AT91_AT91_MCIREG_H */

View File

@ -1,236 +0,0 @@
/*-
* Copyright (c) 2006 M. Warner Losh.
*
* 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/stdint.h>
#include <sys/stddef.h>
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <sys/module.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/condvar.h>
#include <sys/sysctl.h>
#include <sys/sx.h>
#include <sys/unistd.h>
#include <sys/callout.h>
#include <sys/malloc.h>
#include <sys/priv.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usb_core.h>
#include <dev/usb/usb_busdma.h>
#include <dev/usb/usb_process.h>
#include <dev/usb/usb_util.h>
#include <dev/usb/usb_controller.h>
#include <dev/usb/usb_bus.h>
#include <dev/usb/controller/ohci.h>
#include <dev/usb/controller/ohcireg.h>
#include <sys/rman.h>
#include <arm/at91/at91_pmcvar.h>
#define MEM_RID 0
static device_probe_t ohci_atmelarm_probe;
static device_attach_t ohci_atmelarm_attach;
static device_detach_t ohci_atmelarm_detach;
struct at91_ohci_softc {
struct ohci_softc sc_ohci; /* must be first */
struct at91_pmc_clock *mclk;
struct at91_pmc_clock *iclk;
struct at91_pmc_clock *fclk;
};
static int
ohci_atmelarm_probe(device_t dev)
{
device_set_desc(dev, "AT91 integrated OHCI controller");
return (BUS_PROBE_DEFAULT);
}
static int
ohci_atmelarm_attach(device_t dev)
{
struct at91_ohci_softc *sc = device_get_softc(dev);
int err;
int rid;
/* initialise some bus fields */
sc->sc_ohci.sc_bus.parent = dev;
sc->sc_ohci.sc_bus.devices = sc->sc_ohci.sc_devices;
sc->sc_ohci.sc_bus.devices_max = OHCI_MAX_DEVICES;
sc->sc_ohci.sc_bus.dma_bits = 32;
/* get all DMA memory */
if (usb_bus_mem_alloc_all(&sc->sc_ohci.sc_bus,
USB_GET_DMA_TAG(dev), &ohci_iterate_hw_softc)) {
return (ENOMEM);
}
sc->mclk = at91_pmc_clock_ref("mck");
sc->iclk = at91_pmc_clock_ref("ohci_clk");
sc->fclk = at91_pmc_clock_ref("uhpck");
sc->sc_ohci.sc_dev = dev;
rid = MEM_RID;
sc->sc_ohci.sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&rid, RF_ACTIVE);
if (!(sc->sc_ohci.sc_io_res)) {
err = ENOMEM;
goto error;
}
sc->sc_ohci.sc_io_tag = rman_get_bustag(sc->sc_ohci.sc_io_res);
sc->sc_ohci.sc_io_hdl = rman_get_bushandle(sc->sc_ohci.sc_io_res);
sc->sc_ohci.sc_io_size = rman_get_size(sc->sc_ohci.sc_io_res);
rid = 0;
sc->sc_ohci.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE);
if (!(sc->sc_ohci.sc_irq_res)) {
goto error;
}
sc->sc_ohci.sc_bus.bdev = device_add_child(dev, "usbus", -1);
if (!(sc->sc_ohci.sc_bus.bdev)) {
goto error;
}
device_set_ivars(sc->sc_ohci.sc_bus.bdev, &sc->sc_ohci.sc_bus);
strlcpy(sc->sc_ohci.sc_vendor, "Atmel", sizeof(sc->sc_ohci.sc_vendor));
err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
NULL, (driver_intr_t *)ohci_interrupt, sc, &sc->sc_ohci.sc_intr_hdl);
if (err) {
sc->sc_ohci.sc_intr_hdl = NULL;
goto error;
}
/*
* turn on the clocks from the AT91's point of view. Keep the unit in reset.
*/
at91_pmc_clock_enable(sc->mclk);
at91_pmc_clock_enable(sc->iclk);
at91_pmc_clock_enable(sc->fclk);
bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl,
OHCI_CONTROL, 0);
err = ohci_init(&sc->sc_ohci);
if (!err) {
err = device_probe_and_attach(sc->sc_ohci.sc_bus.bdev);
}
if (err) {
goto error;
}
return (0);
error:
ohci_atmelarm_detach(dev);
return (ENXIO);
}
static int
ohci_atmelarm_detach(device_t dev)
{
struct at91_ohci_softc *sc = device_get_softc(dev);
int err;
/* during module unload there are lots of children leftover */
device_delete_children(dev);
/*
* Put the controller into reset, then disable clocks and do
* the MI tear down. We have to disable the clocks/hardware
* after we do the rest of the teardown. We also disable the
* clocks in the opposite order we acquire them, but that
* doesn't seem to be absolutely necessary. We free up the
* clocks after we disable them, so the system could, in
* theory, reuse them.
*/
bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl,
OHCI_CONTROL, 0);
at91_pmc_clock_disable(sc->fclk);
at91_pmc_clock_disable(sc->iclk);
at91_pmc_clock_disable(sc->mclk);
at91_pmc_clock_deref(sc->fclk);
at91_pmc_clock_deref(sc->iclk);
at91_pmc_clock_deref(sc->mclk);
if (sc->sc_ohci.sc_irq_res && sc->sc_ohci.sc_intr_hdl) {
/*
* only call ohci_detach() after ohci_init()
*/
ohci_detach(&sc->sc_ohci);
err = bus_teardown_intr(dev, sc->sc_ohci.sc_irq_res, sc->sc_ohci.sc_intr_hdl);
sc->sc_ohci.sc_intr_hdl = NULL;
}
if (sc->sc_ohci.sc_irq_res) {
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_ohci.sc_irq_res);
sc->sc_ohci.sc_irq_res = NULL;
}
if (sc->sc_ohci.sc_io_res) {
bus_release_resource(dev, SYS_RES_MEMORY, MEM_RID,
sc->sc_ohci.sc_io_res);
sc->sc_ohci.sc_io_res = NULL;
}
usb_bus_mem_free_all(&sc->sc_ohci.sc_bus, &ohci_iterate_hw_softc);
return (0);
}
static device_method_t ohci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ohci_atmelarm_probe),
DEVMETHOD(device_attach, ohci_atmelarm_attach),
DEVMETHOD(device_detach, ohci_atmelarm_detach),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
static driver_t ohci_driver = {
.name = "ohci",
.methods = ohci_methods,
.size = sizeof(struct at91_ohci_softc),
};
static devclass_t ohci_devclass;
DRIVER_MODULE(ohci, atmelarm, ohci_driver, ohci_devclass, 0, 0);
MODULE_DEPEND(ohci, usb, 1, 1, 1);

View File

@ -1,244 +0,0 @@
/*-
* Copyright (c) 2006 M. Warner Losh.
*
* 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/stdint.h>
#include <sys/stddef.h>
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <sys/module.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/condvar.h>
#include <sys/sysctl.h>
#include <sys/sx.h>
#include <sys/unistd.h>
#include <sys/callout.h>
#include <sys/malloc.h>
#include <sys/priv.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usb_core.h>
#include <dev/usb/usb_busdma.h>
#include <dev/usb/usb_process.h>
#include <dev/usb/usb_util.h>
#include <dev/usb/usb_controller.h>
#include <dev/usb/usb_bus.h>
#include <dev/usb/controller/ohci.h>
#include <dev/usb/controller/ohcireg.h>
#include <sys/rman.h>
#include <arm/at91/at91_pmcvar.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#define MEM_RID 0
static device_probe_t ohci_at91_fdt_probe;
static device_attach_t ohci_at91_fdt_attach;
static device_detach_t ohci_at91_fdt_detach;
struct at91_ohci_softc {
struct ohci_softc sc_ohci; /* must be first */
struct at91_pmc_clock *mclk;
struct at91_pmc_clock *iclk;
struct at91_pmc_clock *fclk;
};
static int
ohci_at91_fdt_probe(device_t dev)
{
if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-ohci"))
return (ENXIO);
device_set_desc(dev, "AT91 integrated OHCI controller");
return (BUS_PROBE_DEFAULT);
}
static int
ohci_at91_fdt_attach(device_t dev)
{
struct at91_ohci_softc *sc = device_get_softc(dev);
int err;
int rid;
/* initialise some bus fields */
sc->sc_ohci.sc_bus.parent = dev;
sc->sc_ohci.sc_bus.devices = sc->sc_ohci.sc_devices;
sc->sc_ohci.sc_bus.devices_max = OHCI_MAX_DEVICES;
sc->sc_ohci.sc_bus.dma_bits = 32;
/* get all DMA memory */
if (usb_bus_mem_alloc_all(&sc->sc_ohci.sc_bus,
USB_GET_DMA_TAG(dev), &ohci_iterate_hw_softc)) {
return (ENOMEM);
}
sc->mclk = at91_pmc_clock_ref("mck");
sc->iclk = at91_pmc_clock_ref("ohci_clk");
sc->fclk = at91_pmc_clock_ref("uhpck");
sc->sc_ohci.sc_dev = dev;
rid = MEM_RID;
sc->sc_ohci.sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&rid, RF_ACTIVE);
if (!(sc->sc_ohci.sc_io_res)) {
err = ENOMEM;
goto error;
}
sc->sc_ohci.sc_io_tag = rman_get_bustag(sc->sc_ohci.sc_io_res);
sc->sc_ohci.sc_io_hdl = rman_get_bushandle(sc->sc_ohci.sc_io_res);
sc->sc_ohci.sc_io_size = rman_get_size(sc->sc_ohci.sc_io_res);
rid = 0;
sc->sc_ohci.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE);
if (!(sc->sc_ohci.sc_irq_res)) {
goto error;
}
sc->sc_ohci.sc_bus.bdev = device_add_child(dev, "usbus", -1);
if (!(sc->sc_ohci.sc_bus.bdev)) {
goto error;
}
device_set_ivars(sc->sc_ohci.sc_bus.bdev, &sc->sc_ohci.sc_bus);
strlcpy(sc->sc_ohci.sc_vendor, "Atmel", sizeof(sc->sc_ohci.sc_vendor));
err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
NULL, (driver_intr_t *)ohci_interrupt, sc, &sc->sc_ohci.sc_intr_hdl);
if (err) {
sc->sc_ohci.sc_intr_hdl = NULL;
goto error;
}
/*
* turn on the clocks from the AT91's point of view. Keep the unit in reset.
*/
at91_pmc_clock_enable(sc->mclk);
at91_pmc_clock_enable(sc->iclk);
at91_pmc_clock_enable(sc->fclk);
bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl,
OHCI_CONTROL, 0);
err = ohci_init(&sc->sc_ohci);
if (!err) {
err = device_probe_and_attach(sc->sc_ohci.sc_bus.bdev);
}
if (err) {
goto error;
}
return (0);
error:
ohci_at91_fdt_detach(dev);
return (ENXIO);
}
static int
ohci_at91_fdt_detach(device_t dev)
{
struct at91_ohci_softc *sc = device_get_softc(dev);
int err;
/* during module unload there are lots of children leftover */
device_delete_children(dev);
if (sc->sc_ohci.sc_io_res != NULL) {
/*
* Put the controller into reset, then disable clocks and do
* the MI tear down. We have to disable the clocks/hardware
* after we do the rest of the teardown. We also disable the
* clocks in the opposite order we acquire them, but that
* doesn't seem to be absolutely necessary. We free up the
* clocks after we disable them, so the system could, in
* theory, reuse them.
*/
bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl,
OHCI_CONTROL, 0);
at91_pmc_clock_disable(sc->fclk);
at91_pmc_clock_disable(sc->iclk);
at91_pmc_clock_disable(sc->mclk);
at91_pmc_clock_deref(sc->fclk);
at91_pmc_clock_deref(sc->iclk);
at91_pmc_clock_deref(sc->mclk);
if (sc->sc_ohci.sc_irq_res && sc->sc_ohci.sc_intr_hdl) {
/*
* only call ohci_detach() after ohci_init()
*/
ohci_detach(&sc->sc_ohci);
err = bus_teardown_intr(dev, sc->sc_ohci.sc_irq_res,
sc->sc_ohci.sc_intr_hdl);
sc->sc_ohci.sc_intr_hdl = NULL;
}
if (sc->sc_ohci.sc_irq_res) {
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_ohci.sc_irq_res);
sc->sc_ohci.sc_irq_res = NULL;
}
if (sc->sc_ohci.sc_io_res) {
bus_release_resource(dev, SYS_RES_MEMORY, MEM_RID,
sc->sc_ohci.sc_io_res);
sc->sc_ohci.sc_io_res = NULL;
}
}
usb_bus_mem_free_all(&sc->sc_ohci.sc_bus, &ohci_iterate_hw_softc);
return (0);
}
static device_method_t ohci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ohci_at91_fdt_probe),
DEVMETHOD(device_attach, ohci_at91_fdt_attach),
DEVMETHOD(device_detach, ohci_at91_fdt_detach),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
static driver_t ohci_driver = {
.name = "ohci",
.methods = ohci_methods,
.size = sizeof(struct at91_ohci_softc),
};
static devclass_t ohci_devclass;
DRIVER_MODULE(ohci, simplebus, ohci_driver, ohci_devclass, 0, 0);
MODULE_DEPEND(ohci, usb, 1, 1, 1);

View File

@ -1,50 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2006 M. Warner Losh.
*
* 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 ARM_AT91_AT91_PDCREG_H
#define ARM_AT91_AT91_PDCREG_H
#define PDC_RPR 0x100 /* PDC Receive Pointer Register */
#define PDC_RCR 0x104 /* PDC Receive Counter Register */
#define PDC_TPR 0x108 /* PDC Transmit Pointer Register */
#define PDC_TCR 0x10c /* PDC Transmit Counter Register */
#define PDC_RNPR 0x110 /* PDC Receive Next Pointer Register */
#define PDC_RNCR 0x114 /* PDC Receive Next Counter Register */
#define PDC_TNPR 0x118 /* PDC Transmit Next Pointer Reg */
#define PDC_TNCR 0x11c /* PDC Transmit Next Counter Reg */
#define PDC_PTCR 0x120 /* PDC Transfer Control Register */
#define PDC_PTSR 0x124 /* PDC Transfer Status Register */
/* PTCR/PTSR */
#define PDC_PTCR_RXTEN (1UL << 0) /* RXTEN: Receiver Transfer Enable */
#define PDC_PTCR_RXTDIS (1UL << 1) /* RXTDIS: Receiver Transfer Disable */
#define PDC_PTCR_TXTEN (1UL << 8) /* TXTEN: Transmitter Transfer En */
#define PDC_PTCR_TXTDIS (1UL << 9) /* TXTDIS: Transmitter Transmit Dis */
#endif /* ARM_AT91_AT91_PDCREG_H */

View File

@ -1,517 +0,0 @@
/*-
* Copyright (c) 2014 M. Warner Losh.
*
* 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/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/resource.h>
#include <sys/systm.h>
#include <sys/rman.h>
#include <machine/bus.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91_piovar.h>
#include <dev/fdt/fdt_pinctrl.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#define BUS_PASS_PINMUX (BUS_PASS_INTERRUPT + 1)
struct pinctrl_range {
uint64_t bus;
uint64_t host;
uint64_t size;
};
struct pinctrl_softc {
device_t dev;
phandle_t node;
struct pinctrl_range *ranges;
int nranges;
pcell_t acells, scells;
int done_pinmux;
};
struct pinctrl_devinfo {
struct ofw_bus_devinfo obdinfo;
struct resource_list rl;
};
static int
at91_pinctrl_probe(device_t dev)
{
if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-pinctrl"))
return (ENXIO);
device_set_desc(dev, "pincontrol bus");
return (0);
}
/* XXX Make this a subclass of simplebus */
static struct pinctrl_devinfo *
at91_pinctrl_setup_dinfo(device_t dev, phandle_t node)
{
struct pinctrl_softc *sc;
struct pinctrl_devinfo *ndi;
uint32_t *reg, *intr, icells;
uint64_t phys, size;
phandle_t iparent;
int i, j, k;
int nintr;
int nreg;
sc = device_get_softc(dev);
ndi = malloc(sizeof(*ndi), M_DEVBUF, M_WAITOK | M_ZERO);
if (ofw_bus_gen_setup_devinfo(&ndi->obdinfo, node) != 0) {
free(ndi, M_DEVBUF);
return (NULL);
}
resource_list_init(&ndi->rl);
nreg = OF_getencprop_alloc_multi(node, "reg", sizeof(*reg),
(void **)&reg);
if (nreg == -1)
nreg = 0;
if (nreg % (sc->acells + sc->scells) != 0) {
// if (bootverbose)
device_printf(dev, "Malformed reg property on <%s>\n",
ndi->obdinfo.obd_name);
nreg = 0;
}
for (i = 0, k = 0; i < nreg; i += sc->acells + sc->scells, k++) {
phys = size = 0;
for (j = 0; j < sc->acells; j++) {
phys <<= 32;
phys |= reg[i + j];
}
for (j = 0; j < sc->scells; j++) {
size <<= 32;
size |= reg[i + sc->acells + j];
}
resource_list_add(&ndi->rl, SYS_RES_MEMORY, k,
phys, phys + size - 1, size);
}
OF_prop_free(reg);
nintr = OF_getencprop_alloc_multi(node, "interrupts", sizeof(*intr),
(void **)&intr);
if (nintr > 0) {
if (OF_searchencprop(node, "interrupt-parent", &iparent,
sizeof(iparent)) == -1) {
device_printf(dev, "No interrupt-parent found, "
"assuming direct parent\n");
iparent = OF_parent(node);
}
if (OF_searchencprop(OF_node_from_xref(iparent),
"#interrupt-cells", &icells, sizeof(icells)) == -1) {
device_printf(dev, "Missing #interrupt-cells property,"
" assuming <1>\n");
icells = 1;
}
if (icells < 1 || icells > nintr) {
device_printf(dev, "Invalid #interrupt-cells property "
"value <%d>, assuming <1>\n", icells);
icells = 1;
}
for (i = 0, k = 0; i < nintr; i += icells, k++) {
intr[i] = ofw_bus_map_intr(dev, iparent, icells,
&intr[i]);
resource_list_add(&ndi->rl, SYS_RES_IRQ, k, intr[i],
intr[i], 1);
}
OF_prop_free(intr);
}
return (ndi);
}
static int
at91_pinctrl_fill_ranges(phandle_t node, struct pinctrl_softc *sc)
{
int host_address_cells;
cell_t *base_ranges;
ssize_t nbase_ranges;
int err;
int i, j, k;
err = OF_searchencprop(OF_parent(node), "#address-cells",
&host_address_cells, sizeof(host_address_cells));
if (err <= 0)
return (-1);
nbase_ranges = OF_getproplen(node, "ranges");
if (nbase_ranges < 0)
return (-1);
sc->nranges = nbase_ranges / sizeof(cell_t) /
(sc->acells + host_address_cells + sc->scells);
if (sc->nranges == 0)
return (0);
sc->ranges = malloc(sc->nranges * sizeof(sc->ranges[0]),
M_DEVBUF, M_WAITOK);
base_ranges = malloc(nbase_ranges, M_DEVBUF, M_WAITOK);
OF_getencprop(node, "ranges", base_ranges, nbase_ranges);
for (i = 0, j = 0; i < sc->nranges; i++) {
sc->ranges[i].bus = 0;
for (k = 0; k < sc->acells; k++) {
sc->ranges[i].bus <<= 32;
sc->ranges[i].bus |= base_ranges[j++];
}
sc->ranges[i].host = 0;
for (k = 0; k < host_address_cells; k++) {
sc->ranges[i].host <<= 32;
sc->ranges[i].host |= base_ranges[j++];
}
sc->ranges[i].size = 0;
for (k = 0; k < sc->scells; k++) {
sc->ranges[i].size <<= 32;
sc->ranges[i].size |= base_ranges[j++];
}
}
free(base_ranges, M_DEVBUF);
return (sc->nranges);
}
static int
at91_pinctrl_attach(device_t dev)
{
struct pinctrl_softc *sc;
struct pinctrl_devinfo *di;
phandle_t node;
device_t cdev;
sc = device_get_softc(dev);
node = ofw_bus_get_node(dev);
sc->dev = dev;
sc->node = node;
/*
* Some important numbers
*/
sc->acells = 2;
OF_getencprop(node, "#address-cells", &sc->acells, sizeof(sc->acells));
sc->scells = 1;
OF_getencprop(node, "#size-cells", &sc->scells, sizeof(sc->scells));
if (at91_pinctrl_fill_ranges(node, sc) < 0) {
device_printf(dev, "could not get ranges\n");
return (ENXIO);
}
for (node = OF_child(node); node > 0; node = OF_peer(node)) {
if ((di = at91_pinctrl_setup_dinfo(dev, node)) == NULL)
continue;
cdev = device_add_child(dev, NULL, -1);
if (cdev == NULL) {
device_printf(dev, "<%s>: device_add_child failed\n",
di->obdinfo.obd_name);
resource_list_free(&di->rl);
ofw_bus_gen_destroy_devinfo(&di->obdinfo);
free(di, M_DEVBUF);
continue;
}
device_set_ivars(cdev, di);
}
fdt_pinctrl_register(dev, "atmel,pins");
return (bus_generic_attach(dev));
}
static const struct ofw_bus_devinfo *
pinctrl_get_devinfo(device_t bus __unused, device_t child)
{
struct pinctrl_devinfo *ndi;
ndi = device_get_ivars(child);
return (&ndi->obdinfo);
}
static struct resource *
pinctrl_alloc_resource(device_t bus, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
struct pinctrl_softc *sc;
struct pinctrl_devinfo *di;
struct resource_list_entry *rle;
int j;
sc = device_get_softc(bus);
/*
* Request for the default allocation with a given rid: use resource
* list stored in the local device info.
*/
if (RMAN_IS_DEFAULT_RANGE(start, end)) {
if ((di = device_get_ivars(child)) == NULL)
return (NULL);
if (type == SYS_RES_IOPORT)
type = SYS_RES_MEMORY;
rle = resource_list_find(&di->rl, type, *rid);
if (rle == NULL) {
// if (bootverbose)
device_printf(bus, "no default resources for "
"rid = %d, type = %d\n", *rid, type);
return (NULL);
}
start = rle->start;
end = rle->end;
count = rle->count;
}
if (type == SYS_RES_MEMORY) {
/* Remap through ranges property */
for (j = 0; j < sc->nranges; j++) {
if (start >= sc->ranges[j].bus && end <
sc->ranges[j].bus + sc->ranges[j].size) {
start -= sc->ranges[j].bus;
start += sc->ranges[j].host;
end -= sc->ranges[j].bus;
end += sc->ranges[j].host;
break;
}
}
if (j == sc->nranges && sc->nranges != 0) {
// if (bootverbose)
device_printf(bus, "Could not map resource "
"%#lx-%#lx\n", start, end);
return (NULL);
}
}
return (bus_generic_alloc_resource(bus, child, type, rid, start, end,
count, flags));
}
static int
pinctrl_print_res(struct pinctrl_devinfo *di)
{
int rv;
rv = 0;
rv += resource_list_print_type(&di->rl, "mem", SYS_RES_MEMORY, "%#jx");
rv += resource_list_print_type(&di->rl, "irq", SYS_RES_IRQ, "%jd");
return (rv);
}
static void
pinctrl_probe_nomatch(device_t bus, device_t child)
{
const char *name, *type, *compat;
// if (!bootverbose)
return;
name = ofw_bus_get_name(child);
type = ofw_bus_get_type(child);
compat = ofw_bus_get_compat(child);
device_printf(bus, "<%s>", name != NULL ? name : "unknown");
pinctrl_print_res(device_get_ivars(child));
if (!ofw_bus_status_okay(child))
printf(" disabled");
if (type)
printf(" type %s", type);
if (compat)
printf(" compat %s", compat);
printf(" (no driver attached)\n");
}
static int
pinctrl_print_child(device_t bus, device_t child)
{
int rv;
rv = bus_print_child_header(bus, child);
rv += pinctrl_print_res(device_get_ivars(child));
if (!ofw_bus_status_okay(child))
rv += printf(" disabled");
rv += bus_print_child_footer(bus, child);
return (rv);
}
const char *periphs[] = {"gpio", "periph A", "periph B", "periph C", "periph D", "periph E" };
struct pincfg {
uint32_t unit;
uint32_t pin;
uint32_t periph;
uint32_t flags;
};
static int
pinctrl_configure_pins(device_t bus, phandle_t cfgxref)
{
struct pinctrl_softc *sc;
struct pincfg *cfg, *cfgdata;
char name[32];
phandle_t node;
ssize_t npins;
int i;
sc = device_get_softc(bus);
node = OF_node_from_xref(cfgxref);
memset(name, 0, sizeof(name));
OF_getprop(node, "name", name, sizeof(name));
npins = OF_getencprop_alloc_multi(node, "atmel,pins", sizeof(*cfgdata),
(void **)&cfgdata);
if (npins < 0) {
printf("We're doing it wrong %s\n", name);
return (ENXIO);
}
if (npins == 0)
return (0);
for (i = 0, cfg = cfgdata; i < npins; i++, cfg++) {
uint32_t pio;
pio = (0xfffffff & sc->ranges[0].bus) + 0x200 * cfg->unit;
printf("P%c%d %s %#x\n", cfg->unit + 'A', cfg->pin,
periphs[cfg->periph], cfg->flags);
switch (cfg->periph) {
case 0:
at91_pio_use_gpio(pio, 1u << cfg->pin);
at91_pio_gpio_pullup(pio, 1u << cfg->pin,
!!(cfg->flags & 1));
at91_pio_gpio_high_z(pio, 1u << cfg->pin,
!!(cfg->flags & 2));
at91_pio_gpio_set_deglitch(pio,
1u << cfg->pin, !!(cfg->flags & 4));
// at91_pio_gpio_pulldown(pio, 1u << cfg->pin,
// !!(cfg->flags & 8));
// at91_pio_gpio_dis_schmidt(pio,
// 1u << cfg->pin, !!(cfg->flags & 16));
break;
case 1:
at91_pio_use_periph_a(pio, 1u << cfg->pin, cfg->flags);
break;
case 2:
at91_pio_use_periph_b(pio, 1u << cfg->pin, cfg->flags);
break;
}
}
OF_prop_free(cfgdata);
return (0);
}
static void
pinctrl_new_pass(device_t bus)
{
struct pinctrl_softc *sc;
sc = device_get_softc(bus);
bus_generic_new_pass(bus);
if (sc->done_pinmux || bus_current_pass < BUS_PASS_PINMUX)
return;
sc->done_pinmux++;
fdt_pinctrl_configure_tree(bus);
}
static device_method_t at91_pinctrl_methods[] = {
DEVMETHOD(device_probe, at91_pinctrl_probe),
DEVMETHOD(device_attach, at91_pinctrl_attach),
DEVMETHOD(bus_print_child, pinctrl_print_child),
DEVMETHOD(bus_probe_nomatch, pinctrl_probe_nomatch),
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
DEVMETHOD(bus_alloc_resource, pinctrl_alloc_resource),
DEVMETHOD(bus_release_resource, bus_generic_release_resource),
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource),
DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str),
DEVMETHOD(bus_new_pass, pinctrl_new_pass),
/* ofw_bus interface */
DEVMETHOD(ofw_bus_get_devinfo, pinctrl_get_devinfo),
DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat),
DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model),
DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name),
DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node),
DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type),
/* fdt_pintrl interface */
DEVMETHOD(fdt_pinctrl_configure,pinctrl_configure_pins),
DEVMETHOD_END
};
static driver_t at91_pinctrl_driver = {
"at91_pinctrl",
at91_pinctrl_methods,
sizeof(struct pinctrl_softc),
};
static devclass_t at91_pinctrl_devclass;
EARLY_DRIVER_MODULE(at91_pinctrl, simplebus, at91_pinctrl_driver,
at91_pinctrl_devclass, NULL, NULL, BUS_PASS_BUS);
/*
* dummy driver to force pass BUS_PASS_PINMUX to happen.
*/
static int
at91_pingroup_probe(device_t dev)
{
return ENXIO;
}
static device_method_t at91_pingroup_methods[] = {
DEVMETHOD(device_probe, at91_pingroup_probe),
DEVMETHOD_END
};
static driver_t at91_pingroup_driver = {
"at91_pingroup",
at91_pingroup_methods,
0,
};
static devclass_t at91_pingroup_devclass;
EARLY_DRIVER_MODULE(at91_pingroup, at91_pinctrl, at91_pingroup_driver,
at91_pingroup_devclass, NULL, NULL, BUS_PASS_PINMUX);

View File

@ -1,655 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2006 M. Warner Losh.
* Copyright (C) 2012 Ian Lepore. 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 "opt_platform.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mbuf.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/poll.h>
#include <sys/rman.h>
#include <sys/selinfo.h>
#include <sys/sx.h>
#include <sys/uio.h>
#include <machine/at91_gpio.h>
#include <machine/bus.h>
#include <arm/at91/at91reg.h>
#include <arm/at91/at91_pioreg.h>
#include <arm/at91/at91_piovar.h>
#ifdef FDT
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#endif
#define MAX_CHANGE 64
struct at91_pio_softc
{
device_t dev; /* Myself */
void *intrhand; /* Interrupt handle */
struct resource *irq_res; /* IRQ resource */
struct resource *mem_res; /* Memory resource */
struct sx sc_mtx; /* basically a perimeter lock */
struct cdev *cdev;
struct selinfo selp;
int buflen;
uint8_t buf[MAX_CHANGE];
int flags;
#define OPENED 1
};
static inline uint32_t
RD4(struct at91_pio_softc *sc, bus_size_t off)
{
return (bus_read_4(sc->mem_res, off));
}
static inline void
WR4(struct at91_pio_softc *sc, bus_size_t off, uint32_t val)
{
bus_write_4(sc->mem_res, off, val);
}
#define AT91_PIO_LOCK(_sc) sx_xlock(&(_sc)->sc_mtx)
#define AT91_PIO_UNLOCK(_sc) sx_xunlock(&(_sc)->sc_mtx)
#define AT91_PIO_LOCK_INIT(_sc) \
sx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev))
#define AT91_PIO_LOCK_DESTROY(_sc) sx_destroy(&_sc->sc_mtx);
#define AT91_PIO_ASSERT_LOCKED(_sc) sx_assert(&_sc->sc_mtx, SA_XLOCKED);
#define AT91_PIO_ASSERT_UNLOCKED(_sc) sx_assert(&_sc->sc_mtx, SA_UNLOCKED);
#define CDEV2SOFTC(dev) ((dev)->si_drv1)
static devclass_t at91_pio_devclass;
/* bus entry points */
static int at91_pio_probe(device_t dev);
static int at91_pio_attach(device_t dev);
static int at91_pio_detach(device_t dev);
static void at91_pio_intr(void *);
/* helper routines */
static int at91_pio_activate(device_t dev);
static void at91_pio_deactivate(device_t dev);
/* cdev routines */
static d_open_t at91_pio_open;
static d_close_t at91_pio_close;
static d_read_t at91_pio_read;
static d_poll_t at91_pio_poll;
static d_ioctl_t at91_pio_ioctl;
static struct cdevsw at91_pio_cdevsw =
{
.d_version = D_VERSION,
.d_open = at91_pio_open,
.d_close = at91_pio_close,
.d_read = at91_pio_read,
.d_poll = at91_pio_poll,
.d_ioctl = at91_pio_ioctl
};
static int
at91_pio_probe(device_t dev)
{
const char *name;
#ifdef FDT
if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-gpio"))
return (ENXIO);
#endif
switch (device_get_unit(dev)) {
case 0:
name = "PIOA";
break;
case 1:
name = "PIOB";
break;
case 2:
name = "PIOC";
break;
case 3:
name = "PIOD";
break;
case 4:
name = "PIOE";
break;
case 5:
name = "PIOF";
break;
default:
name = "PIO";
break;
}
device_set_desc(dev, name);
return (0);
}
static int
at91_pio_attach(device_t dev)
{
struct at91_pio_softc *sc;
int err;
sc = device_get_softc(dev);
sc->dev = dev;
err = at91_pio_activate(dev);
if (err)
goto out;
if (bootverbose)
device_printf(dev, "ABSR: %#x OSR: %#x PSR:%#x ODSR: %#x\n",
RD4(sc, PIO_ABSR), RD4(sc, PIO_OSR), RD4(sc, PIO_PSR),
RD4(sc, PIO_ODSR));
AT91_PIO_LOCK_INIT(sc);
/*
* Activate the interrupt, but disable all interrupts in the hardware.
*/
WR4(sc, PIO_IDR, 0xffffffff);
err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC,
NULL, at91_pio_intr, sc, &sc->intrhand);
if (err) {
AT91_PIO_LOCK_DESTROY(sc);
goto out;
}
sc->cdev = make_dev(&at91_pio_cdevsw, device_get_unit(dev), UID_ROOT,
GID_WHEEL, 0600, "pio%d", device_get_unit(dev));
if (sc->cdev == NULL) {
err = ENOMEM;
goto out;
}
sc->cdev->si_drv1 = sc;
out:
if (err)
at91_pio_deactivate(dev);
return (err);
}
static int
at91_pio_detach(device_t dev)
{
return (EBUSY); /* XXX */
}
static int
at91_pio_activate(device_t dev)
{
struct at91_pio_softc *sc;
int rid;
sc = device_get_softc(dev);
rid = 0;
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (sc->mem_res == NULL)
goto errout;
rid = 0;
sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE | RF_SHAREABLE);
if (sc->irq_res == NULL)
goto errout;
return (0);
errout:
at91_pio_deactivate(dev);
return (ENOMEM);
}
static void
at91_pio_deactivate(device_t dev)
{
struct at91_pio_softc *sc;
sc = device_get_softc(dev);
if (sc->intrhand)
bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
sc->intrhand = NULL;
bus_generic_detach(sc->dev);
if (sc->mem_res)
bus_release_resource(dev, SYS_RES_MEMORY,
rman_get_rid(sc->mem_res), sc->mem_res);
sc->mem_res = NULL;
if (sc->irq_res)
bus_release_resource(dev, SYS_RES_IRQ,
rman_get_rid(sc->irq_res), sc->irq_res);
sc->irq_res = NULL;
}
static void
at91_pio_intr(void *xsc)
{
struct at91_pio_softc *sc = xsc;
uint32_t status;
int i;
/* Reading the status also clears the interrupt. */
status = RD4(sc, PIO_ISR) & RD4(sc, PIO_IMR);
if (status != 0) {
AT91_PIO_LOCK(sc);
for (i = 0; status != 0 && sc->buflen < MAX_CHANGE; ++i) {
if (status & 1)
sc->buf[sc->buflen++] = (uint8_t)i;
status >>= 1;
}
AT91_PIO_UNLOCK(sc);
wakeup(sc);
selwakeup(&sc->selp);
}
}
static int
at91_pio_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
{
struct at91_pio_softc *sc;
sc = CDEV2SOFTC(dev);
AT91_PIO_LOCK(sc);
if (!(sc->flags & OPENED)) {
sc->flags |= OPENED;
}
AT91_PIO_UNLOCK(sc);
return (0);
}
static int
at91_pio_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
{
struct at91_pio_softc *sc;
sc = CDEV2SOFTC(dev);
AT91_PIO_LOCK(sc);
sc->flags &= ~OPENED;
AT91_PIO_UNLOCK(sc);
return (0);
}
static int
at91_pio_poll(struct cdev *dev, int events, struct thread *td)
{
struct at91_pio_softc *sc;
int revents = 0;
sc = CDEV2SOFTC(dev);
AT91_PIO_LOCK(sc);
if (events & (POLLIN | POLLRDNORM)) {
if (sc->buflen != 0)
revents |= events & (POLLIN | POLLRDNORM);
else
selrecord(td, &sc->selp);
}
AT91_PIO_UNLOCK(sc);
return (revents);
}
static int
at91_pio_read(struct cdev *dev, struct uio *uio, int flag)
{
struct at91_pio_softc *sc;
int err, ret, len;
sc = CDEV2SOFTC(dev);
AT91_PIO_LOCK(sc);
err = 0;
ret = 0;
while (uio->uio_resid) {
while (sc->buflen == 0 && err == 0)
err = msleep(sc, &sc->sc_mtx, PCATCH | PZERO, "prd", 0);
if (err != 0)
break;
len = MIN(sc->buflen, uio->uio_resid);
err = uiomove(sc->buf, len, uio);
if (err != 0)
break;
/*
* If we read the whole thing no datacopy is needed,
* otherwise we move the data down.
*/
ret += len;
if (sc->buflen == len)
sc->buflen = 0;
else {
bcopy(sc->buf + len, sc->buf, sc->buflen - len);
sc->buflen -= len;
}
/* If there's no data left, end the read. */
if (sc->buflen == 0)
break;
}
AT91_PIO_UNLOCK(sc);
return (err);
}
static void
at91_pio_bang32(struct at91_pio_softc *sc, uint32_t bits, uint32_t datapin,
uint32_t clockpin)
{
int i;
for (i = 0; i < 32; i++) {
if (bits & 0x80000000)
WR4(sc, PIO_SODR, datapin);
else
WR4(sc, PIO_CODR, datapin);
bits <<= 1;
WR4(sc, PIO_CODR, clockpin);
WR4(sc, PIO_SODR, clockpin);
}
}
static void
at91_pio_bang(struct at91_pio_softc *sc, uint8_t bits, uint32_t bitcount,
uint32_t datapin, uint32_t clockpin)
{
int i;
for (i = 0; i < bitcount; i++) {
if (bits & 0x80)
WR4(sc, PIO_SODR, datapin);
else
WR4(sc, PIO_CODR, datapin);
bits <<= 1;
WR4(sc, PIO_CODR, clockpin);
WR4(sc, PIO_SODR, clockpin);
}
}
static int
at91_pio_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
struct thread *td)
{
struct at91_pio_softc *sc;
struct at91_gpio_cfg *cfg;
struct at91_gpio_info *info;
struct at91_gpio_bang *bang;
struct at91_gpio_bang_many *bangmany;
uint32_t i, num;
uint8_t many[1024], *walker;
int err;
int bitcount;
sc = CDEV2SOFTC(dev);
switch(cmd) {
case AT91_GPIO_SET: /* turn bits on */
WR4(sc, PIO_SODR, *(uint32_t *)data);
return (0);
case AT91_GPIO_CLR: /* turn bits off */
WR4(sc, PIO_CODR, *(uint32_t *)data);
return (0);
case AT91_GPIO_READ: /* Get the status of input bits */
*(uint32_t *)data = RD4(sc, PIO_PDSR);
return (0);
case AT91_GPIO_CFG: /* Configure AT91_GPIO pins */
cfg = (struct at91_gpio_cfg *)data;
if (cfg->cfgmask & AT91_GPIO_CFG_INPUT) {
WR4(sc, PIO_OER, cfg->iomask & ~cfg->input);
WR4(sc, PIO_ODR, cfg->iomask & cfg->input);
}
if (cfg->cfgmask & AT91_GPIO_CFG_HI_Z) {
WR4(sc, PIO_MDDR, cfg->iomask & ~cfg->hi_z);
WR4(sc, PIO_MDER, cfg->iomask & cfg->hi_z);
}
if (cfg->cfgmask & AT91_GPIO_CFG_PULLUP) {
WR4(sc, PIO_PUDR, cfg->iomask & ~cfg->pullup);
WR4(sc, PIO_PUER, cfg->iomask & cfg->pullup);
}
if (cfg->cfgmask & AT91_GPIO_CFG_GLITCH) {
WR4(sc, PIO_IFDR, cfg->iomask & ~cfg->glitch);
WR4(sc, PIO_IFER, cfg->iomask & cfg->glitch);
}
if (cfg->cfgmask & AT91_GPIO_CFG_GPIO) {
WR4(sc, PIO_PDR, cfg->iomask & ~cfg->gpio);
WR4(sc, PIO_PER, cfg->iomask & cfg->gpio);
}
if (cfg->cfgmask & AT91_GPIO_CFG_PERIPH) {
WR4(sc, PIO_ASR, cfg->iomask & ~cfg->periph);
WR4(sc, PIO_BSR, cfg->iomask & cfg->periph);
}
if (cfg->cfgmask & AT91_GPIO_CFG_INTR) {
WR4(sc, PIO_IDR, cfg->iomask & ~cfg->intr);
WR4(sc, PIO_IER, cfg->iomask & cfg->intr);
}
return (0);
case AT91_GPIO_BANG:
bang = (struct at91_gpio_bang *)data;
at91_pio_bang32(sc, bang->bits, bang->datapin, bang->clockpin);
return (0);
case AT91_GPIO_BANG_MANY:
bangmany = (struct at91_gpio_bang_many *)data;
walker = (uint8_t *)bangmany->bits;
bitcount = bangmany->numbits;
while (bitcount > 0) {
num = MIN((bitcount + 7) / 8, sizeof(many));
err = copyin(walker, many, num);
if (err)
return err;
for (i = 0; i < num && bitcount > 0; i++, bitcount -= 8)
if (bitcount >= 8)
at91_pio_bang(sc, many[i], 8, bangmany->datapin, bangmany->clockpin);
else
at91_pio_bang(sc, many[i], bitcount, bangmany->datapin, bangmany->clockpin);
walker += num;
}
return (0);
case AT91_GPIO_INFO: /* Learn about this device's AT91_GPIO bits */
info = (struct at91_gpio_info *)data;
info->output_status = RD4(sc, PIO_ODSR);
info->input_status = RD4(sc, PIO_OSR);
info->highz_status = RD4(sc, PIO_MDSR);
info->pullup_status = RD4(sc, PIO_PUSR);
info->glitch_status = RD4(sc, PIO_IFSR);
info->enabled_status = RD4(sc, PIO_PSR);
info->periph_status = RD4(sc, PIO_ABSR);
info->intr_status = RD4(sc, PIO_IMR);
memset(info->extra_status, 0, sizeof(info->extra_status));
return (0);
}
return (ENOTTY);
}
/*
* The following functions are called early in the boot process, so
* don't use bus_space, as that isn't yet available when we need to use
* them.
*/
void
at91_pio_use_periph_a(uint32_t pio, uint32_t periph_a_mask, int use_pullup)
{
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
PIO[PIO_ASR / 4] = periph_a_mask;
PIO[PIO_PDR / 4] = periph_a_mask;
if (use_pullup)
PIO[PIO_PUER / 4] = periph_a_mask;
else
PIO[PIO_PUDR / 4] = periph_a_mask;
}
void
at91_pio_use_periph_b(uint32_t pio, uint32_t periph_b_mask, int use_pullup)
{
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
PIO[PIO_BSR / 4] = periph_b_mask;
PIO[PIO_PDR / 4] = periph_b_mask;
if (use_pullup)
PIO[PIO_PUER / 4] = periph_b_mask;
else
PIO[PIO_PUDR / 4] = periph_b_mask;
}
void
at91_pio_use_gpio(uint32_t pio, uint32_t gpio_mask)
{
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
PIO[PIO_PER / 4] = gpio_mask;
}
void
at91_pio_gpio_input(uint32_t pio, uint32_t input_enable_mask)
{
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
PIO[PIO_ODR / 4] = input_enable_mask;
}
void
at91_pio_gpio_output(uint32_t pio, uint32_t output_enable_mask, int use_pullup)
{
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
PIO[PIO_OER / 4] = output_enable_mask;
if (use_pullup)
PIO[PIO_PUER / 4] = output_enable_mask;
else
PIO[PIO_PUDR / 4] = output_enable_mask;
}
void
at91_pio_gpio_high_z(uint32_t pio, uint32_t high_z_mask, int enable)
{
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
if (enable)
PIO[PIO_MDER / 4] = high_z_mask;
else
PIO[PIO_MDDR / 4] = high_z_mask;
}
void
at91_pio_gpio_set(uint32_t pio, uint32_t data_mask)
{
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
PIO[PIO_SODR / 4] = data_mask;
}
void
at91_pio_gpio_clear(uint32_t pio, uint32_t data_mask)
{
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
PIO[PIO_CODR / 4] = data_mask;
}
uint32_t
at91_pio_gpio_get(uint32_t pio, uint32_t data_mask)
{
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
return (PIO[PIO_PDSR / 4] & data_mask);
}
void
at91_pio_gpio_set_deglitch(uint32_t pio, uint32_t data_mask, int use_deglitch)
{
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
if (use_deglitch)
PIO[PIO_IFER / 4] = data_mask;
else
PIO[PIO_IFDR / 4] = data_mask;
}
void
at91_pio_gpio_pullup(uint32_t pio, uint32_t data_mask, int do_pullup)
{
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
if (do_pullup)
PIO[PIO_PUER / 4] = data_mask;
else
PIO[PIO_PUDR / 4] = data_mask;
}
void
at91_pio_gpio_set_interrupt(uint32_t pio, uint32_t data_mask,
int enable_interrupt)
{
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
if (enable_interrupt)
PIO[PIO_IER / 4] = data_mask;
else
PIO[PIO_IDR / 4] = data_mask;
}
uint32_t
at91_pio_gpio_clear_interrupt(uint32_t pio)
{
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
/* Reading this register will clear the interrupts. */
return (PIO[PIO_ISR / 4]);
}
static void
at91_pio_new_pass(device_t dev)
{
device_printf(dev, "Pass %d\n", bus_current_pass);
}
static device_method_t at91_pio_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, at91_pio_probe),
DEVMETHOD(device_attach, at91_pio_attach),
DEVMETHOD(device_detach, at91_pio_detach),
DEVMETHOD(bus_new_pass, at91_pio_new_pass),
DEVMETHOD_END
};
static driver_t at91_pio_driver = {
"at91_pio",
at91_pio_methods,
sizeof(struct at91_pio_softc),
};
#ifdef FDT
EARLY_DRIVER_MODULE(at91_pio, at91_pinctrl, at91_pio_driver, at91_pio_devclass,
NULL, NULL, BUS_PASS_INTERRUPT);
#else
DRIVER_MODULE(at91_pio, atmelarm, at91_pio_driver, at91_pio_devclass, NULL, NULL);
#endif

View File

@ -1,183 +0,0 @@
/*
* Theses defines come from an atmel file that says specifically that it
* has no copyright.
*
* These defines are also usable for the AT91SAM9260 which has pin multiplexing
* that is identical to the AT91SAM9G20.
*/
/* $FreeBSD$ */
#ifndef ARM_AT91_AT91_PIO_SAM9G20_H
#define ARM_AT91_AT91_PIO_SAM9G20_H
#include <arm/at91/at91_pioreg.h>
// *****************************************************************************
// PIO DEFINITIONS FOR AT91SAM9G20
// *****************************************************************************
#define AT91C_PA0_SPI0_MISO (AT91C_PIO_PA0) // SPI 0 Master In Slave
#define AT91C_PA0_MCDB0 (AT91C_PIO_PA0) // Multimedia Card B Data 0
#define AT91C_PA1_SPI0_MOSI (AT91C_PIO_PA1) // SPI 0 Master Out Slave
#define AT91C_PA1_MCCDB (AT91C_PIO_PA1) // Multimedia Card B Command
#define AT91C_PA10_MCDA2 (AT91C_PIO_PA10) // Multimedia Card A Data 2
#define AT91C_PA10_ETX2_0 (AT91C_PIO_PA10) // Ethernet MAC Transmit Data 2
#define AT91C_PA11_MCDA3 (AT91C_PIO_PA11) // Multimedia Card A Data 3
#define AT91C_PA11_ETX3_0 (AT91C_PIO_PA11) // Ethernet MAC Transmit Data 3
#define AT91C_PA12_ETX0 (AT91C_PIO_PA12) // Ethernet MAC Transmit Data 0
#define AT91C_PA13_ETX1 (AT91C_PIO_PA13) // Ethernet MAC Transmit Data 1
#define AT91C_PA14_ERX0 (AT91C_PIO_PA14) // Ethernet MAC Receive Data 0
#define AT91C_PA15_ERX1 (AT91C_PIO_PA15) // Ethernet MAC Receive Data 1
#define AT91C_PA16_ETXEN (AT91C_PIO_PA16) // Ethernet MAC Transmit Enable
#define AT91C_PA17_ERXDV (AT91C_PIO_PA17) // Ethernet MAC Receive Data Valid
#define AT91C_PA18_ERXER (AT91C_PIO_PA18) // Ethernet MAC Receive Error
#define AT91C_PA19_ETXCK (AT91C_PIO_PA19) // Ethernet MAC Transmit Clock/Reference Clock
#define AT91C_PA2_SPI0_SPCK (AT91C_PIO_PA2) // SPI 0 Serial Clock
#define AT91C_PA20_EMDC (AT91C_PIO_PA20) // Ethernet MAC Management Data Clock
#define AT91C_PA21_EMDIO (AT91C_PIO_PA21) // Ethernet MAC Management Data Input/Output
#define AT91C_PA22_ADTRG (AT91C_PIO_PA22) // ADC Trigger
#define AT91C_PA22_ETXER (AT91C_PIO_PA22) // Ethernet MAC Transmikt Coding Error
#define AT91C_PA23_TWD (AT91C_PIO_PA23) // TWI Two-wire Serial Data
#define AT91C_PA23_ETX2_1 (AT91C_PIO_PA23) // Ethernet MAC Transmit Data 2
#define AT91C_PA24_TWCK (AT91C_PIO_PA24) // TWI Two-wire Serial Clock
#define AT91C_PA24_ETX3_1 (AT91C_PIO_PA24) // Ethernet MAC Transmit Data 3
#define AT91C_PA25_TCLK0 (AT91C_PIO_PA25) // Timer Counter 0 external clock input
#define AT91C_PA25_ERX2 (AT91C_PIO_PA25) // Ethernet MAC Receive Data 2
#define AT91C_PA26_TIOA0 (AT91C_PIO_PA26) // Timer Counter 0 Multipurpose Timer I/O Pin A
#define AT91C_PA26_ERX3 (AT91C_PIO_PA26) // Ethernet MAC Receive Data 3
#define AT91C_PA27_TIOA1 (AT91C_PIO_PA27) // Timer Counter 1 Multipurpose Timer I/O Pin A
#define AT91C_PA27_ERXCK (AT91C_PIO_PA27) // Ethernet MAC Receive Clock
#define AT91C_PA28_TIOA2 (AT91C_PIO_PA28) // Timer Counter 2 Multipurpose Timer I/O Pin A
#define AT91C_PA28_ECRS (AT91C_PIO_PA28) // Ethernet MAC Carrier Sense/Carrier Sense and Data Valid
#define AT91C_PA29_SCK1 (AT91C_PIO_PA29) // USART 1 Serial Clock
#define AT91C_PA29_ECOL (AT91C_PIO_PA29) // Ethernet MAC Collision Detected
#define AT91C_PA3_SPI0_NPCS0 (AT91C_PIO_PA3) // SPI 0 Peripheral Chip Select 0
#define AT91C_PA3_MCDB3 (AT91C_PIO_PA3) // Multimedia Card B Data 3
#define AT91C_PA30_SCK2 (AT91C_PIO_PA30) // USART 2 Serial Clock
#define AT91C_PA30_RXD4 (AT91C_PIO_PA30) // USART 4 Receive Data
#define AT91C_PA31_SCK0 (AT91C_PIO_PA31) // USART 0 Serial Clock
#define AT91C_PA31_TXD4 (AT91C_PIO_PA31) // USART 4 Transmit Data
#define AT91C_PA4_RTS2 (AT91C_PIO_PA4) // USART 2 Ready To Send
#define AT91C_PA4_MCDB2 (AT91C_PIO_PA4) // Multimedia Card B Data 2
#define AT91C_PA5_CTS2 (AT91C_PIO_PA5) // USART 2 Clear To Send
#define AT91C_PA5_MCDB1 (AT91C_PIO_PA5) // Multimedia Card B Data 1
#define AT91C_PA6_MCDA0 (AT91C_PIO_PA6) // Multimedia Card A Data 0
#define AT91C_PA7_MCCDA (AT91C_PIO_PA7) // Multimedia Card A Command
#define AT91C_PA8_MCCK (AT91C_PIO_PA8) // Multimedia Card Clock
#define AT91C_PA9_MCDA1 (AT91C_PIO_PA9) // Multimedia Card A Data 1
#define AT91C_PB0_SPI1_MISO (AT91C_PIO_PB0) // SPI 1 Master In Slave
#define AT91C_PB0_TIOA3 (AT91C_PIO_PB0) // Timer Counter 3 Multipurpose Timer I/O Pin A
#define AT91C_PB1_SPI1_MOSI (AT91C_PIO_PB1) // SPI 1 Master Out Slave
#define AT91C_PB1_TIOB3 (AT91C_PIO_PB1) // Timer Counter 3 Multipurpose Timer I/O Pin B
#define AT91C_PB10_TXD3 (AT91C_PIO_PB10) // USART 3 Transmit Data
#define AT91C_PB10_ISI_D8 (AT91C_PIO_PB10) // Image Sensor Data 8
#define AT91C_PB11_RXD3 (AT91C_PIO_PB11) // USART 3 Receive Data
#define AT91C_PB11_ISI_D9 (AT91C_PIO_PB11) // Image Sensor Data 9
#define AT91C_PB12_TXD5 (AT91C_PIO_PB12) // USART 5 Transmit Data
#define AT91C_PB12_ISI_D10 (AT91C_PIO_PB12) // Image Sensor Data 10
#define AT91C_PB13_RXD5 (AT91C_PIO_PB13) // USART 5 Receive Data
#define AT91C_PB13_ISI_D11 (AT91C_PIO_PB13) // Image Sensor Data 11
#define AT91C_PB14_DRXD (AT91C_PIO_PB14) // DBGU Debug Receive Data
#define AT91C_PB15_DTXD (AT91C_PIO_PB15) // DBGU Debug Transmit Data
#define AT91C_PB16_TK0 (AT91C_PIO_PB16) // SSC0 Transmit Clock
#define AT91C_PB16_TCLK3 (AT91C_PIO_PB16) // Timer Counter 3 external clock input
#define AT91C_PB17_TF0 (AT91C_PIO_PB17) // SSC0 Transmit Frame Sync
#define AT91C_PB17_TCLK4 (AT91C_PIO_PB17) // Timer Counter 4 external clock input
#define AT91C_PB18_TD0 (AT91C_PIO_PB18) // SSC0 Transmit data
#define AT91C_PB18_TIOB4 (AT91C_PIO_PB18) // Timer Counter 4 Multipurpose Timer I/O Pin B
#define AT91C_PB19_RD0 (AT91C_PIO_PB19) // SSC0 Receive Data
#define AT91C_PB19_TIOB5 (AT91C_PIO_PB19) // Timer Counter 5 Multipurpose Timer I/O Pin B
#define AT91C_PB2_SPI1_SPCK (AT91C_PIO_PB2) // SPI 1 Serial Clock
#define AT91C_PB2_TIOA4 (AT91C_PIO_PB2) // Timer Counter 4 Multipurpose Timer I/O Pin A
#define AT91C_PB20_RK0 (AT91C_PIO_PB20) // SSC0 Receive Clock
#define AT91C_PB20_ISI_D0 (AT91C_PIO_PB20) // Image Sensor Data 0
#define AT91C_PB21_RF0 (AT91C_PIO_PB21) // SSC0 Receive Frame Sync
#define AT91C_PB21_ISI_D1 (AT91C_PIO_PB21) // Image Sensor Data 1
#define AT91C_PB22_DSR0 (AT91C_PIO_PB22) // USART 0 Data Set ready
#define AT91C_PB22_ISI_D2 (AT91C_PIO_PB22) // Image Sensor Data 2
#define AT91C_PB23_DCD0 (AT91C_PIO_PB23) // USART 0 Data Carrier Detect
#define AT91C_PB23_ISI_D3 (AT91C_PIO_PB23) // Image Sensor Data 3
#define AT91C_PB24_DTR0 (AT91C_PIO_PB24) // USART 0 Data Terminal ready
#define AT91C_PB24_ISI_D4 (AT91C_PIO_PB24) // Image Sensor Data 4
#define AT91C_PB25_RI0 (AT91C_PIO_PB25) // USART 0 Ring Indicator
#define AT91C_PB25_ISI_D5 (AT91C_PIO_PB25) // Image Sensor Data 5
#define AT91C_PB26_RTS0 (AT91C_PIO_PB26) // USART 0 Ready To Send
#define AT91C_PB26_ISI_D6 (AT91C_PIO_PB26) // Image Sensor Data 6
#define AT91C_PB27_CTS0 (AT91C_PIO_PB27) // USART 0 Clear To Send
#define AT91C_PB27_ISI_D7 (AT91C_PIO_PB27) // Image Sensor Data 7
#define AT91C_PB28_RTS1 (AT91C_PIO_PB28) // USART 1 Ready To Send
#define AT91C_PB28_ISI_PCK (AT91C_PIO_PB28) // Image Sensor Data Clock
#define AT91C_PB29_CTS1 (AT91C_PIO_PB29) // USART 1 Clear To Send
#define AT91C_PB29_ISI_VSYNC (AT91C_PIO_PB29) // Image Sensor Vertical Synchro
#define AT91C_PB3_SPI1_NPCS0 (AT91C_PIO_PB3) // SPI 1 Peripheral Chip Select 0
#define AT91C_PB3_TIOA5 (AT91C_PIO_PB3) // Timer Counter 5 Multipurpose Timer I/O Pin A
#define AT91C_PB30_PCK0_0 (AT91C_PIO_PB30) // PMC Programmable Clock Output 0
#define AT91C_PB30_ISI_HSYNC (AT91C_PIO_PB30) // Image Sensor Horizontal Synchro
#define AT91C_PB31_PCK1_0 (AT91C_PIO_PB31) // PMC Programmable Clock Output 1
#define AT91C_PB31_ISI_MCK (AT91C_PIO_PB31) // Image Sensor Reference Clock
#define AT91C_PB4_TXD0 (AT91C_PIO_PB4) // USART 0 Transmit Data
#define AT91C_PB5_RXD0 (AT91C_PIO_PB5) // USART 0 Receive Data
#define AT91C_PB6_TXD1 (AT91C_PIO_PB6) // USART 1 Transmit Data
#define AT91C_PB6_TCLK1 (AT91C_PIO_PB6) // Timer Counter 1 external clock input
#define AT91C_PB7_RXD1 (AT91C_PIO_PB7) // USART 1 Receive Data
#define AT91C_PB7_TCLK2 (AT91C_PIO_PB7) // Timer Counter 2 external clock input
#define AT91C_PB8_TXD2 (AT91C_PIO_PB8) // USART 2 Transmit Data
#define AT91C_PB9_RXD2 (AT91C_PIO_PB9) // USART 2 Receive Data
#define AT91C_PC0_AD0 (AT91C_PIO_PC0) // ADC Analog Input 0
#define AT91C_PC0_SCK3 (AT91C_PIO_PC0) // USART 3 Serial Clock
#define AT91C_PC1_AD1 (AT91C_PIO_PC1) // ADC Analog Input 1
#define AT91C_PC1_PCK0_1 (AT91C_PIO_PC1) // PMC Programmable Clock Output 0
#define AT91C_PC10_A25_CFR NW (AT91C_PIO_PC10) // Address Bus[25]
#define AT91C_PC10_CTS3 (AT91C_PIO_PC10) // USART 3 Clear To Send
#define AT91C_PC11_NCS2 (AT91C_PIO_PC11) // Chip Select Line 2
#define AT91C_PC11_SPI0_NPCS1 (AT91C_PIO_PC11) // SPI 0 Peripheral Chip Select 1
#define AT91C_PC12_IRQ0 (AT91C_PIO_PC12) // External Interrupt 0
#define AT91C_PC12_NCS7 (AT91C_PIO_PC12) // Chip Select Line 7
#define AT91C_PC13_FIQ (AT91C_PIO_PC13) // AIC Fast Interrupt Input
#define AT91C_PC13_NCS6 (AT91C_PIO_PC13) // Chip Select Line 6
#define AT91C_PC14_NCS3_NANDCS (AT91C_PIO_PC14) // Chip Select Line 3
#define AT91C_PC14_IRQ2 (AT91C_PIO_PC14) // External Interrupt 2
#define AT91C_PC15_NWAIT (AT91C_PIO_PC15) // External Wait Signal
#define AT91C_PC15_IRQ1 (AT91C_PIO_PC15) // External Interrupt 1
#define AT91C_PC16_D16 (AT91C_PIO_PC16) // Data Bus[16]
#define AT91C_PC16_SPI0_NPCS2 (AT91C_PIO_PC16) // SPI 0 Peripheral Chip Select 2
#define AT91C_PC17_D17 (AT91C_PIO_PC17) // Data Bus[17]
#define AT91C_PC17_SPI0_NPCS3 (AT91C_PIO_PC17) // SPI 0 Peripheral Chip Select 3
#define AT91C_PC18_D18 (AT91C_PIO_PC18) // Data Bus[18]
#define AT91C_PC18_SPI1_NPCS1_1 (AT91C_PIO_PC18) // SPI 1 Peripheral Chip Select 1
#define AT91C_PC19_D19 (AT91C_PIO_PC19) // Data Bus[19]
#define AT91C_PC19_SPI1_NPCS2_1 (AT91C_PIO_PC19) // SPI 1 Peripheral Chip Select 2
#define AT91C_PC2_AD2 (AT91C_PIO_PC2) // ADC Analog Input 2
#define AT91C_PC2_PCK1_1 (AT91C_PIO_PC2) // PMC Programmable Clock Output 1
#define AT91C_PC20_D20 (AT91C_PIO_PC20) // Data Bus[20]
#define AT91C_PC20_SPI1_NPCS3_1 (AT91C_PIO_PC20) // SPI 1 Peripheral Chip Select 3
#define AT91C_PC21_D21 (AT91C_PIO_PC21) // Data Bus[21]
#define AT91C_PC21_EF100 (AT91C_PIO_PC21) // Ethernet MAC Force 100 Mbits/sec
#define AT91C_PC22_D22 (AT91C_PIO_PC22) // Data Bus[22]
#define AT91C_PC22_TCLK5 (AT91C_PIO_PC22) // Timer Counter 5 external clock input
#define AT91C_PC23_D23 (AT91C_PIO_PC23) // Data Bus[23]
#define AT91C_PC24_D24 (AT91C_PIO_PC24) // Data Bus[24]
#define AT91C_PC25_D25 (AT91C_PIO_PC25) // Data Bus[25]
#define AT91C_PC26_D26 (AT91C_PIO_PC26) // Data Bus[26]
#define AT91C_PC27_D27 (AT91C_PIO_PC27) // Data Bus[27]
#define AT91C_PC28_D28 (AT91C_PIO_PC28) // Data Bus[28]
#define AT91C_PC29_D29 (AT91C_PIO_PC29) // Data Bus[29]
#define AT91C_PC3_AD3 (AT91C_PIO_PC3) // ADC Analog Input 3
#define AT91C_PC3_SPI1_NPCS3_0 (AT91C_PIO_PC3) // SPI 1 Peripheral Chip Select 3
#define AT91C_PC30_D30 (AT91C_PIO_PC30) // Data Bus[30]
#define AT91C_PC31_D31 (AT91C_PIO_PC31) // Data Bus[31]
#define AT91C_PC4_A23 (AT91C_PIO_PC4) // Address Bus[23]
#define AT91C_PC4_SPI1_NPCS2_0 (AT91C_PIO_PC4) // SPI 1 Peripheral Chip Select 2
#define AT91C_PC5_A24 (AT91C_PIO_PC5) // Address Bus[24]
#define AT91C_PC5_SPI1_NPCS1_0 (AT91C_PIO_PC5) // SPI 1 Peripheral Chip Select 1
#define AT91C_PC6_TIOB2 (AT91C_PIO_PC6) // Timer Counter 2 Multipurpose Timer I/O Pin B
#define AT91C_PC6_CFCE1 (AT91C_PIO_PC6) // Compact Flash Enable 1
#define AT91C_PC7_TIOB1 (AT91C_PIO_PC7) // Timer Counter 1 Multipurpose Timer I/O Pin B
#define AT91C_PC7_CFCE2 (AT91C_PIO_PC7) // Compact Flash Enable 2
#define AT91C_PC8_NCS4_CFCS0 (AT91C_PIO_PC8) // Chip Select Line 4
#define AT91C_PC8_RTS3 (AT91C_PIO_PC8) // USART 3 Ready To Send
#define AT91C_PC9_NCS5_CFCS1 (AT91C_PIO_PC9) // Chip Select Line 5
#define AT91C_PC9_TIOB0 (AT91C_PIO_PC9) // Timer Counter 0 Multipurpose Timer I/O Pin B
#endif /* ARM_AT91_AT91_PIO_SAM9G20_H */

View File

@ -1,274 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support - ROUSSET -
* ----------------------------------------------------------------------------
* Copyright (c) 2009, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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 AT91LIB version 1.9 boards/at91sam9g45-ek/at91sam9g45/AT91SAM9G45.h
*/
/* $FreeBSD$ */
#ifndef ARM_AT91_AT91_PIO_SAM9G45_H
#define ARM_AT91_AT91_PIO_SAM9G45_H
#include <arm/at91/at91_pioreg.h>
// *****************************************************************************
// PIO DEFINITIONS FOR AT91SAM9G45
// *****************************************************************************
#define AT91C_PA0_MCI0_CK (AT91C_PIO_PA0) //
#define AT91C_PA0_TCLK3 (AT91C_PIO_PA0) //
#define AT91C_PA1_MCI0_CDA (AT91C_PIO_PA1) //
#define AT91C_PA1_TIOA3 (AT91C_PIO_PA1) //
#define AT91C_PA10_ETX0 (AT91C_PIO_PA10) // Ethernet MAC Transmit Data 0
#define AT91C_PA11_ETX1 (AT91C_PIO_PA11) // Ethernet MAC Transmit Data 1
#define AT91C_PA12_ERX0 (AT91C_PIO_PA12) // Ethernet MAC Receive Data 0
#define AT91C_PA13_ERX1 (AT91C_PIO_PA13) // Ethernet MAC Receive Data 1
#define AT91C_PA14_ETXEN (AT91C_PIO_PA14) // Ethernet MAC Transmit Enable
#define AT91C_PA15_ERXDV (AT91C_PIO_PA15) // Ethernet MAC Receive Data Valid
#define AT91C_PA16_ERXER (AT91C_PIO_PA16) // Ethernet MAC Receive Error
#define AT91C_PA17_ETXCK_EREFCK (AT91C_PIO_PA17) // Ethernet MAC Transmit Clock/Reference Clock
#define AT91C_PA18_EMDC (AT91C_PIO_PA18) // Ethernet MAC Management Data Clock
#define AT91C_PA19_EMDIO (AT91C_PIO_PA19) // Ethernet MAC Management Data Input/Output
#define AT91C_PA2_MCI0_DA0 (AT91C_PIO_PA2) //
#define AT91C_PA2_TIOB3 (AT91C_PIO_PA2) //
#define AT91C_PA20_TWD0 (AT91C_PIO_PA20) // TWI Two-wire Serial Data
#define AT91C_PA21_TWCK0 (AT91C_PIO_PA21) // TWI Two-wire Serial Clock
#define AT91C_PA22_MCI1_CDA (AT91C_PIO_PA22) //
#define AT91C_PA22_SCK3 (AT91C_PIO_PA22) //
#define AT91C_PA23_MCI1_DA0 (AT91C_PIO_PA23) //
#define AT91C_PA23_RTS3 (AT91C_PIO_PA23) //
#define AT91C_PA24_MCI1_DA1 (AT91C_PIO_PA24) //
#define AT91C_PA24_CTS3 (AT91C_PIO_PA24) //
#define AT91C_PA25_MCI1_DA2 (AT91C_PIO_PA25) //
#define AT91C_PA25_PWM3 (AT91C_PIO_PA25) //
#define AT91C_PA26_MCI1_DA3 (AT91C_PIO_PA26) //
#define AT91C_PA26_TIOB2 (AT91C_PIO_PA26) //
#define AT91C_PA27_MCI1_DA4 (AT91C_PIO_PA27) //
#define AT91C_PA27_ETXER (AT91C_PIO_PA27) // Ethernet MAC Transmikt Coding Error
#define AT91C_PA28_MCI1_DA5 (AT91C_PIO_PA28) //
#define AT91C_PA28_ERXCK (AT91C_PIO_PA28) // Ethernet MAC Receive Clock
#define AT91C_PA29_MCI1_DA6 (AT91C_PIO_PA29) //
#define AT91C_PA29_ECRS (AT91C_PIO_PA29) // Ethernet MAC Carrier Sense/Carrier Sense and Data Valid
#define AT91C_PA3_MCI0_DA1 (AT91C_PIO_PA3) //
#define AT91C_PA3_TCLK4 (AT91C_PIO_PA3) //
#define AT91C_PA30_MCI1_DA7 (AT91C_PIO_PA30) //
#define AT91C_PA30_ECOL (AT91C_PIO_PA30) // Ethernet MAC Collision Detected
#define AT91C_PA31_MCI1_CK (AT91C_PIO_PA31) //
#define AT91C_PA31_PCK0 (AT91C_PIO_PA31) //
#define AT91C_PA4_MCI0_DA2 (AT91C_PIO_PA4) //
#define AT91C_PA4_TIOA4 (AT91C_PIO_PA4) //
#define AT91C_PA5_MCI0_DA3 (AT91C_PIO_PA5) //
#define AT91C_PA5_TIOB4 (AT91C_PIO_PA5) //
#define AT91C_PA6_MCI0_DA4 (AT91C_PIO_PA6) //
#define AT91C_PA6_ETX2 (AT91C_PIO_PA6) // Ethernet MAC Transmit Data 2
#define AT91C_PA7_MCI0_DA5 (AT91C_PIO_PA7) //
#define AT91C_PA7_ETX3 (AT91C_PIO_PA7) // Ethernet MAC Transmit Data 3
#define AT91C_PA8_MCI0_DA6 (AT91C_PIO_PA8) //
#define AT91C_PA8_ERX2 (AT91C_PIO_PA8) // Ethernet MAC Receive Data 2
#define AT91C_PA9_MCI0_DA7 (AT91C_PIO_PA9) //
#define AT91C_PA9_ERX3 (AT91C_PIO_PA9) // Ethernet MAC Receive Data 3
#define AT91C_PB0_SPI0_MISO (AT91C_PIO_PB0) // SPI 0 Master In Slave
#define AT91C_PB1_SPI0_MOSI (AT91C_PIO_PB1) // SPI 0 Master Out Slave
#define AT91C_PB10_TWD1 (AT91C_PIO_PB10) //
#define AT91C_PB10_ISI_D10 (AT91C_PIO_PB10) //
#define AT91C_PB11_TWCK1 (AT91C_PIO_PB11) //
#define AT91C_PB11_ISI_D11 (AT91C_PIO_PB11) //
#define AT91C_PB12_DRXD (AT91C_PIO_PB12) //
#define AT91C_PB13_DTXD (AT91C_PIO_PB13) //
#define AT91C_PB14_SPI1_MISO (AT91C_PIO_PB14) //
#define AT91C_PB15_SPI1_MOSI (AT91C_PIO_PB15) //
#define AT91C_PB15_CTS0 (AT91C_PIO_PB15) //
#define AT91C_PB16_SPI1_SPCK (AT91C_PIO_PB16) //
#define AT91C_PB16_SCK0 (AT91C_PIO_PB16) //
#define AT91C_PB17_SPI1_NPCS0 (AT91C_PIO_PB17) //
#define AT91C_PB17_RTS0 (AT91C_PIO_PB17) //
#define AT91C_PB18_RXD0 (AT91C_PIO_PB18) //
#define AT91C_PB18_SPI0_NPCS1 (AT91C_PIO_PB18) //
#define AT91C_PB19_TXD0 (AT91C_PIO_PB19) //
#define AT91C_PB19_SPI0_NPCS2 (AT91C_PIO_PB19) //
#define AT91C_PB2_SPI0_SPCK (AT91C_PIO_PB2) // SPI 0 Serial Clock
#define AT91C_PB20_ISI_D0 (AT91C_PIO_PB20) //
#define AT91C_PB21_ISI_D1 (AT91C_PIO_PB21) //
#define AT91C_PB22_ISI_D2 (AT91C_PIO_PB22) //
#define AT91C_PB23_ISI_D3 (AT91C_PIO_PB23) //
#define AT91C_PB24_ISI_D4 (AT91C_PIO_PB24) //
#define AT91C_PB25_ISI_D5 (AT91C_PIO_PB25) //
#define AT91C_PB26_ISI_D6 (AT91C_PIO_PB26) //
#define AT91C_PB27_ISI_D7 (AT91C_PIO_PB27) //
#define AT91C_PB28_ISI_PCK (AT91C_PIO_PB28) //
#define AT91C_PB29_ISI_VSYNC (AT91C_PIO_PB29) //
#define AT91C_PB3_SPI0_NPCS0 (AT91C_PIO_PB3) // SPI 0 Peripheral Chip Select 0
#define AT91C_PB30_ISI_HSYNC (AT91C_PIO_PB30) //
#define AT91C_PB31_ (AT91C_PIO_PB31) //
#define AT91C_PB31_PCK1 (AT91C_PIO_PB31) //
#define AT91C_PB4_TXD1 (AT91C_PIO_PB4) // USART 1 Transmit Data
#define AT91C_PB5_RXD1 (AT91C_PIO_PB5) // USART 1 Receive Data
#define AT91C_PB6_TXD2 (AT91C_PIO_PB6) // USART 2 Transmit Data
#define AT91C_PB7_RXD2 (AT91C_PIO_PB7) // USART 2 Receive Data
#define AT91C_PB8_TXD3 (AT91C_PIO_PB8) // USART 3 Transmit Data
#define AT91C_PB8_ISI_D8 (AT91C_PIO_PB8) //
#define AT91C_PB9_RXD3 (AT91C_PIO_PB9) // USART 3 Receive Data
#define AT91C_PB9_ISI_D9 (AT91C_PIO_PB9) //
#define AT91C_PC0_DQM2 (AT91C_PIO_PC0) // DQM2
#define AT91C_PC1_DQM3 (AT91C_PIO_PC1) // DQM3
#define AT91C_PC10_NCS4_CFCS0 (AT91C_PIO_PC10) //
#define AT91C_PC10_TCLK2 (AT91C_PIO_PC10) //
#define AT91C_PC11_NCS5_CFCS1 (AT91C_PIO_PC11) //
#define AT91C_PC11_CTS2 (AT91C_PIO_PC11) //
#define AT91C_PC12_A25_CFRNW (AT91C_PIO_PC12) //
#define AT91C_PC13_NCS2 (AT91C_PIO_PC13) //
#define AT91C_PC14_NCS3_NANDCS (AT91C_PIO_PC14) //
#define AT91C_PC15_NWAIT (AT91C_PIO_PC15) //
#define AT91C_PC16_D16 (AT91C_PIO_PC16) //
#define AT91C_PC17_D17 (AT91C_PIO_PC17) //
#define AT91C_PC18_D18 (AT91C_PIO_PC18) //
#define AT91C_PC19_D19 (AT91C_PIO_PC19) //
#define AT91C_PC2_A19 (AT91C_PIO_PC2) //
#define AT91C_PC20_D20 (AT91C_PIO_PC20) //
#define AT91C_PC21_D21 (AT91C_PIO_PC21) //
#define AT91C_PC22_D22 (AT91C_PIO_PC22) //
#define AT91C_PC23_D23 (AT91C_PIO_PC23) //
#define AT91C_PC24_D24 (AT91C_PIO_PC24) //
#define AT91C_PC25_D25 (AT91C_PIO_PC25) //
#define AT91C_PC26_D26 (AT91C_PIO_PC26) //
#define AT91C_PC27_D27 (AT91C_PIO_PC27) //
#define AT91C_PC28_D28 (AT91C_PIO_PC28) //
#define AT91C_PC29_D29 (AT91C_PIO_PC29) //
#define AT91C_PC3_A20 (AT91C_PIO_PC3) //
#define AT91C_PC30_D30 (AT91C_PIO_PC30) //
#define AT91C_PC31_D31 (AT91C_PIO_PC31) //
#define AT91C_PC4_A21_NANDALE (AT91C_PIO_PC4) //
#define AT91C_PC5_A22_NANDCLE (AT91C_PIO_PC5) //
#define AT91C_PC6_A23 (AT91C_PIO_PC6) //
#define AT91C_PC7_A24 (AT91C_PIO_PC7) //
#define AT91C_PC8_CFCE1 (AT91C_PIO_PC8) //
#define AT91C_PC9_CFCE2 (AT91C_PIO_PC9) //
#define AT91C_PC9_RTS2 (AT91C_PIO_PC9) //
#define AT91C_PD0_TK0 (AT91C_PIO_PD0) //
#define AT91C_PD0_PWM3 (AT91C_PIO_PD0) //
#define AT91C_PD1_TF0 (AT91C_PIO_PD1) //
#define AT91C_PD10_TD1 (AT91C_PIO_PD10) //
#define AT91C_PD11_RD1 (AT91C_PIO_PD11) //
#define AT91C_PD12_TK1 (AT91C_PIO_PD12) //
#define AT91C_PD12_PCK0 (AT91C_PIO_PD12) //
#define AT91C_PD13_RK1 (AT91C_PIO_PD13) //
#define AT91C_PD14_TF1 (AT91C_PIO_PD14) //
#define AT91C_PD15_RF1 (AT91C_PIO_PD15) //
#define AT91C_PD16_RTS1 (AT91C_PIO_PD16) //
#define AT91C_PD17_CTS1 (AT91C_PIO_PD17) //
#define AT91C_PD18_SPI1_NPCS2 (AT91C_PIO_PD18) //
#define AT91C_PD18_IRQ (AT91C_PIO_PD18) //
#define AT91C_PD19_SPI1_NPCS3 (AT91C_PIO_PD19) //
#define AT91C_PD19_FIQ (AT91C_PIO_PD19) //
#define AT91C_PD2_TD0 (AT91C_PIO_PD2) //
#define AT91C_PD20_TIOA0 (AT91C_PIO_PD20) //
#define AT91C_PD21_TIOA1 (AT91C_PIO_PD21) //
#define AT91C_PD22_TIOA2 (AT91C_PIO_PD22) //
#define AT91C_PD23_TCLK0 (AT91C_PIO_PD23) //
#define AT91C_PD24_SPI0_NPCS1 (AT91C_PIO_PD24) //
#define AT91C_PD24_PWM0 (AT91C_PIO_PD24) //
#define AT91C_PD25_SPI0_NPCS2 (AT91C_PIO_PD25) //
#define AT91C_PD25_PWM1 (AT91C_PIO_PD25) //
#define AT91C_PD26_PCK0 (AT91C_PIO_PD26) //
#define AT91C_PD26_PWM2 (AT91C_PIO_PD26) //
#define AT91C_PD27_PCK1 (AT91C_PIO_PD27) //
#define AT91C_PD27_SPI0_NPCS3 (AT91C_PIO_PD27) //
#define AT91C_PD28_TSADTRG (AT91C_PIO_PD28) //
#define AT91C_PD28_SPI1_NPCS1 (AT91C_PIO_PD28) //
#define AT91C_PD29_TCLK1 (AT91C_PIO_PD29) //
#define AT91C_PD29_SCK1 (AT91C_PIO_PD29) //
#define AT91C_PD3_RD0 (AT91C_PIO_PD3) //
#define AT91C_PD30_TIOB0 (AT91C_PIO_PD30) //
#define AT91C_PD30_SCK2 (AT91C_PIO_PD30) //
#define AT91C_PD31_TIOB1 (AT91C_PIO_PD31) //
#define AT91C_PD31_PWM1 (AT91C_PIO_PD31) //
#define AT91C_PD4_RK0 (AT91C_PIO_PD4) //
#define AT91C_PD5_RF0 (AT91C_PIO_PD5) //
#define AT91C_PD6_AC97RX (AT91C_PIO_PD6) //
#define AT91C_PD7_AC97TX (AT91C_PIO_PD7) //
#define AT91C_PD7_TIOA5 (AT91C_PIO_PD7) //
#define AT91C_PD8_AC97FS (AT91C_PIO_PD8) //
#define AT91C_PD8_TIOB5 (AT91C_PIO_PD8) //
#define AT91C_PD9_AC97CK (AT91C_PIO_PD9) //
#define AT91C_PD9_TCLK5 (AT91C_PIO_PD9) //
#define AT91C_PE0_LCDPWR (AT91C_PIO_PE0) //
#define AT91C_PE0_PCK0 (AT91C_PIO_PE0) //
#define AT91C_PE1_LCDMOD (AT91C_PIO_PE1) //
#define AT91C_PE10_LCDD3 (AT91C_PIO_PE10) //
#define AT91C_PE10_LCDD5 (AT91C_PIO_PE10) //
#define AT91C_PE11_LCDD4 (AT91C_PIO_PE11) //
#define AT91C_PE11_LCDD6 (AT91C_PIO_PE11) //
#define AT91C_PE12_LCDD5 (AT91C_PIO_PE12) //
#define AT91C_PE12_LCDD7 (AT91C_PIO_PE12) //
#define AT91C_PE13_LCDD6 (AT91C_PIO_PE13) //
#define AT91C_PE13_LCDD10 (AT91C_PIO_PE13) //
#define AT91C_PE14_LCDD7 (AT91C_PIO_PE14) //
#define AT91C_PE14_LCDD11 (AT91C_PIO_PE14) //
#define AT91C_PE15_LCDD8 (AT91C_PIO_PE15) //
#define AT91C_PE15_LCDD12 (AT91C_PIO_PE15) //
#define AT91C_PE16_LCDD9 (AT91C_PIO_PE16) //
#define AT91C_PE16_LCDD13 (AT91C_PIO_PE16) //
#define AT91C_PE17_LCDD10 (AT91C_PIO_PE17) //
#define AT91C_PE17_LCDD14 (AT91C_PIO_PE17) //
#define AT91C_PE18_LCDD11 (AT91C_PIO_PE18) //
#define AT91C_PE18_LCDD15 (AT91C_PIO_PE18) //
#define AT91C_PE19_LCDD12 (AT91C_PIO_PE19) //
#define AT91C_PE19_LCDD18 (AT91C_PIO_PE19) //
#define AT91C_PE2_LCDCC (AT91C_PIO_PE2) //
#define AT91C_PE20_LCDD13 (AT91C_PIO_PE20) //
#define AT91C_PE20_LCDD19 (AT91C_PIO_PE20) //
#define AT91C_PE21_LCDD14 (AT91C_PIO_PE21) //
#define AT91C_PE21_LCDD20 (AT91C_PIO_PE21) //
#define AT91C_PE22_LCDD15 (AT91C_PIO_PE22) //
#define AT91C_PE22_LCDD21 (AT91C_PIO_PE22) //
#define AT91C_PE23_LCDD16 (AT91C_PIO_PE23) //
#define AT91C_PE23_LCDD22 (AT91C_PIO_PE23) //
#define AT91C_PE24_LCDD17 (AT91C_PIO_PE24) //
#define AT91C_PE24_LCDD23 (AT91C_PIO_PE24) //
#define AT91C_PE25_LCDD18 (AT91C_PIO_PE25) //
#define AT91C_PE26_LCDD19 (AT91C_PIO_PE26) //
#define AT91C_PE27_LCDD20 (AT91C_PIO_PE27) //
#define AT91C_PE28_LCDD21 (AT91C_PIO_PE28) //
#define AT91C_PE29_LCDD22 (AT91C_PIO_PE29) //
#define AT91C_PE3_LCDVSYNC (AT91C_PIO_PE3) //
#define AT91C_PE30_LCDD23 (AT91C_PIO_PE30) //
#define AT91C_PE31_PWM2 (AT91C_PIO_PE31) //
#define AT91C_PE31_PCK1 (AT91C_PIO_PE31) //
#define AT91C_PE4_LCDHSYNC (AT91C_PIO_PE4) //
#define AT91C_PE5_LCDDOTCK (AT91C_PIO_PE5) //
#define AT91C_PE6_LCDDEN (AT91C_PIO_PE6) //
#define AT91C_PE7_LCDD0 (AT91C_PIO_PE7) //
#define AT91C_PE7_LCDD2 (AT91C_PIO_PE7) //
#define AT91C_PE8_LCDD1 (AT91C_PIO_PE8) //
#define AT91C_PE8_LCDD3 (AT91C_PIO_PE8) //
#define AT91C_PE9_LCDD2 (AT91C_PIO_PE9) //
#define AT91C_PE9_LCDD4 (AT91C_PIO_PE9) //
#endif /* ARM_AT91_AT91_PIO_SAM9G45_H */

View File

@ -1,234 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2006 M. Warner Losh.
*
* 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 ARM_AT91_AT91_PIOREG_H
#define ARM_AT91_AT91_PIOREG_H
#ifndef ATMEL_ENV
/* Registers */
#define PIO_PER 0x00 /* PIO Enable Register */
#define PIO_PDR 0x04 /* PIO Disable Register */
#define PIO_PSR 0x08 /* PIO Status Register */
/* 0x0c reserved */
#define PIO_OER 0x10 /* PIO Output Enable Register */
#define PIO_ODR 0x14 /* PIO Output Disable Register */
#define PIO_OSR 0x18 /* PIO Output Status Register */
/* 0x1c reserved */
#define PIO_IFER 0x20 /* PIO Glitch Input Enable Register */
#define PIO_IFDR 0x24 /* PIO Glitch Input Disable Register */
#define PIO_IFSR 0x28 /* PIO Glitch Input Status Register */
/* 0x2c reserved */
#define PIO_SODR 0x30 /* PIO Set Output Data Register */
#define PIO_CODR 0x34 /* PIO Clear Output Data Register */
#define PIO_ODSR 0x38 /* PIO Output Data Status Register */
#define PIO_PDSR 0x3c /* PIO Pin Data Status Register */
#define PIO_IER 0x40 /* PIO Interrupt Enable Register */
#define PIO_IDR 0x44 /* PIO Interrupt Disable Register */
#define PIO_IMR 0x48 /* PIO Interrupt Mask Register */
#define PIO_ISR 0x4c /* PIO Interrupt Status Register */
#define PIO_MDER 0x50 /* PIO Multi-Driver Enable Register */
#define PIO_MDDR 0x54 /* PIO Multi-Driver Disable Register */
#define PIO_MDSR 0x58 /* PIO Multi-Driver Status Register */
/* 0x5c reserved */
#define PIO_PUDR 0x60 /* PIO Pull-up Disable Register */
#define PIO_PUER 0x64 /* PIO Pull-up Enable Register */
#define PIO_PUSR 0x68 /* PIO Pull-up Status Register */
/* 0x6c reserved */
#define PIO_ASR 0x70 /* PIO Peripheral A Select Register */
#define PIO_BSR 0x74 /* PIO Peripheral B Select Register */
#define PIO_ABSR 0x78 /* PIO AB Status Register */
/* 0x7c-0x9c reserved */
#define PIO_OWER 0xa0 /* PIO Output Write Enable Register */
#define PIO_OWDR 0xa4 /* PIO Output Write Disable Register */
#define PIO_OWSR 0xa8 /* PIO Output Write Status Register */
/* 0xac reserved */
#endif
#define AT91C_PIO_PA0 ((unsigned int) 1 << 0) // Pin Controlled by PA0
#define AT91C_PIO_PA1 ((unsigned int) 1 << 1) // Pin Controlled by PA1
#define AT91C_PIO_PA2 ((unsigned int) 1 << 2) // Pin Controlled by PA2
#define AT91C_PIO_PA3 ((unsigned int) 1 << 3) // Pin Controlled by PA3
#define AT91C_PIO_PA4 ((unsigned int) 1 << 4) // Pin Controlled by PA4
#define AT91C_PIO_PA5 ((unsigned int) 1 << 5) // Pin Controlled by PA5
#define AT91C_PIO_PA6 ((unsigned int) 1 << 6) // Pin Controlled by PA6
#define AT91C_PIO_PA7 ((unsigned int) 1 << 7) // Pin Controlled by PA7
#define AT91C_PIO_PA8 ((unsigned int) 1 << 8) // Pin Controlled by PA8
#define AT91C_PIO_PA9 ((unsigned int) 1 << 9) // Pin Controlled by PA9
#define AT91C_PIO_PA10 ((unsigned int) 1 << 10) // Pin Controlled by PA10
#define AT91C_PIO_PA11 ((unsigned int) 1 << 11) // Pin Controlled by PA11
#define AT91C_PIO_PA12 ((unsigned int) 1 << 12) // Pin Controlled by PA12
#define AT91C_PIO_PA13 ((unsigned int) 1 << 13) // Pin Controlled by PA13
#define AT91C_PIO_PA14 ((unsigned int) 1 << 14) // Pin Controlled by PA14
#define AT91C_PIO_PA15 ((unsigned int) 1 << 15) // Pin Controlled by PA15
#define AT91C_PIO_PA16 ((unsigned int) 1 << 16) // Pin Controlled by PA16
#define AT91C_PIO_PA17 ((unsigned int) 1 << 17) // Pin Controlled by PA17
#define AT91C_PIO_PA18 ((unsigned int) 1 << 18) // Pin Controlled by PA18
#define AT91C_PIO_PA19 ((unsigned int) 1 << 19) // Pin Controlled by PA19
#define AT91C_PIO_PA20 ((unsigned int) 1 << 20) // Pin Controlled by PA20
#define AT91C_PIO_PA21 ((unsigned int) 1 << 21) // Pin Controlled by PA21
#define AT91C_PIO_PA22 ((unsigned int) 1 << 22) // Pin Controlled by PA22
#define AT91C_PIO_PA23 ((unsigned int) 1 << 23) // Pin Controlled by PA23
#define AT91C_PIO_PA24 ((unsigned int) 1 << 24) // Pin Controlled by PA24
#define AT91C_PIO_PA25 ((unsigned int) 1 << 25) // Pin Controlled by PA25
#define AT91C_PIO_PA26 ((unsigned int) 1 << 26) // Pin Controlled by PA26
#define AT91C_PIO_PA27 ((unsigned int) 1 << 27) // Pin Controlled by PA27
#define AT91C_PIO_PA28 ((unsigned int) 1 << 28) // Pin Controlled by PA28
#define AT91C_PIO_PA29 ((unsigned int) 1 << 29) // Pin Controlled by PA29
#define AT91C_PIO_PA30 ((unsigned int) 1 << 30) // Pin Controlled by PA30
#define AT91C_PIO_PA31 ((unsigned int) 1 << 31) // Pin Controlled by PA31
#define AT91C_PIO_PB0 ((unsigned int) 1 << 0) // Pin Controlled by PB0
#define AT91C_PIO_PB1 ((unsigned int) 1 << 1) // Pin Controlled by PB1
#define AT91C_PIO_PB2 ((unsigned int) 1 << 2) // Pin Controlled by PB2
#define AT91C_PIO_PB3 ((unsigned int) 1 << 3) // Pin Controlled by PB3
#define AT91C_PIO_PB4 ((unsigned int) 1 << 4) // Pin Controlled by PB4
#define AT91C_PIO_PB5 ((unsigned int) 1 << 5) // Pin Controlled by PB5
#define AT91C_PIO_PB6 ((unsigned int) 1 << 6) // Pin Controlled by PB6
#define AT91C_PIO_PB7 ((unsigned int) 1 << 7) // Pin Controlled by PB7
#define AT91C_PIO_PB8 ((unsigned int) 1 << 8) // Pin Controlled by PB8
#define AT91C_PIO_PB9 ((unsigned int) 1 << 9) // Pin Controlled by PB9
#define AT91C_PIO_PB10 ((unsigned int) 1 << 10) // Pin Controlled by PB10
#define AT91C_PIO_PB11 ((unsigned int) 1 << 11) // Pin Controlled by PB11
#define AT91C_PIO_PB12 ((unsigned int) 1 << 12) // Pin Controlled by PB12
#define AT91C_PIO_PB13 ((unsigned int) 1 << 13) // Pin Controlled by PB13
#define AT91C_PIO_PB14 ((unsigned int) 1 << 14) // Pin Controlled by PB14
#define AT91C_PIO_PB15 ((unsigned int) 1 << 15) // Pin Controlled by PB15
#define AT91C_PIO_PB16 ((unsigned int) 1 << 16) // Pin Controlled by PB16
#define AT91C_PIO_PB17 ((unsigned int) 1 << 17) // Pin Controlled by PB17
#define AT91C_PIO_PB18 ((unsigned int) 1 << 18) // Pin Controlled by PB18
#define AT91C_PIO_PB19 ((unsigned int) 1 << 19) // Pin Controlled by PB19
#define AT91C_PIO_PB20 ((unsigned int) 1 << 20) // Pin Controlled by PB20
#define AT91C_PIO_PB21 ((unsigned int) 1 << 21) // Pin Controlled by PB21
#define AT91C_PIO_PB22 ((unsigned int) 1 << 22) // Pin Controlled by PB22
#define AT91C_PIO_PB23 ((unsigned int) 1 << 23) // Pin Controlled by PB23
#define AT91C_PIO_PB24 ((unsigned int) 1 << 24) // Pin Controlled by PB24
#define AT91C_PIO_PB25 ((unsigned int) 1 << 25) // Pin Controlled by PB25
#define AT91C_PIO_PB26 ((unsigned int) 1 << 26) // Pin Controlled by PB26
#define AT91C_PIO_PB27 ((unsigned int) 1 << 27) // Pin Controlled by PB27
#define AT91C_PIO_PB28 ((unsigned int) 1 << 28) // Pin Controlled by PB28
#define AT91C_PIO_PB29 ((unsigned int) 1 << 29) // Pin Controlled by PB29
#define AT91C_PIO_PB30 ((unsigned int) 1 << 30) // Pin Controlled by PB30
#define AT91C_PIO_PB31 ((unsigned int) 1 << 31) // Pin Controlled by PB31
#define AT91C_PIO_PC0 ((unsigned int) 1 << 0) // Pin Controlled by PC0
#define AT91C_PIO_PC1 ((unsigned int) 1 << 1) // Pin Controlled by PC1
#define AT91C_PIO_PC2 ((unsigned int) 1 << 2) // Pin Controlled by PC2
#define AT91C_PIO_PC3 ((unsigned int) 1 << 3) // Pin Controlled by PC3
#define AT91C_PIO_PC4 ((unsigned int) 1 << 4) // Pin Controlled by PC4
#define AT91C_PIO_PC5 ((unsigned int) 1 << 5) // Pin Controlled by PC5
#define AT91C_PIO_PC6 ((unsigned int) 1 << 6) // Pin Controlled by PC6
#define AT91C_PIO_PC7 ((unsigned int) 1 << 7) // Pin Controlled by PC7
#define AT91C_PIO_PC8 ((unsigned int) 1 << 8) // Pin Controlled by PC8
#define AT91C_PIO_PC9 ((unsigned int) 1 << 9) // Pin Controlled by PC9
#define AT91C_PIO_PC10 ((unsigned int) 1 << 10) // Pin Controlled by PC10
#define AT91C_PIO_PC11 ((unsigned int) 1 << 11) // Pin Controlled by PC11
#define AT91C_PIO_PC12 ((unsigned int) 1 << 12) // Pin Controlled by PC12
#define AT91C_PIO_PC13 ((unsigned int) 1 << 13) // Pin Controlled by PC13
#define AT91C_PIO_PC14 ((unsigned int) 1 << 14) // Pin Controlled by PC14
#define AT91C_PIO_PC15 ((unsigned int) 1 << 15) // Pin Controlled by PC15
#define AT91C_PIO_PC16 ((unsigned int) 1 << 16) // Pin Controlled by PC16
#define AT91C_PIO_PC17 ((unsigned int) 1 << 17) // Pin Controlled by PC17
#define AT91C_PIO_PC18 ((unsigned int) 1 << 18) // Pin Controlled by PC18
#define AT91C_PIO_PC19 ((unsigned int) 1 << 19) // Pin Controlled by PC19
#define AT91C_PIO_PC20 ((unsigned int) 1 << 20) // Pin Controlled by PC20
#define AT91C_PIO_PC21 ((unsigned int) 1 << 21) // Pin Controlled by PC21
#define AT91C_PIO_PC22 ((unsigned int) 1 << 22) // Pin Controlled by PC22
#define AT91C_PIO_PC23 ((unsigned int) 1 << 23) // Pin Controlled by PC23
#define AT91C_PIO_PC24 ((unsigned int) 1 << 24) // Pin Controlled by PC24
#define AT91C_PIO_PC25 ((unsigned int) 1 << 25) // Pin Controlled by PC25
#define AT91C_PIO_PC26 ((unsigned int) 1 << 26) // Pin Controlled by PC26
#define AT91C_PIO_PC27 ((unsigned int) 1 << 27) // Pin Controlled by PC27
#define AT91C_PIO_PC28 ((unsigned int) 1 << 28) // Pin Controlled by PC28
#define AT91C_PIO_PC29 ((unsigned int) 1 << 29) // Pin Controlled by PC29
#define AT91C_PIO_PC30 ((unsigned int) 1 << 30) // Pin Controlled by PC30
#define AT91C_PIO_PC31 ((unsigned int) 1 << 31) // Pin Controlled by PC31
#define AT91C_PIO_PD0 ((unsigned int) 1 << 0) // Pin Controlled by PD0
#define AT91C_PIO_PD1 ((unsigned int) 1 << 1) // Pin Controlled by PD1
#define AT91C_PIO_PD2 ((unsigned int) 1 << 2) // Pin Controlled by PD2
#define AT91C_PIO_PD3 ((unsigned int) 1 << 3) // Pin Controlled by PD3
#define AT91C_PIO_PD4 ((unsigned int) 1 << 4) // Pin Controlled by PD4
#define AT91C_PIO_PD5 ((unsigned int) 1 << 5) // Pin Controlled by PD5
#define AT91C_PIO_PD6 ((unsigned int) 1 << 6) // Pin Controlled by PD6
#define AT91C_PIO_PD7 ((unsigned int) 1 << 7) // Pin Controlled by PD7
#define AT91C_PIO_PD8 ((unsigned int) 1 << 8) // Pin Controlled by PD8
#define AT91C_PIO_PD9 ((unsigned int) 1 << 9) // Pin Controlled by PD9
#define AT91C_PIO_PD10 ((unsigned int) 1 << 10) // Pin Controlled by PD10
#define AT91C_PIO_PD11 ((unsigned int) 1 << 11) // Pin Controlled by PD11
#define AT91C_PIO_PD12 ((unsigned int) 1 << 12) // Pin Controlled by PD12
#define AT91C_PIO_PD13 ((unsigned int) 1 << 13) // Pin Controlled by PD13
#define AT91C_PIO_PD14 ((unsigned int) 1 << 14) // Pin Controlled by PD14
#define AT91C_PIO_PD15 ((unsigned int) 1 << 15) // Pin Controlled by PD15
#define AT91C_PIO_PD16 ((unsigned int) 1 << 16) // Pin Controlled by PD16
#define AT91C_PIO_PD17 ((unsigned int) 1 << 17) // Pin Controlled by PD17
#define AT91C_PIO_PD18 ((unsigned int) 1 << 18) // Pin Controlled by PD18
#define AT91C_PIO_PD19 ((unsigned int) 1 << 19) // Pin Controlled by PD19
#define AT91C_PIO_PD20 ((unsigned int) 1 << 20) // Pin Controlled by PD20
#define AT91C_PIO_PD21 ((unsigned int) 1 << 21) // Pin Controlled by PD21
#define AT91C_PIO_PD22 ((unsigned int) 1 << 22) // Pin Controlled by PD22
#define AT91C_PIO_PD23 ((unsigned int) 1 << 23) // Pin Controlled by PD23
#define AT91C_PIO_PD24 ((unsigned int) 1 << 24) // Pin Controlled by PD24
#define AT91C_PIO_PD25 ((unsigned int) 1 << 25) // Pin Controlled by PD25
#define AT91C_PIO_PD26 ((unsigned int) 1 << 26) // Pin Controlled by PD26
#define AT91C_PIO_PD27 ((unsigned int) 1 << 27) // Pin Controlled by PD27
#define AT91C_PIO_PD28 ((unsigned int) 1 << 28) // Pin Controlled by PD28
#define AT91C_PIO_PD29 ((unsigned int) 1 << 29) // Pin Controlled by PD29
#define AT91C_PIO_PD30 ((unsigned int) 1 << 30) // Pin Controlled by PD30
#define AT91C_PIO_PD31 ((unsigned int) 1 << 31) // Pin Controlled by PD31
#define AT91C_PIO_PE0 ((unsigned int) 1 << 0) // Pin Controlled by PE0
#define AT91C_PIO_PE1 ((unsigned int) 1 << 1) // Pin Controlled by PE1
#define AT91C_PIO_PE2 ((unsigned int) 1 << 2) // Pin Controlled by PE2
#define AT91C_PIO_PE3 ((unsigned int) 1 << 3) // Pin Controlled by PE3
#define AT91C_PIO_PE4 ((unsigned int) 1 << 4) // Pin Controlled by PE4
#define AT91C_PIO_PE5 ((unsigned int) 1 << 5) // Pin Controlled by PE5
#define AT91C_PIO_PE6 ((unsigned int) 1 << 6) // Pin Controlled by PE6
#define AT91C_PIO_PE7 ((unsigned int) 1 << 7) // Pin Controlled by PE7
#define AT91C_PIO_PE8 ((unsigned int) 1 << 8) // Pin Controlled by PE8
#define AT91C_PIO_PE9 ((unsigned int) 1 << 9) // Pin Controlled by PE9
#define AT91C_PIO_PE10 ((unsigned int) 1 << 10) // Pin Controlled by PE10
#define AT91C_PIO_PE11 ((unsigned int) 1 << 11) // Pin Controlled by PE11
#define AT91C_PIO_PE12 ((unsigned int) 1 << 12) // Pin Controlled by PE12
#define AT91C_PIO_PE13 ((unsigned int) 1 << 13) // Pin Controlled by PE13
#define AT91C_PIO_PE14 ((unsigned int) 1 << 14) // Pin Controlled by PE14
#define AT91C_PIO_PE15 ((unsigned int) 1 << 15) // Pin Controlled by PE15
#define AT91C_PIO_PE16 ((unsigned int) 1 << 16) // Pin Controlled by PE16
#define AT91C_PIO_PE17 ((unsigned int) 1 << 17) // Pin Controlled by PE17
#define AT91C_PIO_PE18 ((unsigned int) 1 << 18) // Pin Controlled by PE18
#define AT91C_PIO_PE19 ((unsigned int) 1 << 19) // Pin Controlled by PE19
#define AT91C_PIO_PE20 ((unsigned int) 1 << 20) // Pin Controlled by PE20
#define AT91C_PIO_PE21 ((unsigned int) 1 << 21) // Pin Controlled by PE21
#define AT91C_PIO_PE22 ((unsigned int) 1 << 22) // Pin Controlled by PE22
#define AT91C_PIO_PE23 ((unsigned int) 1 << 23) // Pin Controlled by PE23
#define AT91C_PIO_PE24 ((unsigned int) 1 << 24) // Pin Controlled by PE24
#define AT91C_PIO_PE25 ((unsigned int) 1 << 25) // Pin Controlled by PE25
#define AT91C_PIO_PE26 ((unsigned int) 1 << 26) // Pin Controlled by PE26
#define AT91C_PIO_PE27 ((unsigned int) 1 << 27) // Pin Controlled by PE27
#define AT91C_PIO_PE28 ((unsigned int) 1 << 28) // Pin Controlled by PE28
#define AT91C_PIO_PE29 ((unsigned int) 1 << 29) // Pin Controlled by PE29
#define AT91C_PIO_PE30 ((unsigned int) 1 << 30) // Pin Controlled by PE30
#define AT91C_PIO_PE31 ((unsigned int) 1 << 31) // Pin Controlled by PE31
#endif /* ARM_AT91_AT91_PIOREG_H */

View File

@ -1,52 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2006 M. Warner Losh.
*
* 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 ARM_AT91_AT91_PIOVAR_H
#define ARM_AT91_AT91_PIOVAR_H
void at91_pio_use_periph_a(uint32_t pio, uint32_t periph_a_mask,
int use_pullup);
void at91_pio_use_periph_b(uint32_t pio, uint32_t periph_b_mask,
int use_pullup);
void at91_pio_use_gpio(uint32_t pio, uint32_t gpio_mask);
void at91_pio_gpio_input(uint32_t pio, uint32_t input_enable_mask);
void at91_pio_gpio_output(uint32_t pio, uint32_t output_enable_mask,
int use_pullup);
void at91_pio_gpio_high_z(uint32_t pio, uint32_t high_z_mask, int enable);
void at91_pio_gpio_set(uint32_t pio, uint32_t data_mask);
void at91_pio_gpio_clear(uint32_t pio, uint32_t data_mask);
uint32_t at91_pio_gpio_get(uint32_t pio, uint32_t data_mask);
void at91_pio_gpio_set_deglitch(uint32_t pio, uint32_t data_mask,
int use_deglitch);
void at91_pio_gpio_set_interrupt(uint32_t pio, uint32_t data_mask,
int enable_interrupt);
uint32_t at91_pio_gpio_clear_interrupt(uint32_t pio);
void at91_pio_gpio_pullup(uint32_t pio, uint32_t data_mask, int do_pullup);
#endif /* ARM_AT91_AT91_PIOVAR_H */

View File

@ -1,222 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2009 Gallon Sylvestre. All rights reserved.
* Copyright (c) 2010 Greg Ansley. 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 "opt_platform.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/resource.h>
#include <sys/systm.h>
#include <sys/rman.h>
#include <sys/time.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 <machine/resource.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91_pitreg.h>
#ifdef FDT
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#endif
#ifndef PIT_PRESCALE
#define PIT_PRESCALE (16)
#endif
static struct pit_softc {
struct resource *mem_res; /* Memory resource */
void *intrhand; /* Interrupt handle */
device_t sc_dev;
} *sc;
static uint32_t timecount = 0;
static unsigned at91_pit_get_timecount(struct timecounter *tc);
static int pit_intr(void *arg);
static inline uint32_t
RD4(struct pit_softc *sc, bus_size_t off)
{
return (bus_read_4(sc->mem_res, off));
}
static inline void
WR4(struct pit_softc *sc, bus_size_t off, uint32_t val)
{
bus_write_4(sc->mem_res, off, val);
}
void
at91_pit_delay(int us)
{
int32_t cnt, last, piv;
uint64_t pit_freq;
const uint64_t mhz = 1E6;
if (sc == NULL)
return;
last = PIT_PIV(RD4(sc, PIT_PIIR));
/* Max delay ~= 260s. @ 133Mhz */
pit_freq = at91_master_clock / PIT_PRESCALE;
cnt = howmany(pit_freq * us, mhz);
cnt = (cnt <= 0) ? 1 : cnt;
while (cnt > 0) {
piv = PIT_PIV(RD4(sc, PIT_PIIR));
cnt -= piv - last ;
if (piv < last)
cnt -= PIT_PIV(~0u) - last;
last = piv;
}
}
static struct timecounter at91_pit_timecounter = {
at91_pit_get_timecount, /* get_timecount */
NULL, /* no poll_pps */
0xffffffff, /* counter mask */
0 / PIT_PRESCALE, /* frequency */
"AT91SAM9 timer", /* name */
1000 /* quality */
};
static int
at91_pit_probe(device_t dev)
{
#ifdef FDT
if (!ofw_bus_is_compatible(dev, "atmel,at91sam9260-pit"))
return (ENXIO);
#endif
device_set_desc(dev, "AT91SAM9 PIT");
return (0);
}
static int
at91_pit_attach(device_t dev)
{
void *ih;
int rid, err = 0;
struct resource *irq;
sc = device_get_softc(dev);
sc->sc_dev = dev;
rid = 0;
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (sc->mem_res == NULL)
panic("couldn't allocate register resources");
rid = 0;
irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 1, 1, 1,
RF_ACTIVE | RF_SHAREABLE);
if (!irq) {
device_printf(dev, "could not allocate interrupt resources.\n");
err = ENOMEM;
goto out;
}
/* Activate the interrupt. */
err = bus_setup_intr(dev, irq, INTR_TYPE_CLK, pit_intr, NULL, NULL,
&ih);
at91_pit_timecounter.tc_frequency = at91_master_clock / PIT_PRESCALE;
tc_init(&at91_pit_timecounter);
/* Enable the PIT here. */
WR4(sc, PIT_MR, PIT_PIV(at91_master_clock / PIT_PRESCALE / hz) |
PIT_EN | PIT_IEN);
out:
return (err);
}
static int
pit_intr(void *arg)
{
struct trapframe *fp = arg;
uint32_t icnt;
if (RD4(sc, PIT_SR) & PIT_PITS_DONE) {
icnt = RD4(sc, PIT_PIVR) >> 20;
/* Just add in the overflows we just read */
timecount += PIT_PIV(RD4(sc, PIT_MR)) * icnt;
hardclock(TRAPF_USERMODE(fp), TRAPF_PC(fp));
return (FILTER_HANDLED);
}
return (FILTER_STRAY);
}
static unsigned
at91_pit_get_timecount(struct timecounter *tc)
{
uint32_t piir, icnt;
piir = RD4(sc, PIT_PIIR); /* Current count | over flows */
icnt = piir >> 20; /* Overflows */
return (timecount + PIT_PIV(piir) + PIT_PIV(RD4(sc, PIT_MR)) * icnt);
}
static device_method_t at91_pit_methods[] = {
DEVMETHOD(device_probe, at91_pit_probe),
DEVMETHOD(device_attach, at91_pit_attach),
DEVMETHOD_END
};
static driver_t at91_pit_driver = {
"at91_pit",
at91_pit_methods,
sizeof(struct pit_softc),
};
static devclass_t at91_pit_devclass;
#ifdef FDT
EARLY_DRIVER_MODULE(at91_pit, simplebus, at91_pit_driver, at91_pit_devclass,
NULL, NULL, BUS_PASS_TIMER);
#else
EARLY_DRIVER_MODULE(at91_pit, atmelarm, at91_pit_driver, at91_pit_devclass,
NULL, NULL, BUS_PASS_TIMER);
#endif

View File

@ -1,49 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2009 Sylvestre Gallon. 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 ARM_AT91_AT91_PITREG_H
#define ARM_AT91_AT91_PITREG_H
#define PIT_MR 0x0
#define PIT_SR 0x4
#define PIT_PIVR 0x8
#define PIT_PIIR 0xc
/* PIT_MR */
#define PIT_PIV(x) (x & 0xfffff) /* periodic interval value */
#define PIT_CNT(x) ((x >>20) & 0xfff) /* periodic interval counter */
#define PIT_EN (1 << 24) /* pit enable */
#define PIT_IEN (1 << 25) /* pit interrupt enable */
/* PIT_SR */
#define PIT_PITS_DONE 1 /* interrupt done */
void at91_pit_delay(int us);
#endif /* ARM_AT91_AT91_PITREG_H */

View File

@ -1,719 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2006 M. Warner Losh.
* Copyright (c) 2010 Greg Ansley. 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 "opt_platform.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/time.h>
#include <sys/bus.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/timetc.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <arm/at91/at91reg.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91_pmcreg.h>
#include <arm/at91/at91_pmcvar.h>
#ifdef FDT
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#endif
static struct at91_pmc_softc {
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
struct resource *mem_res; /* Memory resource */
device_t dev;
} *pmc_softc;
static uint32_t pllb_init;
MALLOC_DECLARE(M_PMC_CLK);
MALLOC_DEFINE(M_PMC_CLK, "at91_pmc_clocks", "AT91 PMC Clock descriptors");
#define AT91_PMC_BASE 0xffffc00
static void at91_pmc_set_pllb_mode(struct at91_pmc_clock *, int);
static void at91_pmc_set_upll_mode(struct at91_pmc_clock *, int);
static void at91_pmc_set_sys_mode(struct at91_pmc_clock *, int);
static void at91_pmc_set_periph_mode(struct at91_pmc_clock *, int);
static void at91_pmc_clock_alias(const char *name, const char *alias);
static struct at91_pmc_clock slck = {
.name = "slck", /* 32,768 Hz slow clock */
.hz = 32768,
.refcnt = 1,
.id = 0,
.primary = 1,
};
/*
* NOTE: Clocks for "ordinary peripheral" devices e.g. spi0, udp0, uhp0 etc.
* are now created automatically. Only "system" clocks need be defined here.
*/
static struct at91_pmc_clock main_ck = {
.name = "main", /* Main clock */
.refcnt = 0,
.id = 1,
.primary = 1,
.pmc_mask = PMC_IER_MOSCS,
};
static struct at91_pmc_clock plla = {
.name = "plla", /* PLLA Clock, used for CPU clocking */
.parent = &main_ck,
.refcnt = 1,
.id = 0,
.primary = 1,
.pll = 1,
.pmc_mask = PMC_IER_LOCKA,
};
static struct at91_pmc_clock pllb = {
.name = "pllb", /* PLLB Clock, used for USB functions */
.parent = &main_ck,
.refcnt = 0,
.id = 0,
.primary = 1,
.pll = 1,
.pmc_mask = PMC_IER_LOCKB,
.set_mode = &at91_pmc_set_pllb_mode,
};
/* Used by USB on at91sam9g45 */
static struct at91_pmc_clock upll = {
.name = "upll", /* UTMI PLL, used for USB functions on 9G45 family */
.parent = &main_ck,
.refcnt = 0,
.id = 0,
.primary = 1,
.pll = 1,
.pmc_mask = (1 << 6),
.set_mode = &at91_pmc_set_upll_mode,
};
static struct at91_pmc_clock udpck = {
.name = "udpck",
.parent = &pllb,
.pmc_mask = PMC_SCER_UDP,
.set_mode = at91_pmc_set_sys_mode
};
static struct at91_pmc_clock uhpck = {
.name = "uhpck",
.parent = &pllb,
.pmc_mask = PMC_SCER_UHP,
.set_mode = at91_pmc_set_sys_mode
};
static struct at91_pmc_clock mck = {
.name = "mck", /* Master (Peripheral) Clock */
.pmc_mask = PMC_IER_MCKRDY,
.refcnt = 0,
};
static struct at91_pmc_clock cpu = {
.name = "cpu", /* CPU Clock */
.parent = &plla,
.pmc_mask = PMC_SCER_PCK,
.refcnt = 0,
};
/* "+32" or the automatic peripheral clocks */
static struct at91_pmc_clock *clock_list[16+32] = {
&slck,
&main_ck,
&plla,
&pllb,
&upll,
&udpck,
&uhpck,
&mck,
&cpu
};
static inline uint32_t
RD4(struct at91_pmc_softc *sc, bus_size_t off)
{
if (sc == NULL) {
uint32_t *p = (uint32_t *)(AT91_BASE + AT91_PMC_BASE + off);
return *p;
}
return (bus_read_4(sc->mem_res, off));
}
static inline void
WR4(struct at91_pmc_softc *sc, bus_size_t off, uint32_t val)
{
if (sc == NULL) {
uint32_t *p = (uint32_t *)(AT91_BASE + AT91_PMC_BASE + off);
*p = val;
} else
bus_write_4(sc->mem_res, off, val);
}
/*
* The following is unused currently since we don't ever set the PLLA
* frequency of the device. If we did, we'd have to also pay attention
* to the ICPLLA bit in the PMC_PLLICPR register for frequencies lower
* than ~600MHz, which the PMC code doesn't do right now.
*/
uint32_t
at91_pmc_800mhz_plla_outb(int freq)
{
uint32_t outa;
/*
* Set OUTA, per the data sheet. See Table 46-16 titled
* PLLA Frequency Regarding ICPLLA and OUTA in the SAM9X25 doc,
* Table 46-17 in the SAM9G20 doc, or Table 46-16 in the SAM9G45 doc.
* Note: the frequencies overlap by 5MHz, so we add 3 here to
* center shoot the transition.
*/
freq /= 1000000; /* MHz */
if (freq >= 800)
freq = 800;
freq += 3; /* Allow for overlap. */
outa = 3 - ((freq / 50) & 3); /* 750 / 50 = 7, see table */
return (1 << 29)| (outa << 14);
}
uint32_t
at91_pmc_800mhz_pllb_outb(int freq)
{
return (0);
}
void
at91_pmc_set_pllb_mode(struct at91_pmc_clock *clk, int on)
{
struct at91_pmc_softc *sc = pmc_softc;
uint32_t value;
value = on ? pllb_init : 0;
/*
* Only write to the register if the value is changing. Besides being
* good common sense, this works around RM9200 Errata #26 (CKGR_PLL[AB]R
* must not be written with the same value currently in the register).
*/
if (RD4(sc, CKGR_PLLBR) != value) {
WR4(sc, CKGR_PLLBR, value);
while (on && (RD4(sc, PMC_SR) & PMC_IER_LOCKB) != PMC_IER_LOCKB)
continue;
}
}
static void
at91_pmc_set_upll_mode(struct at91_pmc_clock *clk, int on)
{
struct at91_pmc_softc *sc = pmc_softc;
uint32_t value;
if (on) {
on = PMC_IER_LOCKU;
value = CKGR_UCKR_UPLLEN | CKGR_UCKR_BIASEN;
} else
value = 0;
WR4(sc, CKGR_UCKR, RD4(sc, CKGR_UCKR) | value);
while ((RD4(sc, PMC_SR) & PMC_IER_LOCKU) != on)
continue;
WR4(sc, PMC_USB, PMC_USB_USBDIV(9) | PMC_USB_USBS);
WR4(sc, PMC_SCER, PMC_SCER_UHP_SAM9);
}
static void
at91_pmc_set_sys_mode(struct at91_pmc_clock *clk, int on)
{
struct at91_pmc_softc *sc = pmc_softc;
WR4(sc, on ? PMC_SCER : PMC_SCDR, clk->pmc_mask);
if (on)
while ((RD4(sc, PMC_SCSR) & clk->pmc_mask) != clk->pmc_mask)
continue;
else
while ((RD4(sc, PMC_SCSR) & clk->pmc_mask) == clk->pmc_mask)
continue;
}
static void
at91_pmc_set_periph_mode(struct at91_pmc_clock *clk, int on)
{
struct at91_pmc_softc *sc = pmc_softc;
WR4(sc, on ? PMC_PCER : PMC_PCDR, clk->pmc_mask);
if (on)
while ((RD4(sc, PMC_PCSR) & clk->pmc_mask) != clk->pmc_mask)
continue;
else
while ((RD4(sc, PMC_PCSR) & clk->pmc_mask) == clk->pmc_mask)
continue;
}
struct at91_pmc_clock *
at91_pmc_clock_add(const char *name, uint32_t irq,
struct at91_pmc_clock *parent)
{
struct at91_pmc_clock *clk;
int i, buflen;
clk = malloc(sizeof(*clk), M_PMC_CLK, M_NOWAIT | M_ZERO);
if (clk == NULL)
goto err;
buflen = strlen(name) + 1;
clk->name = malloc(buflen, M_PMC_CLK, M_NOWAIT);
if (clk->name == NULL)
goto err;
strlcpy(clk->name, name, buflen);
clk->pmc_mask = 1 << irq;
clk->set_mode = &at91_pmc_set_periph_mode;
if (parent == NULL)
clk->parent = &mck;
else
clk->parent = parent;
for (i = 0; i < nitems(clock_list); i++) {
if (clock_list[i] == NULL) {
clock_list[i] = clk;
return (clk);
}
}
err:
if (clk != NULL) {
if (clk->name != NULL)
free(clk->name, M_PMC_CLK);
free(clk, M_PMC_CLK);
}
panic("could not allocate pmc clock '%s'", name);
return (NULL);
}
static void
at91_pmc_clock_alias(const char *name, const char *alias)
{
struct at91_pmc_clock *clk, *alias_clk;
clk = at91_pmc_clock_ref(name);
if (clk)
alias_clk = at91_pmc_clock_add(alias, 0, clk->parent);
if (clk && alias_clk) {
alias_clk->hz = clk->hz;
alias_clk->pmc_mask = clk->pmc_mask;
alias_clk->set_mode = clk->set_mode;
}
}
struct at91_pmc_clock *
at91_pmc_clock_ref(const char *name)
{
int i;
for (i = 0; i < nitems(clock_list); i++) {
if (clock_list[i] == NULL)
break;
if (strcmp(name, clock_list[i]->name) == 0)
return (clock_list[i]);
}
return (NULL);
}
void
at91_pmc_clock_deref(struct at91_pmc_clock *clk)
{
if (clk == NULL)
return;
}
void
at91_pmc_clock_enable(struct at91_pmc_clock *clk)
{
if (clk == NULL)
return;
/* XXX LOCKING? XXX */
if (clk->parent)
at91_pmc_clock_enable(clk->parent);
if (clk->refcnt++ == 0 && clk->set_mode)
clk->set_mode(clk, 1);
}
void
at91_pmc_clock_disable(struct at91_pmc_clock *clk)
{
if (clk == NULL)
return;
/* XXX LOCKING? XXX */
if (--clk->refcnt == 0 && clk->set_mode)
clk->set_mode(clk, 0);
if (clk->parent)
at91_pmc_clock_disable(clk->parent);
}
static int
at91_pmc_pll_rate(struct at91_pmc_clock *clk, uint32_t reg)
{
uint32_t mul, div, freq;
freq = clk->parent->hz;
div = (reg >> clk->pll_div_shift) & clk->pll_div_mask;
mul = (reg >> clk->pll_mul_shift) & clk->pll_mul_mask;
#if 0
printf("pll = (%d / %d) * %d = %d\n",
freq, div, mul + 1, (freq/div) * (mul+1));
#endif
if (div != 0 && mul != 0) {
freq /= div;
freq *= mul + 1;
} else
freq = 0;
clk->hz = freq;
return (freq);
}
static uint32_t
at91_pmc_pll_calc(struct at91_pmc_clock *clk, uint32_t out_freq)
{
uint32_t i, div = 0, mul = 0, diff = 1 << 30;
unsigned ret = 0x3e00;
if (out_freq > clk->pll_max_out)
goto fail;
for (i = 1; i < 256; i++) {
int32_t diff1;
uint32_t input, mul1;
input = clk->parent->hz / i;
if (input < clk->pll_min_in)
break;
if (input > clk->pll_max_in)
continue;
mul1 = out_freq / input;
if (mul1 > (clk->pll_mul_mask + 1))
continue;
if (mul1 == 0)
break;
diff1 = out_freq - input * mul1;
if (diff1 < 0)
diff1 = -diff1;
if (diff > diff1) {
diff = diff1;
div = i;
mul = mul1;
if (diff == 0)
break;
}
}
if (diff > (out_freq >> PMC_PLL_SHIFT_TOL))
goto fail;
if (clk->set_outb != NULL)
ret |= clk->set_outb(out_freq);
return (ret |
((mul - 1) << clk->pll_mul_shift) |
(div << clk->pll_div_shift));
fail:
return (0);
}
#if !defined(AT91C_MAIN_CLOCK)
static const unsigned int at91_main_clock_tbl[] = {
3000000, 3276800, 3686400, 3840000, 4000000,
4433619, 4915200, 5000000, 5242880, 6000000,
6144000, 6400000, 6553600, 7159090, 7372800,
7864320, 8000000, 9830400, 10000000, 11059200,
12000000, 12288000, 13560000, 14318180, 14745600,
16000000, 17344700, 18432000, 20000000
};
#define MAIN_CLOCK_TBL_LEN nitems(at91_main_clock_tbl)
#endif
static unsigned int
at91_pmc_sense_main_clock(void)
{
#if !defined(AT91C_MAIN_CLOCK)
unsigned int ckgr_val;
unsigned int diff, matchdiff, freq;
int i;
ckgr_val = (RD4(NULL, CKGR_MCFR) & CKGR_MCFR_MAINF_MASK) << 11;
/*
* Clocks up to 50MHz can be connected to some models. If
* the frequency is >= 21MHz, assume that the slow clock can
* measure it correctly, and that any error can be adequately
* compensated for by roudning to the nearest 500Hz. Users
* with fast, or odd-ball clocks will need to set
* AT91C_MAIN_CLOCK in the kernel config file.
*/
if (ckgr_val >= 21000000)
return (rounddown(ckgr_val + 250, 500));
/*
* Try to find the standard frequency that match best.
*/
freq = at91_main_clock_tbl[0];
matchdiff = abs(ckgr_val - at91_main_clock_tbl[0]);
for (i = 1; i < MAIN_CLOCK_TBL_LEN; i++) {
diff = abs(ckgr_val - at91_main_clock_tbl[i]);
if (diff < matchdiff) {
freq = at91_main_clock_tbl[i];
matchdiff = diff;
}
}
return (freq);
#else
return (AT91C_MAIN_CLOCK);
#endif
}
void
at91_pmc_init_clock(void)
{
struct at91_pmc_softc *sc = NULL;
unsigned int main_clock;
uint32_t mckr;
uint32_t mdiv;
soc_info.soc_data->soc_clock_init();
main_clock = at91_pmc_sense_main_clock();
if (at91_is_sam9() || at91_is_sam9xe()) {
uhpck.pmc_mask = PMC_SCER_UHP_SAM9;
udpck.pmc_mask = PMC_SCER_UDP_SAM9;
}
/* There is no pllb on AT91SAM9G45 */
if (at91_cpu_is(AT91_T_SAM9G45)) {
uhpck.parent = &upll;
uhpck.pmc_mask = PMC_SCER_UHP_SAM9;
}
mckr = RD4(sc, PMC_MCKR);
main_ck.hz = main_clock;
/*
* Note: this means outa calc code for plla never used since
* we never change it. If we did, we'd also have to mind
* ICPLLA to get the charge pump current right.
*/
at91_pmc_pll_rate(&plla, RD4(sc, CKGR_PLLAR));
if (at91_cpu_is(AT91_T_SAM9G45) && (mckr & PMC_MCKR_PLLADIV2))
plla.hz /= 2;
/*
* Initialize the usb clock. This sets up pllb, but disables the
* actual clock. XXX except for the if 0 :(
*/
if (!at91_cpu_is(AT91_T_SAM9G45)) {
pllb_init = at91_pmc_pll_calc(&pllb, 48000000 * 2) | 0x10000000;
at91_pmc_pll_rate(&pllb, pllb_init);
#if 0
/* Turn off USB clocks */
at91_pmc_set_periph_mode(&ohci_clk, 0);
at91_pmc_set_periph_mode(&udc_clk, 0);
#endif
}
if (at91_is_rm92()) {
WR4(sc, PMC_SCDR, PMC_SCER_UHP | PMC_SCER_UDP);
WR4(sc, PMC_SCER, PMC_SCER_MCKUDP);
} else
WR4(sc, PMC_SCDR, PMC_SCER_UHP_SAM9 | PMC_SCER_UDP_SAM9);
/*
* MCK and PCU derive from one of the primary clocks. Initialize
* this relationship.
*/
mck.parent = clock_list[mckr & 0x3];
mck.parent->refcnt++;
cpu.hz = mck.hz = mck.parent->hz /
(1 << ((mckr & PMC_MCKR_PRES_MASK) >> 2));
mdiv = (mckr & PMC_MCKR_MDIV_MASK) >> 8;
if (at91_is_sam9() || at91_is_sam9xe()) {
/*
* On AT91SAM9G45 when mdiv == 3 we need to divide
* MCK by 3 but not, for example, on 9g20.
*/
if (!at91_cpu_is(AT91_T_SAM9G45) || mdiv <= 2)
mdiv *= 2;
if (mdiv > 0)
mck.hz /= mdiv;
} else
mck.hz /= (1 + mdiv);
/* Only found on SAM9G20 */
if (at91_cpu_is(AT91_T_SAM9G20))
cpu.hz /= (mckr & PMC_MCKR_PDIV) ? 2 : 1;
at91_master_clock = mck.hz;
/* These clocks refrenced by "special" names */
at91_pmc_clock_alias("ohci0", "ohci_clk");
at91_pmc_clock_alias("udp0", "udp_clk");
/* Turn off "Progamable" clocks */
WR4(sc, PMC_SCDR, PMC_SCER_PCK0 | PMC_SCER_PCK1 | PMC_SCER_PCK2 |
PMC_SCER_PCK3);
/* XXX kludge, turn on all peripherals */
WR4(sc, PMC_PCER, 0xffffffff);
/* Disable all interrupts for PMC */
WR4(sc, PMC_IDR, 0xffffffff);
}
static void
at91_pmc_deactivate(device_t dev)
{
struct at91_pmc_softc *sc;
sc = device_get_softc(dev);
bus_generic_detach(sc->dev);
if (sc->mem_res)
bus_release_resource(dev, SYS_RES_IOPORT,
rman_get_rid(sc->mem_res), sc->mem_res);
sc->mem_res = NULL;
}
static int
at91_pmc_activate(device_t dev)
{
struct at91_pmc_softc *sc;
int rid;
sc = device_get_softc(dev);
rid = 0;
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (sc->mem_res == NULL)
goto errout;
return (0);
errout:
at91_pmc_deactivate(dev);
return (ENOMEM);
}
static int
at91_pmc_probe(device_t dev)
{
#ifdef FDT
if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-pmc") &&
!ofw_bus_is_compatible(dev, "atmel,at91sam9260-pmc") &&
!ofw_bus_is_compatible(dev, "atmel,at91sam9g45-pmc") &&
!ofw_bus_is_compatible(dev, "atmel,at91sam9x5-pmc"))
return (ENXIO);
#endif
device_set_desc(dev, "PMC");
return (0);
}
static int
at91_pmc_attach(device_t dev)
{
int err;
pmc_softc = device_get_softc(dev);
pmc_softc->dev = dev;
if ((err = at91_pmc_activate(dev)) != 0)
return (err);
/*
* Configure main clock frequency.
*/
at91_pmc_init_clock();
/*
* Display info about clocks previously computed
*/
device_printf(dev,
"Primary: %d Hz PLLA: %d MHz CPU: %d MHz MCK: %d MHz\n",
main_ck.hz,
plla.hz / 1000000,
cpu.hz / 1000000, mck.hz / 1000000);
return (0);
}
static device_method_t at91_pmc_methods[] = {
DEVMETHOD(device_probe, at91_pmc_probe),
DEVMETHOD(device_attach, at91_pmc_attach),
DEVMETHOD_END
};
static driver_t at91_pmc_driver = {
"at91_pmc",
at91_pmc_methods,
sizeof(struct at91_pmc_softc),
};
static devclass_t at91_pmc_devclass;
#ifdef FDT
EARLY_DRIVER_MODULE(at91_pmc, simplebus, at91_pmc_driver, at91_pmc_devclass,
NULL, NULL, BUS_PASS_CPU);
#else
EARLY_DRIVER_MODULE(at91_pmc, atmelarm, at91_pmc_driver, at91_pmc_devclass,
NULL, NULL, BUS_PASS_CPU);
#endif

View File

@ -1,146 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2005 M. Warner Losh.
*
* 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 ARM_AT91_AT91_PMCREG_H
#define ARM_AT91_AT91_PMCREG_H
/* Registers */
#define PMC_SCER 0x00 /* System Clock Enable Register */
#define PMC_SCDR 0x04 /* System Clock Disable Register */
#define PMC_SCSR 0x08 /* System Clock Status Register */
/* 0x0c reserved */
#define PMC_PCER 0x10 /* Peripheral Clock Enable Register */
#define PMC_PCDR 0x14 /* Peripheral Clock Disable Register */
#define PMC_PCSR 0x18 /* Peripheral Clock Status Register */
#define CKGR_UCKR 0x1c /* UTMI Clock Configuration Register */
#define CKGR_MOR 0x20 /* Main Oscillator Register */
#define CKGR_MCFR 0x24 /* Main Clock Frequency Register */
#define CKGR_PLLAR 0x28 /* PLL A Register */
#define CKGR_PLLBR 0x2c /* PLL B Register */
#define PMC_MCKR 0x30 /* Master Clock Register */
/* 0x34 reserved */
#define PMC_USB 0x38 /* USB Clock Register */
/* 0x3c reserved */
#define PMC_PCK0 0x40 /* Programmable Clock 0 Register */
#define PMC_PCK1 0x44 /* Programmable Clock 1 Register */
#define PMC_PCK2 0x48 /* Programmable Clock 2 Register */
#define PMC_PCK3 0x4c /* Programmable Clock 3 Register */
/* 0x50 reserved */
/* 0x54 reserved */
/* 0x58 reserved */
/* 0x5c reserved */
#define PMC_IER 0x60 /* Interrupt Enable Register */
#define PMC_IDR 0x64 /* Interrupt Disable Register */
#define PMC_SR 0x68 /* Status Register */
#define PMC_IMR 0x6c /* Interrupt Mask Register */
/* 0x70 reserved */
/* 0x74 reserved */
/* 0x78 reserved */
/* 0x7c reserved */
#define PMC_PLLICPR 0x80 /* PLL Charge Pump Current Register */
/* PMC System Clock Enable Register */
/* PMC System Clock Disable Register */
/* PMC System Clock StatusRegister */
#define PMC_SCER_PCK (1UL << 0) /* PCK: Processor Clock Enable */
#define PMC_SCER_UDP (1UL << 1) /* UDP: USB Device Port Clock Enable */
#define PMC_SCER_MCKUDP (1UL << 2) /* MCKUDP: Master disable susp/res */
#define PMC_SCER_UHP (1UL << 4) /* UHP: USB Host Port Clock Enable */
#define PMC_SCER_PCK0 (1UL << 8) /* PCK0: Programmable Clock out en */
#define PMC_SCER_PCK1 (1UL << 9) /* PCK1: Programmable Clock out en */
#define PMC_SCER_PCK2 (1UL << 10) /* PCK2: Programmable Clock out en */
#define PMC_SCER_PCK3 (1UL << 11) /* PCK3: Programmable Clock out en */
#define PMC_SCER_UHP_SAM9 (1UL << 6) /* UHP: USB Host Port Clock Enable */
#define PMC_SCER_UDP_SAM9 (1UL << 7) /* UDP: USB Device Port Clock Enable */
/* PMC Peripheral Clock Enable Register */
/* PMC Peripheral Clock Disable Register */
/* PMC Peripheral Clock Status Register */
/* Each bit here is 1 << peripheral number to enable/disable/status */
/* PMC UTMI Clock Configuration Register */
#define CKGR_UCKR_BIASEN (1UL << 24)
#define CKGR_UCKR_UPLLEN (1UL << 16)
/* PMC Clock Generator Main Oscillator Register */
#define CKGR_MOR_MOSCEN (1UL << 0) /* MOSCEN: Main Oscillator Enable */
#define CKGR_MOR_OSCBYPASS (1UL << 1) /* Oscillator Bypass */
#define CKGR_MOR_OSCOUNT(x) (x << 8) /* Main Oscillator Start-up Time */
/* PMC Clock Generator Main Clock Frequency Register */
#define CKGR_MCFR_MAINRDY (1UL << 16) /* Main Clock Ready */
#define CKGR_MCFR_MAINF_MASK 0xfffful /* Main Clock Frequency */
/* PMC Clock Generator Master Clock Register */
#define PMC_MCKR_PDIV (1 << 12) /* SAM9G20 Only */
#define PMC_MCKR_PLLADIV2 (1 << 12) /* SAM9G45 Only */
#define PMC_MCKR_CSS_MASK (3 << 0)
#define PMC_MCKR_MDIV_MASK (3 << 8)
#define PMC_MCKR_PRES_MASK (7 << 2)
/* PMC USB Clock Register */
#define PMC_USB_USBDIV(n) (((n) & 0x0F) << 8)
#define PMC_USB_USBS (1 << 0)
/* PMC Interrupt Enable Register */
/* PMC Interrupt Disable Register */
/* PMC Status Register */
/* PMC Interrupt Mask Register */
#define PMC_IER_MOSCS (1UL << 0) /* Main Oscillator Status */
#define PMC_IER_LOCKA (1UL << 1) /* PLL A Locked */
#define PMC_IER_LOCKB (1UL << 2) /* PLL B Locked */
#define PMC_IER_MCKRDY (1UL << 3) /* Master Clock Status */
#define PMC_IER_LOCKU (1UL << 6) /* UPLL Locked */
#define PMC_IER_PCK0RDY (1UL << 8) /* Programmable Clock 0 Ready */
#define PMC_IER_PCK1RDY (1UL << 9) /* Programmable Clock 1 Ready */
#define PMC_IER_PCK2RDY (1UL << 10) /* Programmable Clock 2 Ready */
#define PMC_IER_PCK3RDY (1UL << 11) /* Programmable Clock 3 Ready */
/*
* PLL input frequency spec sheet says it must be between 1MHz and 32MHz,
* but it works down as low as 100kHz, a frequency necessary for some
* output frequencies to work.
*/
#define PMC_PLL_MIN_IN_FREQ 100000
#define PMC_PLL_MAX_IN_FREQ 32000000
/*
* PLL Max output frequency is 240MHz. The errata says 180MHz is the max
* for some revisions of this part. Be more permissive and optimistic.
*/
#define PMC_PLL_MAX_OUT_FREQ 240000000
#define PMC_PLL_MULT_MIN 2
#define PMC_PLL_MULT_MAX 2048
#define PMC_PLL_SHIFT_TOL 5 /* Allow errors 1 part in 32 */
#define PMC_PLL_FAST_THRESH 155000000
#endif /* ARM_AT91_AT91_PMCREG_H */

View File

@ -1,69 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2005 M. Warner Losh.
*
* 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 ARM_AT91_AT91_PMCVAR_H
#define ARM_AT91_AT91_PMCVAR_H
struct at91_pmc_clock
{
char *name;
uint32_t hz;
struct at91_pmc_clock *parent;
uint32_t pmc_mask;
void (*set_mode)(struct at91_pmc_clock *, int);
uint32_t refcnt;
unsigned id:2;
unsigned primary:1;
unsigned pll:1;
unsigned programmable:1;
/* PLL Params */
uint32_t pll_min_in;
uint32_t pll_max_in;
uint32_t pll_min_out;
uint32_t pll_max_out;
uint32_t pll_div_shift;
uint32_t pll_div_mask;
uint32_t pll_mul_shift;
uint32_t pll_mul_mask;
uint32_t (*set_outb)(int);
};
struct at91_pmc_clock *at91_pmc_clock_add(const char *name, uint32_t irq,
struct at91_pmc_clock *parent);
struct at91_pmc_clock *at91_pmc_clock_ref(const char *name);
void at91_pmc_clock_deref(struct at91_pmc_clock *);
void at91_pmc_clock_enable(struct at91_pmc_clock *);
void at91_pmc_clock_disable(struct at91_pmc_clock *);
uint32_t at91_pmc_800mhz_plla_outb(int freq);
uint32_t at91_pmc_800mhz_pllb_outb(int freq);
#endif /* ARM_AT91_AT91_PMCVAR_H */

View File

@ -1,57 +0,0 @@
#include <machine/asm.h>
#include <arm/at91/at91_rstreg.h>
#include <arm/at91/at91reg.h>
#include <arm/at91/at91sam9g20reg.h>
__FBSDID("$FreeBSD$");
#define SDRAM_TR (AT91_BASE + \
AT91SAM9G20_SDRAMC_BASE + AT91SAM9G20_SDRAMC_TR)
#define SDRAM_LPR (AT91_BASE + \
AT91SAM9G20_SDRAMC_BASE + AT91SAM9G20_SDRAMC_LPR)
#define RSTC_RCR (AT91_BASE + \
AT91SAM9G20_RSTC_BASE + RST_CR)
/*
* From AT91SAM9G20 Datasheet errata 44:3.5:
*
* When User Reset occurs during SDRAM read access, the SDRAM clock is turned
* off while data are ready to be read on the data bus. The SDRAM maintains
* the data until the clock restarts.
*
* If the User reset is programed to assert a general reset, the data
* maintained by the SDRAM leads to a data bus conflict and adversly affects
* the boot memories connected to the EBI:
* + NAND Flash boot functionality, if the system boots out of internal ROM.
* + NOR Flash boot, if the system boots on an external memory connected to
* the EBI CS0.
*
* Assembly code is mandatory for the following sequnce as ARM
* instructions need to be piplined.
*
*/
ENTRY(cpu_reset_sam9g20)
/* Disable IRQs */
mrs r0, cpsr
orr r0, r0, #0x80
msr cpsr_c, r0
/* Change Refresh to block all data access */
ldr r0, =SDRAM_TR
ldr r1, =1
str r1, [r0]
/* Prepare power down command */
ldr r0, =SDRAM_LPR
ldr r1, =2
/* Prepare proc_reset and periph reset */
ldr r2, =RSTC_RCR
ldr r3, =0xA5000005
/* perform power down command */
str r1, [r0]
/* Perfom proc_reset and periph reset (in the ARM pipeline) */
str r3, [r2]

View File

@ -1,236 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2010 Greg Ansley. 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 "opt_platform.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/rman.h>
#include <sys/systm.h>
#include <machine/bus.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91_rstreg.h>
#include <arm/at91/at91board.h>
#ifdef FDT
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#define FDT_HACKS 1
#endif
#define RST_TIMEOUT (5) /* Seconds to hold NRST for hard reset */
#define RST_TICK (20) /* sample NRST at hz/RST_TICK intervals */
#ifndef FDT
static int at91_rst_intr(void *arg);
#endif
static struct at91_rst_softc {
struct resource *mem_res; /* Memory resource */
struct resource *irq_res; /* IRQ resource */
void *intrhand; /* Interrupt handle */
struct callout tick_ch; /* Tick callout */
device_t sc_dev;
u_int shutdown; /* Shutdown in progress */
} *at91_rst_sc;
static inline uint32_t
RD4(struct at91_rst_softc *sc, bus_size_t off)
{
return (bus_read_4(sc->mem_res, off));
}
static inline void
WR4(struct at91_rst_softc *sc, bus_size_t off, uint32_t val)
{
bus_write_4(sc->mem_res, off, val);
}
void cpu_reset_sam9g20(void) __attribute__((weak));
void cpu_reset_sam9g20(void) {}
void
at91_rst_cpu_reset(void)
{
if (at91_rst_sc) {
cpu_reset_sam9g20(); /* May be null */
WR4(at91_rst_sc, RST_MR,
RST_MR_ERSTL(0xd) | RST_MR_URSTEN | RST_MR_KEY);
WR4(at91_rst_sc, RST_CR,
RST_CR_PROCRST |
RST_CR_PERRST |
RST_CR_EXTRST |
RST_CR_KEY);
}
while(1)
continue;
}
static int
at91_rst_probe(device_t dev)
{
#ifdef FDT
if (!ofw_bus_is_compatible(dev, "atmel,at91sam9260-rstc"))
return (ENXIO);
#endif
device_set_desc(dev, "AT91SAM9 Reset Controller");
return (0);
}
static int
at91_rst_attach(device_t dev)
{
struct at91_rst_softc *sc;
const char *cause;
int rid, err = 0;
at91_rst_sc = sc = device_get_softc(dev);
sc->sc_dev = dev;
callout_init(&sc->tick_ch, 1);
rid = 0;
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (sc->mem_res == NULL) {
device_printf(dev, "could not allocate memory resources.\n");
err = ENOMEM;
goto out;
}
#ifndef FDT_HACKS
rid = 0;
sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE | RF_SHAREABLE);
if (sc->irq_res == NULL) {
device_printf(dev, "could not allocate interrupt resources.\n");
err = ENOMEM;
goto out;
}
/* Activate the interrupt. */
err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
at91_rst_intr, NULL, sc, &sc->intrhand);
if (err)
device_printf(dev, "could not establish interrupt handler.\n");
#endif
WR4(at91_rst_sc, RST_MR, RST_MR_ERSTL(0xd) | RST_MR_URSIEN | RST_MR_KEY);
switch (RD4(sc, RST_SR) & RST_SR_RST_MASK) {
case RST_SR_RST_POW:
cause = "Power On";
break;
case RST_SR_RST_WAKE:
cause = "Wake Up";
break;
case RST_SR_RST_WDT:
cause = "Watchdog";
break;
case RST_SR_RST_SOFT:
cause = "Software Request";
break;
case RST_SR_RST_USR:
cause = "External (User)";
break;
default:
cause = "Unknown";
break;
}
device_printf(dev, "Reset cause: %s.\n", cause);
out:
return (err);
}
#ifndef FDT_HACKS
static void
at91_rst_tick(void *argp)
{
struct at91_rst_softc *sc = argp;
if (sc->shutdown++ >= RST_TIMEOUT * RST_TICK) {
/* User released the button in morre than RST_TIMEOUT */
cpu_reset();
} else if ((RD4(sc, RST_SR) & RST_SR_NRSTL)) {
/* User released the button in less than RST_TIMEOUT */
sc->shutdown = 0;
device_printf(sc->sc_dev, "shutting down...\n");
shutdown_nice(0);
} else {
callout_reset(&sc->tick_ch, hz/RST_TICK, at91_rst_tick, sc);
}
}
static int
at91_rst_intr(void *argp)
{
struct at91_rst_softc *sc = argp;
if (RD4(sc, RST_SR) & RST_SR_URSTS) {
if (sc->shutdown == 0)
callout_reset(&sc->tick_ch, hz/RST_TICK, at91_rst_tick, sc);
return (FILTER_HANDLED);
}
return (FILTER_STRAY);
}
#endif
static device_method_t at91_rst_methods[] = {
DEVMETHOD(device_probe, at91_rst_probe),
DEVMETHOD(device_attach, at91_rst_attach),
DEVMETHOD_END
};
static driver_t at91_rst_driver = {
"at91_rst",
at91_rst_methods,
sizeof(struct at91_rst_softc),
};
static devclass_t at91_rst_devclass;
#ifdef FDT
DRIVER_MODULE(at91_rst, simplebus, at91_rst_driver, at91_rst_devclass, NULL,
NULL);
#else
DRIVER_MODULE(at91_rst, atmelarm, at91_rst_driver, at91_rst_devclass, NULL,
NULL);
#endif

View File

@ -1,65 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2009 Greg Ansley. 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 ARM_AT91_AT91_RSTREG_H
#define ARM_AT91_AT91_RSTREG_H
#define RST_CR 0x0 /* Control Register */
#define RST_SR 0x4 /* Status Register */
#define RST_MR 0x8 /* Mode Register */
/* RST_CR */
#define RST_CR_PROCRST (1<<0)
#define RST_CR_PERRST (1<<2)
#define RST_CR_EXTRST (1<<3)
#define RST_CR_KEY (0xa5<<24)
/* RST_SR */
#define RST_SR_SRCMP (1<<17) /* Software Reset in progress */
#define RST_SR_NRSTL (1<<16) /* NRST pin level at MCK */
#define RST_SR_URSTS (1<<0) /* NRST pin has been active */
#define RST_SR_RST_POW (0<<8) /* General (Power On) reset */
#define RST_SR_RST_WAKE (1<<8) /* Wake-up reset */
#define RST_SR_RST_WDT (2<<8) /* Watchdog reset */
#define RST_SR_RST_SOFT (3<<8) /* Software reset */
#define RST_SR_RST_USR (4<<8) /* User (External) reset */
#define RST_SR_RST_MASK (7<<8) /* User (External) reset */
/* RST_MR */
#define RST_MR_URSTEN (1<<0) /* User reset enable */
#define RST_MR_URSIEN (1<<4) /* User interrupt enable */
#define RST_MR_ERSTL(x) ((x)<<8) /* External reset length */
#define RST_MR_KEY (0xa5<<24)
#ifndef __ASSEMBLER__
void at91_rst_cpu_reset(void);
#endif
#endif /* ARM_AT91_AT91_RSTREG_H */

View File

@ -1,366 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2006 M. Warner Losh.
* Copyright (c) 2012 Ian Lepore. 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.
*/
/*
* Driver for the at91 on-chip realtime clock.
*
* This driver does not currently support alarms, just date and time.
*
* The RTC on the AT91RM9200 resets when the core rests, so it is useless as a
* source of time (except when the CPU clock is powered down to save power,
* which we don't currently do). On AT91SAM9 chips, the RTC survives chip
* reset, and there's provisions for it to keep time via battery backup if the
* system loses power. On those systems, we use it as a RTC. We tell the two
* apart because the century field is 19 on AT91RM9200 on reset, or on AT91SAM9
* chips that haven't had their time properly set.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/clock.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mbuf.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/rman.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <arm/at91/at91_rtcreg.h>
#include "clock_if.h"
/*
* The driver has all the infrastructure to use interrupts but doesn't actually
* have any need to do so right now. There's a non-zero cost for installing the
* handler because the RTC shares the system interrupt (IRQ 1), and thus will
* get called a lot for no reason at all.
*/
#define AT91_RTC_USE_INTERRUPTS_NOT
struct at91_rtc_softc
{
device_t dev; /* Myself */
void *intrhand; /* Interrupt handle */
struct resource *irq_res; /* IRQ resource */
struct resource *mem_res; /* Memory resource */
struct mtx sc_mtx; /* basically a perimeter lock */
};
static inline uint32_t
RD4(struct at91_rtc_softc *sc, bus_size_t off)
{
return bus_read_4(sc->mem_res, off);
}
static inline void
WR4(struct at91_rtc_softc *sc, bus_size_t off, uint32_t val)
{
bus_write_4(sc->mem_res, off, val);
}
#define AT91_RTC_LOCK(_sc) mtx_lock_spin(&(_sc)->sc_mtx)
#define AT91_RTC_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->sc_mtx)
#define AT91_RTC_LOCK_INIT(_sc) \
mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \
"rtc", MTX_SPIN)
#define AT91_RTC_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx);
#define AT91_RTC_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED);
#define AT91_RTC_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
static devclass_t at91_rtc_devclass;
/* bus entry points */
static int at91_rtc_probe(device_t dev);
static int at91_rtc_attach(device_t dev);
static int at91_rtc_detach(device_t dev);
/* helper routines */
static int at91_rtc_activate(device_t dev);
static void at91_rtc_deactivate(device_t dev);
#ifdef AT91_RTC_USE_INTERRUPTS
static int
at91_rtc_intr(void *xsc)
{
struct at91_rtc_softc *sc;
uint32_t status;
sc = xsc;
/* Must clear the status bits after reading them to re-arm. */
status = RD4(sc, RTC_SR);
WR4(sc, RTC_SCCR, status);
if (status == 0)
return;
AT91_RTC_LOCK(sc);
/* Do something here */
AT91_RTC_UNLOCK(sc);
wakeup(sc);
return (FILTER_HANDLED);
}
#endif
static int
at91_rtc_probe(device_t dev)
{
device_set_desc(dev, "RTC");
return (0);
}
static int
at91_rtc_attach(device_t dev)
{
struct at91_rtc_softc *sc = device_get_softc(dev);
int err;
sc->dev = dev;
err = at91_rtc_activate(dev);
if (err)
goto out;
AT91_RTC_LOCK_INIT(sc);
/*
* Disable all interrupts in the hardware.
* Clear all bits in the status register.
* Set 24-hour-clock mode.
*/
WR4(sc, RTC_IDR, 0xffffffff);
WR4(sc, RTC_SCCR, 0x1f);
WR4(sc, RTC_MR, 0);
#ifdef AT91_RTC_USE_INTERRUPTS
err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC,
at91_rtc_intr, NULL, sc, &sc->intrhand);
if (err) {
AT91_RTC_LOCK_DESTROY(sc);
goto out;
}
#endif
/*
* Read the calendar register. If the century is 19 then the clock has
* never been set. Try to store an invalid value into the register,
* which will turn on the error bit in RTC_VER, and our getclock code
* knows to return EINVAL if any error bits are on.
*/
if (RTC_CALR_CEN(RD4(sc, RTC_CALR)) == 19)
WR4(sc, RTC_CALR, 0);
/*
* Register as a time of day clock with 1-second resolution.
*/
clock_register(dev, 1000000);
out:
if (err)
at91_rtc_deactivate(dev);
return (err);
}
/*
* Cannot support detach, since there's no clock_unregister function.
*/
static int
at91_rtc_detach(device_t dev)
{
return (EBUSY);
}
static int
at91_rtc_activate(device_t dev)
{
struct at91_rtc_softc *sc;
int rid;
sc = device_get_softc(dev);
rid = 0;
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (sc->mem_res == NULL)
goto errout;
#ifdef AT91_RTC_USE_INTERRUPTS
rid = 0;
sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE | RF_SHAREABLE);
if (sc->irq_res == NULL)
goto errout;
#endif
return (0);
errout:
at91_rtc_deactivate(dev);
return (ENOMEM);
}
static void
at91_rtc_deactivate(device_t dev)
{
struct at91_rtc_softc *sc;
sc = device_get_softc(dev);
#ifdef AT91_RTC_USE_INTERRUPTS
WR4(sc, RTC_IDR, 0xffffffff);
if (sc->intrhand)
bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
sc->intrhand = NULL;
#endif
bus_generic_detach(sc->dev);
if (sc->mem_res)
bus_release_resource(dev, SYS_RES_MEMORY,
rman_get_rid(sc->mem_res), sc->mem_res);
sc->mem_res = NULL;
#ifdef AT91_RTC_USE_INTERRUPTS
if (sc->irq_res)
bus_release_resource(dev, SYS_RES_IRQ,
rman_get_rid(sc->irq_res), sc->irq_res);
sc->irq_res = NULL;
#endif
return;
}
/*
* Get the time of day clock and return it in ts.
* Return 0 on success, an error number otherwise.
*/
static int
at91_rtc_gettime(device_t dev, struct timespec *ts)
{
struct clocktime ct;
uint32_t calr, calr2, timr, timr2;
struct at91_rtc_softc *sc;
sc = device_get_softc(dev);
/* If the error bits are set we can't return useful values. */
if (RD4(sc, RTC_VER) & (RTC_VER_NVTIM | RTC_VER_NVCAL))
return EINVAL;
/*
* The RTC hardware can update registers while the CPU is reading them.
* The manual advises reading until you obtain the same values twice.
* Interleaving the reads (rather than timr, timr2, calr, calr2 order)
* also ensures we don't miss a midnight rollover/carry between reads.
*/
do {
timr = RD4(sc, RTC_TIMR);
calr = RD4(sc, RTC_CALR);
timr2 = RD4(sc, RTC_TIMR);
calr2 = RD4(sc, RTC_CALR);
} while (timr != timr2 || calr != calr2);
ct.nsec = 0;
ct.sec = RTC_TIMR_SEC(timr);
ct.min = RTC_TIMR_MIN(timr);
ct.hour = RTC_TIMR_HR(timr);
ct.year = RTC_CALR_CEN(calr) * 100 + RTC_CALR_YEAR(calr);
ct.mon = RTC_CALR_MON(calr);
ct.day = RTC_CALR_DAY(calr);
ct.dow = -1;
return clock_ct_to_ts(&ct, ts);
}
/*
* Set the time of day clock based on the value of the struct timespec arg.
* Return 0 on success, an error number otherwise.
*/
static int
at91_rtc_settime(device_t dev, struct timespec *ts)
{
struct at91_rtc_softc *sc;
struct clocktime ct;
int rv;
sc = device_get_softc(dev);
clock_ts_to_ct(ts, &ct);
/*
* Can't set the clock unless a second has elapsed since we last did so.
*/
while ((RD4(sc, RTC_SR) & RTC_SR_SECEV) == 0)
cpu_spinwait();
/*
* Stop the clocks for an update; wait until hardware is ready.
* Clear the update-ready status after it gets asserted (the manual says
* to do this before updating the value registers).
*/
WR4(sc, RTC_CR, RTC_CR_UPDCAL | RTC_CR_UPDTIM);
while ((RD4(sc, RTC_SR) & RTC_SR_ACKUPD) == 0)
cpu_spinwait();
WR4(sc, RTC_SCCR, RTC_SR_ACKUPD);
/*
* Set the values in the hardware, then check whether the hardware was
* happy with them so we can return the correct status.
*/
WR4(sc, RTC_TIMR, RTC_TIMR_MK(ct.hour, ct.min, ct.sec));
WR4(sc, RTC_CALR, RTC_CALR_MK(ct.year, ct.mon, ct.day, ct.dow+1));
if (RD4(sc, RTC_VER) & (RTC_VER_NVTIM | RTC_VER_NVCAL))
rv = EINVAL;
else
rv = 0;
/*
* Restart the clocks (turn off the update bits).
* Clear the second-event bit (because the manual says to).
*/
WR4(sc, RTC_CR, RD4(sc, RTC_CR) & ~(RTC_CR_UPDCAL | RTC_CR_UPDTIM));
WR4(sc, RTC_SCCR, RTC_SR_SECEV);
return (0);
}
static device_method_t at91_rtc_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, at91_rtc_probe),
DEVMETHOD(device_attach, at91_rtc_attach),
DEVMETHOD(device_detach, at91_rtc_detach),
/* clock interface */
DEVMETHOD(clock_gettime, at91_rtc_gettime),
DEVMETHOD(clock_settime, at91_rtc_settime),
DEVMETHOD_END
};
static driver_t at91_rtc_driver = {
"at91_rtc",
at91_rtc_methods,
sizeof(struct at91_rtc_softc),
};
DRIVER_MODULE(at91_rtc, atmelarm, at91_rtc_driver, at91_rtc_devclass, 0, 0);

View File

@ -1,105 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2006 M. Warner Losh.
*
* 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 ARM_AT91_AT91_RTCREG_H
#define ARM_AT91_AT91_RTCREG_H
/* Registers */
#define RTC_CR 0x00 /* RTC Control Register */
#define RTC_MR 0x04 /* RTC Mode Register */
#define RTC_TIMR 0x08 /* RTC Time Register */
#define RTC_CALR 0x0c /* RTC Calendar Register */
#define RTC_TIMALR 0x10 /* RTC Time Alarm Register */
#define RTC_CALALR 0x14 /* RTC Calendar Alarm Register */
#define RTC_SR 0x18 /* RTC Status Register */
#define RTC_SCCR 0x1c /* RTC Status Command Clear Register */
#define RTC_IER 0x20 /* RTC Interrupt Enable Register */
#define RTC_IDR 0x24 /* RTC Interrupt Disable Register */
#define RTC_IMR 0x28 /* RTC Interrupt Mask Register */
#define RTC_VER 0x2c /* RTC Valid Entry Register */
/* CR */
#define RTC_CR_UPDTIM (0x1u << 0) /* Request update of time register */
#define RTC_CR_UPDCAL (0x1u << 1) /* Request update of calendar reg. */
/* TIMR */
#define RTC_TIMR_SEC_M 0x7fUL
#define RTC_TIMR_SEC_S 0
#define RTC_TIMR_SEC(x) FROMBCD(((x) & RTC_TIMR_SEC_M) >> RTC_TIMR_SEC_S)
#define RTC_TIMR_MIN_M 0x7f00UL
#define RTC_TIMR_MIN_S 8
#define RTC_TIMR_MIN(x) FROMBCD(((x) & RTC_TIMR_MIN_M) >> RTC_TIMR_MIN_S)
#define RTC_TIMR_HR_M 0x3f0000UL
#define RTC_TIMR_HR_S 16
#define RTC_TIMR_HR(x) FROMBCD(((x) & RTC_TIMR_HR_M) >> RTC_TIMR_HR_S)
#define RTC_TIMR_MK(hr, min, sec) \
((TOBCD(hr) << RTC_TIMR_HR_S) | \
(TOBCD(min) << RTC_TIMR_MIN_S) | \
(TOBCD(sec) << RTC_TIMR_SEC_S))
#define RTC_TIMR_PM (1UL << 22)
/* CALR */
#define RTC_CALR_CEN_M 0x0000007fUL
#define RTC_CALR_CEN_S 0
#define RTC_CALR_CEN(x) FROMBCD(((x) & RTC_CALR_CEN_M) >> RTC_CALR_CEN_S)
#define RTC_CALR_YEAR_M 0x0000ff00UL
#define RTC_CALR_YEAR_S 8
#define RTC_CALR_YEAR(x) FROMBCD(((x) & RTC_CALR_YEAR_M) >> RTC_CALR_YEAR_S)
#define RTC_CALR_MON_M 0x001f0000UL
#define RTC_CALR_MON_S 16
#define RTC_CALR_MON(x) FROMBCD(((x) & RTC_CALR_MON_M) >> RTC_CALR_MON_S)
#define RTC_CALR_DOW_M 0x00d0000UL
#define RTC_CALR_DOW_S 21
#define RTC_CALR_DOW(x) FROMBCD(((x) & RTC_CALR_DOW_M) >> RTC_CALR_DOW_S)
#define RTC_CALR_DAY_M 0x3f000000UL
#define RTC_CALR_DAY_S 24
#define RTC_CALR_DAY(x) FROMBCD(((x) & RTC_CALR_DAY_M) >> RTC_CALR_DAY_S)
#define RTC_CALR_MK(yr, mon, day, dow) \
((TOBCD((yr) / 100) << RTC_CALR_CEN_S) | \
(TOBCD((yr) % 100) << RTC_CALR_YEAR_S) | \
(TOBCD(mon) << RTC_CALR_MON_S) | \
(TOBCD(dow) << RTC_CALR_DOW_S) | \
(TOBCD(day) << RTC_CALR_DAY_S))
/* SR */
#define RTC_SR_ACKUPD (0x1u << 0) /* Acknowledge for Update */
#define RTC_SR_ALARM (0x1u << 1) /* Alarm Flag */
#define RTC_SR_SECEV (0x1u << 2) /* Second Event */
#define RTC_SR_TIMEV (0x1u << 3) /* Time Event */
#define RTC_SR_CALEV (0x1u << 4) /* Calendar event */
/* VER */
#define RTC_VER_NVTIM (0x1 << 0) /* Non-valid time */
#define RTC_VER_NVCAL (0x1 << 1) /* Non-valid calendar */
#define RTC_VER_NVTIMALR (0x1 << 2) /* Non-valid time alarm */
#define RTC_VER_NVCALALR (0x1 << 3) /* Non-valid calendar alarm */
#endif /* ARM_AT91_AT91_RTCREG_H */

View File

@ -1,106 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2014 M. Warner Losh.
*
* 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 "opt_platform.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/resource.h>
#include <sys/systm.h>
#include <sys/rman.h>
#include <machine/bus.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91_aicreg.h>
#ifdef FDT
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#endif
struct sdramc_softc {
struct resource *mem_res; /* Memory resource */
device_t sc_dev;
};
static int
at91_sdramc_probe(device_t dev)
{
#ifdef FDT
if (!ofw_bus_is_compatible(dev, "atmel,at91sam9260-sdramc"))
return (ENXIO);
#endif
device_set_desc(dev, "SDRAMC");
return (0);
}
static int
at91_sdramc_attach(device_t dev)
{
int rid, err = 0;
struct sdramc_softc *sc;
sc = device_get_softc(dev);
sc->sc_dev = dev;
rid = 0;
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (sc->mem_res == NULL)
panic("couldn't allocate register resources");
return (err);
}
static device_method_t at91_sdramc_methods[] = {
DEVMETHOD(device_probe, at91_sdramc_probe),
DEVMETHOD(device_attach, at91_sdramc_attach),
DEVMETHOD_END
};
static driver_t at91_sdramc_driver = {
"at91_sdramc",
at91_sdramc_methods,
sizeof(struct sdramc_softc),
};
static devclass_t at91_sdramc_devclass;
#ifdef FDT
DRIVER_MODULE(at91_sdramc, simplebus, at91_sdramc_driver, at91_sdramc_devclass, NULL,
NULL);
#else
DRIVER_MODULE(at91_sdramc, atmelarm, at91_sdramc_driver, at91_sdramc_devclass, NULL,
NULL);
#endif

View File

@ -1,106 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2014 M. Warner Losh.
*
* 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 "opt_platform.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/resource.h>
#include <sys/systm.h>
#include <sys/rman.h>
#include <machine/bus.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91_aicreg.h>
#ifdef FDT
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#endif
struct shdwc_softc {
struct resource *mem_res; /* Memory resource */
device_t sc_dev;
};
static int
at91_shdwc_probe(device_t dev)
{
#ifdef FDT
if (!ofw_bus_is_compatible(dev, "atmel,at91sam9260-shdwc"))
return (ENXIO);
#endif
device_set_desc(dev, "SHDWC");
return (0);
}
static int
at91_shdwc_attach(device_t dev)
{
int rid, err = 0;
struct shdwc_softc *sc;
sc = device_get_softc(dev);
sc->sc_dev = dev;
rid = 0;
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (sc->mem_res == NULL)
panic("couldn't allocate register resources");
return (err);
}
static device_method_t at91_shdwc_methods[] = {
DEVMETHOD(device_probe, at91_shdwc_probe),
DEVMETHOD(device_attach, at91_shdwc_attach),
DEVMETHOD_END
};
static driver_t at91_shdwc_driver = {
"at91_shdwc",
at91_shdwc_methods,
sizeof(struct shdwc_softc),
};
static devclass_t at91_shdwc_devclass;
#ifdef FDT
DRIVER_MODULE(at91_shdwc, simplebus, at91_shdwc_driver, at91_shdwc_devclass, NULL,
NULL);
#else
DRIVER_MODULE(at91_shdwc, atmelarm, at91_shdwc_driver, at91_shdwc_devclass, NULL,
NULL);
#endif

View File

@ -1,93 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2014 M. Warner Losh.
*
* 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/types.h>
#include <arm/at91/at91reg.h>
#include <arm/at91/at91_smc.h>
#include <arm/at91/at91sam9260reg.h>
/*
* RD4HW()/WR4HW() read and write at91 hardware register space directly. They
* serve the same purpose as the RD4()/WR4() idiom you see in many drivers,
* except that those translate to bus_space calls, but in this code we need to
* access some devices before bus_space is ready to use. Of course for this to
* work the appropriate static device mappings need to be made in machdep.c.
*/
static inline uint32_t
RD4HW(uint32_t devbase, uint32_t regoff)
{
return *(volatile uint32_t *)(AT91_BASE + devbase + regoff);
}
static inline void
WR4HW(uint32_t devbase, uint32_t regoff, uint32_t val)
{
*(volatile uint32_t *)(AT91_BASE + devbase + regoff) = val;
}
void
at91_smc_setup(int id, int cs, const struct at91_smc_init *smc)
{
// Need a generic way to get this address for all SoCs... Assume 9260 for now...
uint32_t base = AT91SAM9260_SMC_BASE + SMC_CS_OFF(cs);
WR4HW(base, SMC_SETUP, SMC_SETUP_NCS_RD_SETUP(smc->ncs_rd_setup) |
SMC_SETUP_NRD_SETUP(smc->nrd_setup) |
SMC_SETUP_NCS_WR_SETUP(smc->ncs_wr_setup) |
SMC_SETUP_NWE_SETUP(smc->nwe_setup));
WR4HW(base, SMC_PULSE, SMC_PULSE_NCS_RD_PULSE(smc->ncs_rd_pulse) |
SMC_PULSE_NRD_PULSE(smc->nrd_pulse) |
SMC_PULSE_NCS_WR_PULSE(smc->ncs_wr_pulse) |
SMC_PULSE_NWE_PULSE(smc->nwe_pulse));
WR4HW(base, SMC_CYCLE, SMC_CYCLE_NRD_CYCLE(smc->nrd_cycle) |
SMC_CYCLE_NWE_CYCLE(smc->nwe_cycle));
WR4HW(base, SMC_MODE, smc->mode | SMC_MODE_TDF_CYCLES(smc->tdf_cycles));
}
void
at91_ebi_enable(int bank)
{
WR4HW(AT91SAM9260_MATRIX_BASE, AT91SAM9260_EBICSA, (1 << bank) |
RD4HW(AT91SAM9260_MATRIX_BASE, AT91SAM9260_EBICSA));
}
void
at91_ebi_disable(int bank)
{
WR4HW(AT91SAM9260_MATRIX_BASE, AT91SAM9260_EBICSA, ~(1 << bank) &
RD4HW(AT91SAM9260_MATRIX_BASE, AT91SAM9260_EBICSA));
}

View File

@ -1,118 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2014 M. Warner Losh.
*
* 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 ARM_AT91_AT91_SMC_H
#define ARM_AT91_AT91_SMC_H
/* Registers */
#define SMC_SETUP 0x00
#define SMC_PULSE 0x04
#define SMC_CYCLE 0x08
#define SMC_MODE 0x0C
#define SMC_CS_OFF(cs) (0x10 * (cs))
/* Setup */
#define SMC_SETUP_NCS_RD_SETUP(x) ((x) << 24)
#define SMC_SETUP_NRD_SETUP(x) ((x) << 16)
#define SMC_SETUP_NCS_WR_SETUP(x) ((x) << 8)
#define SMC_SETUP_NWE_SETUP(x) (x)
/* Pulse */
#define SMC_PULSE_NCS_RD_PULSE(x) ((x) << 24)
#define SMC_PULSE_NRD_PULSE(x) ((x) << 16)
#define SMC_PULSE_NCS_WR_PULSE(x) ((x) << 8)
#define SMC_PULSE_NWE_PULSE(x) (x)
/* Cycle */
#define SMC_CYCLE_NRD_CYCLE(x) ((x) << 16)
#define SMC_CYCLE_NWE_CYCLE(x) (x)
/* Mode */
#define SMC_MODE_READ (1 << 0)
#define SMC_MODE_WRITE (1 << 1)
#define SMC_MODE_EXNW_DISABLED (0 << 4)
#define SMC_MODE_EXNW_FROZEN_MODE (2 << 4)
#define SMC_MODE_EXNW_READY_MODE (3 << 4)
#define SMC_MODE_BAT (1 << 8)
#define SMC_MODE_DBW_8BIT (0 << 12)
#define SMC_MODE_DBW_16BIT (1 << 12)
#define SMC_MODE_DBW_32_BIT (2 << 12)
#define SMC_MODE_TDF_CYCLES(x) ((x) << 16)
#define SMC_MODE_TDF_MODE (1 << 20)
#define SMC_MODE_PMEN (1 << 24)
#define SMC_PS_4BYTE (0 << 28)
#define SMC_PS_8BYTE (1 << 28)
#define SMC_PS_16BYTE (2 << 28)
#define SMC_PS_32BYTE (3 << 28)
/*
* structure to ease init. See the SMC chapter in the datasheet for
* the appropriate SoC you are using for details.
*/
struct at91_smc_init
{
/* Setup register */
uint8_t ncs_rd_setup;
uint8_t nrd_setup;
uint8_t ncs_wr_setup;
uint8_t nwe_setup;
/* Pulse register */
uint8_t ncs_rd_pulse;
uint8_t nrd_pulse;
uint8_t ncs_wr_pulse;
uint8_t nwe_pulse;
/* Cycle register */
uint16_t nrd_cycle;
uint16_t nwe_cycle;
/* Mode register */
uint8_t mode; /* Combo of READ/WRITE/EXNW fields */
uint8_t bat;
uint8_t dwb;
uint8_t tdf_cycles;
uint8_t tdf_mode;
uint8_t pmen;
uint8_t ps;
};
/*
* Convenience routine to fill in SMC registers for a given chip select.
*/
void at91_smc_setup(int id, int cs, const struct at91_smc_init *smc);
/*
* Disable/Enable different External Bus Interfaces (EBI)
*/
void at91_ebi_enable(int cs);
void at91_ebi_disable(int cs);
#endif /* ARM_AT91_AT91_SMC_H */

View File

@ -1,461 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2006 M. Warner Losh.
* Copyright (c) 2011-2012 Ian Lepore.
* 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 "opt_platform.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mbuf.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/rman.h>
#include <sys/sx.h>
#include <machine/bus.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91_spireg.h>
#include <arm/at91/at91_pdcreg.h>
#include <dev/spibus/spi.h>
#include <dev/spibus/spibusvar.h>
#ifdef FDT
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#endif
#include "spibus_if.h"
struct at91_spi_softc
{
device_t dev; /* Myself */
void *intrhand; /* Interrupt handle */
struct resource *irq_res; /* IRQ resource */
struct resource *mem_res; /* Memory resource */
bus_dma_tag_t dmatag; /* bus dma tag for transfers */
bus_dmamap_t map[4]; /* Maps for the transaction */
struct sx xfer_mtx; /* Enforce one transfer at a time */
uint32_t xfer_done; /* interrupt<->mainthread signaling */
};
#define CS_TO_MR(cs) ((~(1 << (cs)) & 0x0f) << 16)
static inline uint32_t
RD4(struct at91_spi_softc *sc, bus_size_t off)
{
return (bus_read_4(sc->mem_res, off));
}
static inline void
WR4(struct at91_spi_softc *sc, bus_size_t off, uint32_t val)
{
bus_write_4(sc->mem_res, off, val);
}
/* bus entry points */
static int at91_spi_attach(device_t dev);
static int at91_spi_detach(device_t dev);
static int at91_spi_probe(device_t dev);
static int at91_spi_transfer(device_t dev, device_t child,
struct spi_command *cmd);
/* helper routines */
static void at91_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs,
int error);
static int at91_spi_activate(device_t dev);
static void at91_spi_deactivate(device_t dev);
static void at91_spi_intr(void *arg);
static int
at91_spi_probe(device_t dev)
{
#ifdef FDT
if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-spi"))
return (ENXIO);
#endif
device_set_desc(dev, "AT91 SPI");
return (0);
}
static int
at91_spi_attach(device_t dev)
{
struct at91_spi_softc *sc;
int err;
uint32_t csr;
sc = device_get_softc(dev);
sc->dev = dev;
sx_init(&sc->xfer_mtx, device_get_nameunit(dev));
/*
* Allocate resources.
*/
err = at91_spi_activate(dev);
if (err)
goto out;
#ifdef FDT
/*
* Disable devices need to hold their resources, so return now and not attach
* the spibus, setup interrupt handlers, etc.
*/
if (!ofw_bus_status_okay(dev))
return 0;
#endif
/*
* Set up the hardware.
*/
WR4(sc, SPI_CR, SPI_CR_SWRST);
/* "Software Reset must be Written Twice" erratum */
WR4(sc, SPI_CR, SPI_CR_SWRST);
WR4(sc, SPI_IDR, 0xffffffff);
WR4(sc, SPI_MR, (0xf << 24) | SPI_MR_MSTR | SPI_MR_MODFDIS |
CS_TO_MR(0));
/*
* For now, run the bus at the slowest speed possible as otherwise we
* may encounter data corruption on transmit as seen with ETHERNUT5
* and AT45DB321D even though both board and slave device can take
* more.
* This also serves as a work-around for the "NPCSx rises if no data
* data is to be transmitted" erratum. The ideal workaround for the
* latter is to take the chip select control away from the peripheral
* and manage it directly as a GPIO line. The easy solution is to
* slow down the bus so dramatically that it just never gets starved
* as may be seen when the OCHI controller is running and consuming
* memory and APB bandwidth.
* Also, currently we lack a way for lettting both the board and the
* slave devices take their maximum supported SPI clocks into account.
* Also, we hard-wire SPI mode to 3.
*/
csr = SPI_CSR_CPOL | (4 << 16) | (0xff << 8);
WR4(sc, SPI_CSR0, csr);
WR4(sc, SPI_CSR1, csr);
WR4(sc, SPI_CSR2, csr);
WR4(sc, SPI_CSR3, csr);
WR4(sc, SPI_CR, SPI_CR_SPIEN);
WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS);
WR4(sc, PDC_PTCR, PDC_PTCR_RXTDIS);
WR4(sc, PDC_RNPR, 0);
WR4(sc, PDC_RNCR, 0);
WR4(sc, PDC_TNPR, 0);
WR4(sc, PDC_TNCR, 0);
WR4(sc, PDC_RPR, 0);
WR4(sc, PDC_RCR, 0);
WR4(sc, PDC_TPR, 0);
WR4(sc, PDC_TCR, 0);
RD4(sc, SPI_RDR);
RD4(sc, SPI_SR);
device_add_child(dev, "spibus", -1);
bus_generic_attach(dev);
out:
if (err)
at91_spi_deactivate(dev);
return (err);
}
static int
at91_spi_detach(device_t dev)
{
return (EBUSY); /* XXX */
}
static int
at91_spi_activate(device_t dev)
{
struct at91_spi_softc *sc;
int err, i, rid;
sc = device_get_softc(dev);
err = ENOMEM;
rid = 0;
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (sc->mem_res == NULL)
goto out;
rid = 0;
sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE);
if (sc->irq_res == NULL)
goto out;
err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
NULL, at91_spi_intr, sc, &sc->intrhand);
if (err != 0)
goto out;
err = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, 2048, 1,
2048, BUS_DMA_ALLOCNOW, NULL, NULL, &sc->dmatag);
if (err != 0)
goto out;
for (i = 0; i < 4; i++) {
err = bus_dmamap_create(sc->dmatag, 0, &sc->map[i]);
if (err != 0)
goto out;
}
out:
if (err != 0)
at91_spi_deactivate(dev);
return (err);
}
static void
at91_spi_deactivate(device_t dev)
{
struct at91_spi_softc *sc;
int i;
sc = device_get_softc(dev);
bus_generic_detach(dev);
for (i = 0; i < 4; i++)
if (sc->map[i])
bus_dmamap_destroy(sc->dmatag, sc->map[i]);
if (sc->dmatag)
bus_dma_tag_destroy(sc->dmatag);
if (sc->intrhand)
bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
sc->intrhand = NULL;
if (sc->irq_res)
bus_release_resource(dev, SYS_RES_IRQ,
rman_get_rid(sc->irq_res), sc->irq_res);
sc->irq_res = NULL;
if (sc->mem_res)
bus_release_resource(dev, SYS_RES_MEMORY,
rman_get_rid(sc->mem_res), sc->mem_res);
sc->mem_res = NULL;
}
static void
at91_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs __unused,
int error)
{
if (error != 0)
return;
*(bus_addr_t *)arg = segs[0].ds_addr;
}
static int
at91_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
{
struct at91_spi_softc *sc;
bus_addr_t addr;
int err, i, j, mode[4];
uint32_t cs;
KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz,
("%s: TX/RX command sizes should be equal", __func__));
KASSERT(cmd->tx_data_sz == cmd->rx_data_sz,
("%s: TX/RX data sizes should be equal", __func__));
/* get the proper chip select */
spibus_get_cs(child, &cs);
cs &= ~SPIBUS_CS_HIGH;
sc = device_get_softc(dev);
i = 0;
sx_xlock(&sc->xfer_mtx);
/*
* Disable transfers while we set things up.
*/
WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS);
/*
* PSCDEC = 0 has a range of 0..3 for chip select. We
* don't support PSCDEC = 1 which has a range of 0..15.
*/
if (cs > 3) {
device_printf(dev,
"Invalid chip select %d requested by %s\n", cs,
device_get_nameunit(child));
err = EINVAL;
goto out;
}
#ifdef SPI_CHIP_SELECT_HIGH_SUPPORT
/*
* The AT91RM9200 couldn't do CS high for CS 0. Other chips can, but we
* don't support that yet, or other spi modes.
*/
if (at91_is_rm92() && cs == 0 &&
(cmd->flags & SPI_CHIP_SELECT_HIGH) != 0) {
device_printf(dev,
"Invalid chip select high requested by %s for cs 0.\n",
device_get_nameunit(child));
err = EINVAL;
goto out;
}
#endif
err = (RD4(sc, SPI_MR) & ~0x000f0000) | CS_TO_MR(cs);
WR4(sc, SPI_MR, err);
/*
* Set up the TX side of the transfer.
*/
if ((err = bus_dmamap_load(sc->dmatag, sc->map[i], cmd->tx_cmd,
cmd->tx_cmd_sz, at91_getaddr, &addr, 0)) != 0)
goto out;
WR4(sc, PDC_TPR, addr);
WR4(sc, PDC_TCR, cmd->tx_cmd_sz);
bus_dmamap_sync(sc->dmatag, sc->map[i], BUS_DMASYNC_PREWRITE);
mode[i++] = BUS_DMASYNC_POSTWRITE;
if (cmd->tx_data_sz > 0) {
if ((err = bus_dmamap_load(sc->dmatag, sc->map[i],
cmd->tx_data, cmd->tx_data_sz, at91_getaddr, &addr, 0)) !=
0)
goto out;
WR4(sc, PDC_TNPR, addr);
WR4(sc, PDC_TNCR, cmd->tx_data_sz);
bus_dmamap_sync(sc->dmatag, sc->map[i], BUS_DMASYNC_PREWRITE);
mode[i++] = BUS_DMASYNC_POSTWRITE;
}
/*
* Set up the RX side of the transfer.
*/
if ((err = bus_dmamap_load(sc->dmatag, sc->map[i], cmd->rx_cmd,
cmd->rx_cmd_sz, at91_getaddr, &addr, 0)) != 0)
goto out;
WR4(sc, PDC_RPR, addr);
WR4(sc, PDC_RCR, cmd->rx_cmd_sz);
bus_dmamap_sync(sc->dmatag, sc->map[i], BUS_DMASYNC_PREREAD);
mode[i++] = BUS_DMASYNC_POSTREAD;
if (cmd->rx_data_sz > 0) {
if ((err = bus_dmamap_load(sc->dmatag, sc->map[i],
cmd->rx_data, cmd->rx_data_sz, at91_getaddr, &addr, 0)) !=
0)
goto out;
WR4(sc, PDC_RNPR, addr);
WR4(sc, PDC_RNCR, cmd->rx_data_sz);
bus_dmamap_sync(sc->dmatag, sc->map[i], BUS_DMASYNC_PREREAD);
mode[i++] = BUS_DMASYNC_POSTREAD;
}
/*
* Start the transfer, wait for it to complete.
*/
sc->xfer_done = 0;
WR4(sc, SPI_IER, SPI_SR_RXBUFF);
WR4(sc, PDC_PTCR, PDC_PTCR_TXTEN | PDC_PTCR_RXTEN);
do
err = tsleep(&sc->xfer_done, PCATCH | PZERO, "at91_spi", hz);
while (sc->xfer_done == 0 && err != EINTR);
/*
* Stop the transfer and clean things up.
*/
WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS);
if (err == 0)
for (j = 0; j < i; j++)
bus_dmamap_sync(sc->dmatag, sc->map[j], mode[j]);
out:
for (j = 0; j < i; j++)
bus_dmamap_unload(sc->dmatag, sc->map[j]);
sx_xunlock(&sc->xfer_mtx);
return (err);
}
static void
at91_spi_intr(void *arg)
{
struct at91_spi_softc *sc;
uint32_t sr;
sc = (struct at91_spi_softc*)arg;
sr = RD4(sc, SPI_SR) & RD4(sc, SPI_IMR);
if ((sr & SPI_SR_RXBUFF) != 0) {
sc->xfer_done = 1;
WR4(sc, SPI_IDR, SPI_SR_RXBUFF);
wakeup(&sc->xfer_done);
}
if ((sr & ~SPI_SR_RXBUFF) != 0) {
device_printf(sc->dev, "Unexpected ISR %#x\n", sr);
WR4(sc, SPI_IDR, sr & ~SPI_SR_RXBUFF);
}
}
static devclass_t at91_spi_devclass;
static device_method_t at91_spi_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, at91_spi_probe),
DEVMETHOD(device_attach, at91_spi_attach),
DEVMETHOD(device_detach, at91_spi_detach),
/* spibus interface */
DEVMETHOD(spibus_transfer, at91_spi_transfer),
DEVMETHOD_END
};
static driver_t at91_spi_driver = {
"spi",
at91_spi_methods,
sizeof(struct at91_spi_softc),
};
#ifdef FDT
DRIVER_MODULE(at91_spi, simplebus, at91_spi_driver, at91_spi_devclass, NULL,
NULL);
#else
DRIVER_MODULE(at91_spi, atmelarm, at91_spi_driver, at91_spi_devclass, NULL,
NULL);
#endif

View File

@ -1,71 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2006 M. Warner Losh.
*
* 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 ARM_AT91_AT91_SPIREG_H
#define ARM_AT91_AT91_SPIREG_H
#define SPI_CR 0x00 /* CR: Control Register */
#define SPI_CR_SPIEN 0x1
#define SPI_CR_SPIDIS 0x2
#define SPI_CR_SWRST 0x8
#define SPI_MR 0x04 /* MR: Mode Register */
#define SPI_MR_MSTR 0x01
#define SPI_MR_PS 0x02
#define SPI_MR_PCSDEC 0x04
#define SPI_MR_DIV32 0x08
#define SPI_MR_MODFDIS 0x10
#define SPI_MR_LLB 0x80
#define SPI_MR_PSC_CS0 0xe0000
#define SPI_MR_PSC_CS1 0xd0000
#define SPI_MR_PSC_CS2 0xb0000
#define SPI_MR_PSC_CS3 0x70000
#define SPI_RDR 0x08 /* RDR: Receive Data Register */
#define SPI_TDR 0x0c /* TDR: Transmit Data Register */
#define SPI_SR 0x10 /* SR: Status Register */
#define SPI_SR_RDRF 0x00001
#define SPI_SR_TDRE 0x00002
#define SPI_SR_MODF 0x00004
#define SPI_SR_OVRES 0x00008
#define SPI_SR_ENDRX 0x00010
#define SPI_SR_ENDTX 0x00020
#define SPI_SR_RXBUFF 0x00040
#define SPI_SR_TXBUFE 0x00080
#define SPI_SR_NSSR 0x00100
#define SPI_SR_TXEMPTY 0x00200
#define SPI_SR_SPIENS 0x10000
#define SPI_IER 0x14 /* IER: Interrupt Enable Regsiter */
#define SPI_IDR 0x18 /* IDR: Interrupt Disable Regsiter */
#define SPI_IMR 0x1c /* IMR: Interrupt Mask Regsiter */
#define SPI_CSR0 0x30 /* CS0: Chip Select 0 */
#define SPI_CSR_CPOL 0x01
#define SPI_CSR1 0x34 /* CS1: Chip Select 1 */
#define SPI_CSR2 0x38 /* CS2: Chip Select 2 */
#define SPI_CSR3 0x3c /* CS3: Chip Select 3 */
#endif /* ARM_AT91_AT91_SPIREG_H */

View File

@ -1,272 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2006 M. Warner Losh.
*
* 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/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/rman.h>
#include <machine/bus.h>
#include <arm/at91/at91_sscreg.h>
struct at91_ssc_softc
{
device_t dev; /* Myself */
void *intrhand; /* Interrupt handle */
struct resource *irq_res; /* IRQ resource */
struct resource *mem_res; /* Memory resource */
struct mtx sc_mtx; /* basically a perimeter lock */
struct cdev *cdev;
int flags;
#define OPENED 1
};
static inline uint32_t
RD4(struct at91_ssc_softc *sc, bus_size_t off)
{
return bus_read_4(sc->mem_res, off);
}
static inline void
WR4(struct at91_ssc_softc *sc, bus_size_t off, uint32_t val)
{
bus_write_4(sc->mem_res, off, val);
}
#define AT91_SSC_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
#define AT91_SSC_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
#define AT91_SSC_LOCK_INIT(_sc) \
mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->dev), \
"ssc", MTX_DEF)
#define AT91_SSC_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx);
#define AT91_SSC_ASSERT_LOCKED(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED);
#define AT91_SSC_ASSERT_UNLOCKED(_sc) mtx_assert(&(_sc)->sc_mtx, MA_NOTOWNED);
#define CDEV2SOFTC(dev) ((dev)->si_drv1)
static devclass_t at91_ssc_devclass;
/* bus entry points */
static int at91_ssc_probe(device_t dev);
static int at91_ssc_attach(device_t dev);
static int at91_ssc_detach(device_t dev);
static void at91_ssc_intr(void *);
/* helper routines */
static int at91_ssc_activate(device_t dev);
static void at91_ssc_deactivate(device_t dev);
/* cdev routines */
static d_open_t at91_ssc_open;
static d_close_t at91_ssc_close;
static d_read_t at91_ssc_read;
static d_write_t at91_ssc_write;
static struct cdevsw at91_ssc_cdevsw =
{
.d_version = D_VERSION,
.d_open = at91_ssc_open,
.d_close = at91_ssc_close,
.d_read = at91_ssc_read,
.d_write = at91_ssc_write,
};
static int
at91_ssc_probe(device_t dev)
{
device_set_desc(dev, "SSC");
return (0);
}
static int
at91_ssc_attach(device_t dev)
{
struct at91_ssc_softc *sc = device_get_softc(dev);
int err;
sc->dev = dev;
err = at91_ssc_activate(dev);
if (err)
goto out;
AT91_SSC_LOCK_INIT(sc);
/*
* Activate the interrupt
*/
err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
NULL, at91_ssc_intr, sc, &sc->intrhand);
if (err) {
AT91_SSC_LOCK_DESTROY(sc);
goto out;
}
sc->cdev = make_dev(&at91_ssc_cdevsw, device_get_unit(dev), UID_ROOT,
GID_WHEEL, 0600, "ssc%d", device_get_unit(dev));
if (sc->cdev == NULL) {
err = ENOMEM;
goto out;
}
sc->cdev->si_drv1 = sc;
// Init for TSC needs
WR4(sc, SSC_CR, SSC_CR_SWRST);
WR4(sc, SSC_CMR, 0); // clock divider unused
WR4(sc, SSC_RCMR,
SSC_RCMR_CKS_RK | SSC_RCMR_CKO_NONE | SSC_RCMR_START_FALL_EDGE_RF);
WR4(sc, SSC_RFMR,
0x1f | SSC_RFMR_MSFBF | SSC_RFMR_FSOS_NONE);
WR4(sc, SSC_TCMR,
SSC_TCMR_CKS_TK | SSC_TCMR_CKO_NONE | SSC_RCMR_START_CONT);
WR4(sc, SSC_TFMR,
0x1f | SSC_TFMR_DATDEF | SSC_TFMR_MSFBF | SSC_TFMR_FSOS_NEG_PULSE);
out:
if (err)
at91_ssc_deactivate(dev);
return (err);
}
static int
at91_ssc_detach(device_t dev)
{
return (EBUSY); /* XXX */
}
static int
at91_ssc_activate(device_t dev)
{
struct at91_ssc_softc *sc;
int rid;
sc = device_get_softc(dev);
rid = 0;
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (sc->mem_res == NULL)
goto errout;
rid = 0;
sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE);
if (sc->irq_res == NULL)
goto errout;
return (0);
errout:
at91_ssc_deactivate(dev);
return (ENOMEM);
}
static void
at91_ssc_deactivate(device_t dev)
{
struct at91_ssc_softc *sc;
sc = device_get_softc(dev);
if (sc->intrhand)
bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
sc->intrhand = NULL;
bus_generic_detach(sc->dev);
if (sc->mem_res)
bus_release_resource(dev, SYS_RES_IOPORT,
rman_get_rid(sc->mem_res), sc->mem_res);
sc->mem_res = NULL;
if (sc->irq_res)
bus_release_resource(dev, SYS_RES_IRQ,
rman_get_rid(sc->irq_res), sc->irq_res);
sc->irq_res = NULL;
return;
}
static void
at91_ssc_intr(void *xsc)
{
struct at91_ssc_softc *sc = xsc;
wakeup(sc);
return;
}
static int
at91_ssc_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
{
struct at91_ssc_softc *sc;
sc = CDEV2SOFTC(dev);
AT91_SSC_LOCK(sc);
if (!(sc->flags & OPENED)) {
sc->flags |= OPENED;
}
AT91_SSC_UNLOCK(sc);
return (0);
}
static int
at91_ssc_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
{
struct at91_ssc_softc *sc;
sc = CDEV2SOFTC(dev);
AT91_SSC_LOCK(sc);
sc->flags &= ~OPENED;
AT91_SSC_UNLOCK(sc);
return (0);
}
static int
at91_ssc_read(struct cdev *dev, struct uio *uio, int flag)
{
return EIO;
}
static int
at91_ssc_write(struct cdev *dev, struct uio *uio, int flag)
{
return EIO;
}
static device_method_t at91_ssc_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, at91_ssc_probe),
DEVMETHOD(device_attach, at91_ssc_attach),
DEVMETHOD(device_detach, at91_ssc_detach),
{ 0, 0 }
};
static driver_t at91_ssc_driver = {
"at91_ssc",
at91_ssc_methods,
sizeof(struct at91_ssc_softc),
};
DRIVER_MODULE(at91_ssc, atmelarm, at91_ssc_driver, at91_ssc_devclass, 0, 0);

View File

@ -1,152 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2006 M. Warner Losh.
*
* 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 ARM_AT91_AT91_SSCREG_H
#define ARM_AT91_AT91_SSCREG_H
/* Registers */
#define SSC_CR 0x00 /* Control Register */
#define SSC_CMR 0x04 /* Clock Mode Register */
/* 0x08 Reserved */
/* 0x0c Reserved */
#define SSC_RCMR 0x10 /* Receive Clock Mode Register */
#define SSC_RFMR 0x14 /* Receive Frame Mode Register */
#define SSC_TCMR 0x18 /* Transmit Clock Mode Register */
#define SSC_TFMR 0x1c /* Transmit Frame Mode register */
#define SSC_RHR 0x20 /* Receive Holding Register */
#define SSC_THR 0x24 /* Transmit Holding Register */
/* 0x28 Reserved */
/* 0x2c Reserved */
#define SSC_RSHR 0x30 /* Receive Sync Holding Register */
#define SSC_TSHR 0x34 /* Transmit Sync Holding Register */
/* 0x38 Reserved */
/* 0x3c Reserved */
#define SSC_SR 0x40 /* Status Register */
#define SSC_IER 0x44 /* Interrupt Enable Register */
#define SSC_IDR 0x48 /* Interrupt Disable Register */
#define SSC_IMR 0x4c /* Interrupt Mask Register */
/* And PDC registers */
/* SSC_CR */
#define SSC_CR_RXEN (1u << 0) /* RXEN: Receive Enable */
#define SSC_CR_RXDIS (1u << 1) /* RXDIS: Receive Disable */
#define SSC_CR_TXEN (1u << 8) /* TXEN: Transmit Enable */
#define SSC_CR_TXDIS (1u << 9) /* TXDIS: Transmit Disable */
#define SSC_CR_SWRST (1u << 15) /* SWRST: Software Reset */
/* SSC_CMR */
#define SSC_CMR_DIV 0xfffu /* DIV: Clock Divider mask */
/* SSC_RCMR */
#define SSC_RCMR_PERIOD (0xffu << 24) /* PERIOD: Receive Period Divider sel*/
#define SSC_RCMR_STTDLY (0xffu << 16) /* STTDLY: Receive Start Delay */
#define SSC_RCMR_START (0xfu << 8) /* START: Receive Start Sel */
#define SSC_RCMR_START_CONT (0u << 8)
#define SSC_RCMR_START_TX_START (1u << 8)
#define SSC_RCMR_START_LOW_RF (2u << 8)
#define SSC_RCMR_START_HIGH_RF (3u << 8)
#define SSC_RCMR_START_FALL_EDGE_RF (4u << 8)
#define SSC_RCMR_START_RISE_EDGE_RF (5u << 8)
#define SSC_RCMR_START_LEVEL_CHANGE_RF (6u << 8)
#define SSC_RCMR_START_ANY_EDGE_RF (7u << 8)
#define SSC_RCMR_CKI (1u << 5) /* CKI: Receive Clock Inversion */
#define SSC_RCMR_CKO (7u << 2) /* CKO: Receive Clock Output Mode Sel*/
#define SSC_RCMR_CKO_NONE (0u << 2)
#define SSC_RCMR_CKO_CONTINUOUS (1u << 2)
#define SSC_RCMR_CKS (3u) /* CKS: Receive Clock Selection */
#define SSC_RCMR_CKS_DIVIDED (0)
#define SSC_RCMR_CKS_TK_CLOCK (1)
#define SSC_RCMR_CKS_RK (2)
/* SSC_RFMR */
#define SSC_RFMR_FSEDGE (1u << 24) /* FSEDGE: Frame Sync Edge Detection */
#define SSC_RFMR_FSOS (7u << 20) /* FSOS: Receive frame Sync Out sel */
#define SSC_RFMR_FSOS_NONE (0u << 20)
#define SSC_RFMR_FSOS_NEG_PULSE (1u << 20)
#define SSC_RFMR_FSOS_POS_PULSE (2u << 20)
#define SSC_RFMR_FSOS_LOW (3u << 20)
#define SSC_RFMR_FSOS_HIGH (4u << 20)
#define SSC_RFMR_FSOS_TOGGLE (5u << 20)
#define SSC_RFMR_FSLEN (0xfu << 16) /* FSLEN: Receive Frame Sync Length */
#define SSC_RFMR_DATNB (0xfu << 8) /* DATNB: Data Number per Frame */
#define SSC_RFMR_MSFBF (1u << 7) /* MSBF: Most Significant Bit First */
#define SSC_RFMR_LOOP (1u << 5) /* LOOP: Loop Mode */
#define SSC_RFMR_DATLEN (0x1fu << 0) /* DATLEN: Data Length */
/* SSC_TCMR */
#define SSC_TCMR_PERIOD (0xffu << 24) /* PERIOD: Receive Period Divider sel*/
#define SSC_TCMR_STTDLY (0xffu << 16) /* STTDLY: Receive Start Delay */
#define SSC_TCMR_START (0xfu << 8) /* START: Receive Start Sel */
#define SSC_TCMR_START_CONT (0u << 8)
#define SSC_TCMR_START_RX_START (1u << 8)
#define SSC_TCMR_START_LOW_RF (2u << 8)
#define SSC_TCMR_START_HIGH_RF (3u << 8)
#define SSC_TCMR_START_FALL_EDGE_RF (4u << 8)
#define SSC_TCMR_START_RISE_EDGE_RF (5u << 8)
#define SSC_TCMR_START_LEVEL_CHANGE_RF (6u << 8)
#define SSC_TCMR_START_ANY_EDGE_RF (7u << 8)
#define SSC_TCMR_CKI (1u << 5) /* CKI: Receive Clock Inversion */
#define SSC_TCMR_CKO (7u << 2) /* CKO: Receive Clock Output Mode Sel*/
#define SSC_TCMR_CKO_NONE (0u << 2)
#define SSC_TCMR_CKO_CONTINUOUS (1u << 2)
#define SSC_TCMR_CKS (3u) /* CKS: Receive Clock Selection */
#define SSC_TCMR_CKS_DIVIDED (0)
#define SSC_TCMR_CKS_RK_CLOCK (1)
#define SSC_TCMR_CKS_TK (2)
/* SSC_TFMR */
#define SSC_TFMR_FSEDGE (1u << 24) /* FSEDGE: Frame Sync Edge Detection */
#define SSC_TFMR_FSOS (7u << 20) /* FSOS: Receive frame Sync Out sel */
#define SSC_TFMR_FSOS_NONE (0u << 20)
#define SSC_TFMR_FSOS_NEG_PULSE (1u << 20)
#define SSC_TFMR_FSOS_POS_PULSE (2u << 20)
#define SSC_TFMR_FSOS_LOW (3u << 20)
#define SSC_TFMR_FSOS_HIGH (4u << 20)
#define SSC_TFMR_FSOS_TOGGLE (5u << 20)
#define SSC_TFMR_FSLEN (0xfu << 16) /* FSLEN: Receive Frame Sync Length */
#define SSC_TFMR_DATNB (0xfu << 8) /* DATNB: Data Number per Frame */
#define SSC_TFMR_MSFBF (1u << 7) /* MSBF: Most Significant Bit First */
#define SSC_TFMR_DATDEF (1u << 5) /* DATDEF: Data Default Value */
#define SSC_TFMR_DATLEN (0x1fu << 0) /* DATLEN: Data Length */
/* SSC_SR */
#define SSC_SR_TXRDY (1u << 0)
#define SSC_SR_TXEMPTY (1u << 1)
#define SSC_SR_ENDTX (1u << 2)
#define SSC_SR_TXBUFE (1u << 3)
#define SSC_SR_RXRDY (1u << 4)
#define SSC_SR_OVRUN (1u << 5)
#define SSC_SR_ENDRX (1u << 6)
#define SSC_SR_RXBUFF (1u << 7)
#define SSC_SR_TXSYN (1u << 10)
#define SSC_SR_RSSYN (1u << 11)
#define SSC_SR_TXEN (1u << 16)
#define SSC_SR_RXEN (1u << 17)
#endif /* ARM_AT91_AT91_SSCREG_H */

View File

@ -1,314 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2005 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 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/time.h>
#include <sys/bus.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/timetc.h>
#include <sys/watchdog.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/resource.h>
#include <machine/frame.h>
#include <machine/intr.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91_streg.h>
#include <arm/at91/at91rm92reg.h>
static struct at91_st_softc {
struct resource * sc_irq_res;
struct resource * sc_mem_res;
void * sc_intrhand;
eventhandler_tag sc_wet; /* watchdog event handler tag */
} *timer_softc;
static inline uint32_t
RD4(bus_size_t off)
{
if (timer_softc == NULL) {
uint32_t *p = (uint32_t *)(AT91_BASE + AT91RM92_ST_BASE + off);
return *p;
}
return (bus_read_4(timer_softc->sc_mem_res, off));
}
static inline void
WR4(bus_size_t off, uint32_t val)
{
if (timer_softc == NULL) {
uint32_t *p = (uint32_t *)(AT91_BASE + AT91RM92_ST_BASE + off);
*p = val;
}
else
bus_write_4(timer_softc->sc_mem_res, off, val);
}
static void at91_st_watchdog(void *, u_int, int *);
static void at91_st_initclocks(device_t , struct at91_st_softc *);
static inline int
st_crtr(void)
{
int cur1, cur2;
do {
cur1 = RD4(ST_CRTR);
cur2 = RD4(ST_CRTR);
} while (cur1 != cur2);
return (cur1);
}
static unsigned at91_st_get_timecount(struct timecounter *tc);
static struct timecounter at91_st_timecounter = {
at91_st_get_timecount, /* get_timecount */
NULL, /* no poll_pps */
0xfffffu, /* counter_mask */
32768, /* frequency */
"AT91RM9200 timer", /* name */
1000 /* quality */
};
static int
clock_intr(void *arg)
{
struct trapframe *fp = arg;
/* The interrupt is shared, so we have to make sure it's for us. */
if (RD4(ST_SR) & ST_SR_PITS) {
hardclock(TRAPF_USERMODE(fp), TRAPF_PC(fp));
return (FILTER_HANDLED);
}
return (FILTER_STRAY);
}
void
at91_st_delay(int n)
{
uint32_t start, end, cur;
start = st_crtr();
n = (n * 1000) / 32768;
if (n <= 0)
n = 1;
end = (start + n) & ST_CRTR_MASK;
cur = start;
if (start > end) {
while (cur >= start || cur < end)
cur = st_crtr();
} else {
while (cur < end)
cur = st_crtr();
}
}
void
at91_st_cpu_reset(void)
{
/*
* Reset the CPU by programmig the watchdog timer to reset the
* CPU after 128 'slow' clocks, or about ~4ms. Loop until
* the reset happens for safety.
*/
WR4(ST_WDMR, ST_WDMR_RSTEN | 2);
WR4(ST_CR, ST_CR_WDRST);
while (1)
continue;
}
static int
at91_st_probe(device_t dev)
{
device_set_desc(dev, "ST");
return (0);
}
static void
at91_st_deactivate(device_t dev)
{
struct at91_st_softc *sc = timer_softc;
if (sc->sc_intrhand)
bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand);
sc->sc_intrhand = NULL;
if (sc->sc_irq_res)
bus_release_resource(dev, SYS_RES_IRQ,
rman_get_rid(sc->sc_irq_res), sc->sc_irq_res);
sc->sc_irq_res = NULL;
if (sc->sc_mem_res)
bus_release_resource(dev, SYS_RES_MEMORY,
rman_get_rid(sc->sc_mem_res), sc->sc_mem_res);
sc->sc_mem_res = NULL;
}
static int
at91_st_activate(device_t dev)
{
int rid;
int err;
struct at91_st_softc *sc = timer_softc;
rid = 0;
sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
err = ENOMEM;
if (sc->sc_mem_res == NULL)
goto out;
/* Disable all interrupts */
WR4(ST_IDR, 0xffffffff);
/* The system timer shares the system irq (1) */
rid = 0;
sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE | RF_SHAREABLE);
if (sc->sc_irq_res == NULL) {
printf("Unable to allocate irq for the system timer");
goto out;
}
err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_CLK, clock_intr,
NULL, NULL, &sc->sc_intrhand);
out:
if (err != 0)
at91_st_deactivate(dev);
return (err);
}
static int
at91_st_attach(device_t dev)
{
int err;
timer_softc = device_get_softc(dev);
err = at91_st_activate(dev);
if (err)
return err;
timer_softc->sc_wet = EVENTHANDLER_REGISTER(watchdog_list,
at91_st_watchdog, dev, 0);
device_printf(dev,
"watchdog registered, timeout intervall max. 64 sec\n");
at91_st_initclocks(dev, timer_softc);
return (0);
}
static device_method_t at91_st_methods[] = {
DEVMETHOD(device_probe, at91_st_probe),
DEVMETHOD(device_attach, at91_st_attach),
{0, 0},
};
static driver_t at91_st_driver = {
"at91_st",
at91_st_methods,
sizeof(struct at91_st_softc),
};
static devclass_t at91_st_devclass;
DRIVER_MODULE(at91_st, atmelarm, at91_st_driver, at91_st_devclass, 0, 0);
static unsigned
at91_st_get_timecount(struct timecounter *tc)
{
return (st_crtr());
}
/*
* t below is in a weird unit. The watchdog is set to 2^t
* nanoseconds. Since our watchdog timer can't really do that too
* well, we approximate it by assuming that the timeout interval for
* the lsb is 2^22 ns, which is 4.194ms. This is an overestimation of
* the actual time (3.906ms), but close enough for watchdogging.
* These approximations, though a violation of the spec, improve the
* performance of the application which typically specifies things as
* WD_TO_32SEC. In that last case, we'd wait 32s before the wdog
* reset. The spec says we should wait closer to 34s, but given how
* it is likely to be used, and the extremely coarse nature time
* interval, I think this is the best solution.
*/
static void
at91_st_watchdog(void *argp, u_int cmd, int *error)
{
uint32_t wdog;
int t;
t = cmd & WD_INTERVAL;
if (t >= 22 && t <= 37) {
wdog = (1 << (t - 22)) | ST_WDMR_RSTEN;
*error = 0;
} else {
wdog = 0;
}
WR4(ST_WDMR, wdog);
WR4(ST_CR, ST_CR_WDRST);
}
static void
at91_st_initclocks(device_t dev, struct at91_st_softc *sc)
{
int rel_value;
/*
* Real time counter increments every clock cycle, need to set before
* initializing clocks so that DELAY works.
*/
WR4(ST_RTMR, 1);
/* disable watchdog timer */
WR4(ST_WDMR, 0);
rel_value = 32768 / hz;
if (rel_value < 1)
rel_value = 1;
if (32768 % hz) {
device_printf(dev, "Cannot get %d Hz clock; using %dHz\n", hz,
32768 / rel_value);
hz = 32768 / rel_value;
tick = 1000000 / hz;
}
WR4(ST_PIMR, rel_value);
/* Enable PITS interrupts. */
WR4(ST_IER, ST_SR_PITS);
tc_init(&at91_st_timecounter);
}

View File

@ -1,63 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2005 M. Warner Losh.
*
* 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 ARM_AT91_AT91STREG_H
#define ARM_AT91_AT91STREG_H
#define ST_CR 0x00 /* Control register */
#define ST_PIMR 0x04 /* Period interval mode register */
#define ST_WDMR 0x08 /* Watchdog mode register */
#define ST_RTMR 0x0c /* Real-time mode register */
#define ST_SR 0x10 /* Status register */
#define ST_IER 0x14 /* Interrupt enable register */
#define ST_IDR 0x18 /* Interrupt disable register */
#define ST_IMR 0x1c /* Interrupt mask register */
#define ST_RTAR 0x20 /* Real-time alarm register */
#define ST_CRTR 0x24 /* Current real-time register */
/* ST_CR */
#define ST_CR_WDRST (1U << 0) /* WDRST: Watchdog Timer Restart */
/* ST_WDMR */
#define ST_WDMR_EXTEN (1U << 17) /* EXTEN: External Signal Assert Enable */
#define ST_WDMR_RSTEN (1U << 16) /* RSTEN: Reset Enable */
/* ST_SR, ST_IER, ST_IDR, ST_IMR */
#define ST_SR_PITS (1U << 0) /* PITS: Period Interval Timer Status */
#define ST_SR_WDOVF (1U << 1) /* WDOVF: Watchdog Overflow */
#define ST_SR_RTTINC (1U << 2) /* RTTINC: Real-time Timer Increment */
#define ST_SR_ALMS (1U << 3) /* ALMS: Alarm Status */
/* ST_CRTR */
#define ST_CRTR_MASK 0xfffff /* 20-bit counter */
void at91_st_delay(int n);
void at91_st_cpu_reset(void);
#endif /* ARM_AT91_AT91STREG_H */

View File

@ -1,106 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2014 M. Warner Losh.
*
* 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 "opt_platform.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/resource.h>
#include <sys/systm.h>
#include <sys/rman.h>
#include <machine/bus.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91_aicreg.h>
#ifdef FDT
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#endif
struct tcb_softc {
struct resource *mem_res; /* Memory resource */
device_t sc_dev;
};
static int
at91_tcb_probe(device_t dev)
{
#ifdef FDT
if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-tcb"))
return (ENXIO);
#endif
device_set_desc(dev, "TCB");
return (0);
}
static int
at91_tcb_attach(device_t dev)
{
int rid, err = 0;
struct tcb_softc *sc;
sc = device_get_softc(dev);
sc->sc_dev = dev;
rid = 0;
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (sc->mem_res == NULL)
panic("couldn't allocate register resources");
return (err);
}
static device_method_t at91_tcb_methods[] = {
DEVMETHOD(device_probe, at91_tcb_probe),
DEVMETHOD(device_attach, at91_tcb_attach),
DEVMETHOD_END
};
static driver_t at91_tcb_driver = {
"at91_tcb",
at91_tcb_methods,
sizeof(struct tcb_softc),
};
static devclass_t at91_tcb_devclass;
#ifdef FDT
DRIVER_MODULE(at91_tcb, simplebus, at91_tcb_driver, at91_tcb_devclass, NULL,
NULL);
#else
DRIVER_MODULE(at91_tcb, atmelarm, at91_tcb_driver, at91_tcb_devclass, NULL,
NULL);
#endif

View File

@ -1,430 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2006 M. Warner Losh.
*
* 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 "opt_platform.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mbuf.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/rman.h>
#include <machine/bus.h>
#include <arm/at91/at91_twireg.h>
#include <arm/at91/at91var.h>
#include <dev/iicbus/iiconf.h>
#include <dev/iicbus/iicbus.h>
#include "iicbus_if.h"
#ifdef FDT
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#endif
#define TWI_SLOW_CLOCK 1500
#define TWI_FAST_CLOCK 45000
#define TWI_FASTEST_CLOCK 90000
struct at91_twi_softc
{
device_t dev; /* Myself */
void *intrhand; /* Interrupt handle */
struct resource *irq_res; /* IRQ resource */
struct resource *mem_res; /* Memory resource */
struct mtx sc_mtx; /* basically a perimeter lock */
volatile uint32_t flags;
uint32_t cwgr;
int sc_started;
int twi_addr;
device_t iicbus;
};
static inline uint32_t
RD4(struct at91_twi_softc *sc, bus_size_t off)
{
return bus_read_4(sc->mem_res, off);
}
static inline void
WR4(struct at91_twi_softc *sc, bus_size_t off, uint32_t val)
{
bus_write_4(sc->mem_res, off, val);
}
#define AT91_TWI_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
#define AT91_TWI_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
#define AT91_TWI_LOCK_INIT(_sc) \
mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \
"twi", MTX_DEF)
#define AT91_TWI_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx);
#define AT91_TWI_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED);
#define AT91_TWI_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
#define TWI_DEF_CLK 100000
static devclass_t at91_twi_devclass;
/* bus entry points */
static int at91_twi_probe(device_t dev);
static int at91_twi_attach(device_t dev);
static int at91_twi_detach(device_t dev);
static void at91_twi_intr(void *);
/* helper routines */
static int at91_twi_activate(device_t dev);
static void at91_twi_deactivate(device_t dev);
static int
at91_twi_probe(device_t dev)
{
#ifdef FDT
/* XXXX need a whole list, since there's at least 4 different ones */
if (!ofw_bus_is_compatible(dev, "atmel,at91sam9g20-i2c"))
return (ENXIO);
#endif
device_set_desc(dev, "TWI");
return (0);
}
static int
at91_twi_attach(device_t dev)
{
struct at91_twi_softc *sc = device_get_softc(dev);
int err;
sc->dev = dev;
err = at91_twi_activate(dev);
if (err)
goto out;
AT91_TWI_LOCK_INIT(sc);
#ifdef FDT
/*
* Disable devices need to hold their resources, so return now and not attach
* the iicbus, setup interrupt handlers, etc.
*/
if (!ofw_bus_status_okay(dev))
return 0;
#endif
/*
* Activate the interrupt
*/
err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
NULL, at91_twi_intr, sc, &sc->intrhand);
if (err) {
AT91_TWI_LOCK_DESTROY(sc);
goto out;
}
sc->cwgr = TWI_CWGR_CKDIV(8 * at91_master_clock / TWI_FASTEST_CLOCK) |
TWI_CWGR_CHDIV(TWI_CWGR_DIV(TWI_DEF_CLK)) |
TWI_CWGR_CLDIV(TWI_CWGR_DIV(TWI_DEF_CLK));
WR4(sc, TWI_CR, TWI_CR_SWRST);
WR4(sc, TWI_CR, TWI_CR_MSEN | TWI_CR_SVDIS);
WR4(sc, TWI_CWGR, sc->cwgr);
if ((sc->iicbus = device_add_child(dev, "iicbus", -1)) == NULL)
device_printf(dev, "could not allocate iicbus instance\n");
/* Probe and attach the iicbus when interrupts are available. */
config_intrhook_oneshot((ich_func_t)bus_generic_attach, dev);
out:
if (err)
at91_twi_deactivate(dev);
return (err);
}
static int
at91_twi_detach(device_t dev)
{
struct at91_twi_softc *sc;
int rv;
sc = device_get_softc(dev);
at91_twi_deactivate(dev);
if (sc->iicbus && (rv = device_delete_child(dev, sc->iicbus)) != 0)
return (rv);
AT91_TWI_LOCK_DESTROY(sc);
return (0);
}
static int
at91_twi_activate(device_t dev)
{
struct at91_twi_softc *sc;
int rid;
sc = device_get_softc(dev);
rid = 0;
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (sc->mem_res == NULL)
goto errout;
rid = 0;
sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE);
if (sc->irq_res == NULL)
goto errout;
return (0);
errout:
at91_twi_deactivate(dev);
return (ENOMEM);
}
static void
at91_twi_deactivate(device_t dev)
{
struct at91_twi_softc *sc;
sc = device_get_softc(dev);
if (sc->intrhand)
bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
sc->intrhand = NULL;
bus_generic_detach(sc->dev);
if (sc->mem_res)
bus_release_resource(dev, SYS_RES_MEMORY,
rman_get_rid(sc->mem_res), sc->mem_res);
sc->mem_res = NULL;
if (sc->irq_res)
bus_release_resource(dev, SYS_RES_IRQ,
rman_get_rid(sc->irq_res), sc->irq_res);
sc->irq_res = NULL;
return;
}
static void
at91_twi_intr(void *xsc)
{
struct at91_twi_softc *sc = xsc;
uint32_t status;
status = RD4(sc, TWI_SR);
if (status == 0)
return;
AT91_TWI_LOCK(sc);
sc->flags |= status & (TWI_SR_OVRE | TWI_SR_UNRE | TWI_SR_NACK);
if (status & TWI_SR_RXRDY)
sc->flags |= TWI_SR_RXRDY;
if (status & TWI_SR_TXRDY)
sc->flags |= TWI_SR_TXRDY;
if (status & TWI_SR_TXCOMP)
sc->flags |= TWI_SR_TXCOMP;
WR4(sc, TWI_IDR, status);
wakeup(sc);
AT91_TWI_UNLOCK(sc);
return;
}
static int
at91_twi_wait(struct at91_twi_softc *sc, uint32_t bit)
{
int err = 0;
int counter = 100000;
uint32_t sr;
AT91_TWI_ASSERT_LOCKED(sc);
while (!((sr = RD4(sc, TWI_SR)) & bit) && counter-- > 0 &&
!(sr & TWI_SR_NACK))
continue;
if (counter <= 0)
err = EBUSY;
else if (sr & TWI_SR_NACK)
err = ENXIO; // iic nack convention
return (err);
}
static int
at91_twi_rst_card(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
{
struct at91_twi_softc *sc;
int clk;
sc = device_get_softc(dev);
AT91_TWI_LOCK(sc);
if (oldaddr)
*oldaddr = sc->twi_addr;
sc->twi_addr = addr;
/*
* speeds are for 1.5kb/s, 45kb/s and 90kb/s.
*/
switch (speed) {
case IIC_SLOW:
clk = TWI_SLOW_CLOCK;
break;
case IIC_FAST:
clk = TWI_FAST_CLOCK;
break;
case IIC_UNKNOWN:
case IIC_FASTEST:
default:
clk = TWI_FASTEST_CLOCK;
break;
}
sc->cwgr = TWI_CWGR_CKDIV(1) | TWI_CWGR_CHDIV(TWI_CWGR_DIV(clk)) |
TWI_CWGR_CLDIV(TWI_CWGR_DIV(clk));
WR4(sc, TWI_CR, TWI_CR_SWRST);
WR4(sc, TWI_CR, TWI_CR_MSEN | TWI_CR_SVDIS);
WR4(sc, TWI_CWGR, sc->cwgr);
AT91_TWI_UNLOCK(sc);
return 0;
}
static int
at91_twi_callback(device_t dev, int index, caddr_t data)
{
int error = 0;
switch (index) {
case IIC_REQUEST_BUS:
break;
case IIC_RELEASE_BUS:
break;
default:
error = EINVAL;
}
return (error);
}
static int
at91_twi_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
{
struct at91_twi_softc *sc;
int i, len, err;
uint32_t rdwr;
uint8_t *buf;
uint32_t sr;
sc = device_get_softc(dev);
err = 0;
AT91_TWI_LOCK(sc);
for (i = 0; i < nmsgs; i++) {
/*
* The linux atmel driver doesn't use the internal device
* address feature of twi. A separate i2c message needs to
* be written to use this.
* See http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2004-September/024411.html
* for details. Upon reflection, we could use this as an
* optimization, but it is unclear the code bloat will
* result in faster/better operations.
*/
rdwr = (msgs[i].flags & IIC_M_RD) ? TWI_MMR_MREAD : 0;
WR4(sc, TWI_MMR, TWI_MMR_DADR(msgs[i].slave) | rdwr);
len = msgs[i].len;
buf = msgs[i].buf;
/* zero byte transfers aren't allowed */
if (len == 0 || buf == NULL) {
err = EINVAL;
goto out;
}
if (len == 1 && msgs[i].flags & IIC_M_RD)
WR4(sc, TWI_CR, TWI_CR_START | TWI_CR_STOP);
else
WR4(sc, TWI_CR, TWI_CR_START);
if (msgs[i].flags & IIC_M_RD) {
sr = RD4(sc, TWI_SR);
while (!(sr & TWI_SR_TXCOMP)) {
if ((sr = RD4(sc, TWI_SR)) & TWI_SR_RXRDY) {
len--;
*buf++ = RD4(sc, TWI_RHR) & 0xff;
if (len == 1)
WR4(sc, TWI_CR, TWI_CR_STOP);
}
}
if (len > 0 || (sr & TWI_SR_NACK)) {
err = ENXIO; // iic nack convention
goto out;
}
} else {
while (len--) {
if ((err = at91_twi_wait(sc, TWI_SR_TXRDY)))
goto out;
WR4(sc, TWI_THR, *buf++);
}
WR4(sc, TWI_CR, TWI_CR_STOP);
}
if ((err = at91_twi_wait(sc, TWI_SR_TXCOMP)))
break;
}
out:
if (err) {
WR4(sc, TWI_CR, TWI_CR_SWRST);
WR4(sc, TWI_CR, TWI_CR_MSEN | TWI_CR_SVDIS);
WR4(sc, TWI_CWGR, sc->cwgr);
}
AT91_TWI_UNLOCK(sc);
return (err);
}
static device_method_t at91_twi_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, at91_twi_probe),
DEVMETHOD(device_attach, at91_twi_attach),
DEVMETHOD(device_detach, at91_twi_detach),
/* iicbus interface */
DEVMETHOD(iicbus_callback, at91_twi_callback),
DEVMETHOD(iicbus_reset, at91_twi_rst_card),
DEVMETHOD(iicbus_transfer, at91_twi_transfer),
DEVMETHOD_END
};
static driver_t at91_twi_driver = {
"at91_twi",
at91_twi_methods,
sizeof(struct at91_twi_softc),
};
#ifdef FDT
DRIVER_MODULE(at91_twi, simplebus, at91_twi_driver, at91_twi_devclass, NULL,
NULL);
#else
DRIVER_MODULE(at91_twi, atmelarm, at91_twi_driver, at91_twi_devclass, NULL,
NULL);
#endif
DRIVER_MODULE(iicbus, at91_twi, iicbus_driver, iicbus_devclass, NULL, NULL);
MODULE_DEPEND(at91_twi, iicbus, 1, 1, 1);

View File

@ -1,64 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2006 M. Warner Losh.
*
* 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 _ARM_AT91_AT91_TWIIO_H
#define _ARM_AT91_AT91_TWIIO_H
#include <sys/ioccom.h>
struct at91_twi_io
{
int dadr; /* Device address */
int type; /* read/write */
#define TWI_IO_READ_MASTER 1
#define TWI_IO_WRITE_MASTER 2
int iadrsz; /* Internal addr size */
uint32_t iadr; /* Interbak addr */
size_t xfer_len; /* Size to transfer */
caddr_t xfer_buf; /* buffer for xfer */
};
struct at91_twi_clock
{
int ckdiv; /* Clock divider */
int high_rate; /* rate of clock high period */
int low_rate; /* rate of clock low period */
};
/** TWIIOCXFER: Do a two-wire transfer
*/
#define TWIIOCXFER _IOW('x', 1, struct at91_twi_io)
/** TWIIOCSETCLOCK: Sets the clocking parameters for this operation.
*/
#define TWIIOCSETCLOCK _IOW('x', 2, struct at91_twi_clock)
#endif /* !_ARM_AT91_AT91_TWIIO_H */

View File

@ -1,88 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2006 M. Warner Losh.
*
* 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 ARM_AT91_AT91_TWIREG_H
#define ARM_AT91_AT91_TWIREG_H
#define TWI_CR 0x00 /* TWI Control Register */
#define TWI_MMR 0x04 /* TWI Master Mode Register */
#define TWI_SMR 0x08 /* TWI Master Mode Register */
#define TWI_IADR 0x0c /* TWI Internal Address Register */
#define TWI_CWGR 0x10 /* TWI Clock Waveform Generator Reg */
/* 0x14 reserved */
/* 0x18 reserved */
/* 0x1c reserved */
#define TWI_SR 0x20 /* TWI Status Register */
#define TWI_IER 0x24 /* TWI Interrupt Enable Register */
#define TWI_IDR 0x28 /* TWI Interrupt Disable Register */
#define TWI_IMR 0x2c /* TWI Interrupt Mask Register */
#define TWI_RHR 0x30 /* TWI Receiver Holding Register */
#define TWI_THR 0x34 /* TWI Transmit Holding Register */
/* TWI_CR */
#define TWI_CR_START (1U << 0) /* Send a start */
#define TWI_CR_STOP (1U << 1) /* Send a stop */
#define TWI_CR_MSEN (1U << 2) /* Master Transfer Enable */
#define TWI_CR_MSDIS (1U << 3) /* Master Transfer Disable */
#define TWI_CR_SVEN (1U << 4) /* Slave Transfer Enable */
#define TWI_CR_SVDIS (1U << 5) /* Slave Transfer Disable */
#define TWI_CR_SWRST (1U << 7) /* Software Reset */
/* TWI_MMR */
/* TWI_SMR */
#define TWI_MMR_IADRSZ(n) ((n) << 8) /* Set size of transfer */
#define TWI_MMR_MWRITE 0U /* Master Read Direction */
#define TWI_MMR_MREAD (1U << 12) /* Master Read Direction */
#define TWI_MMR_DADR(n) ((n) << 15) /* Device Address */
/* TWI_CWGR */
#define TWI_CWGR_CKDIV(x) ((x) << 16) /* Clock Divider */
#define TWI_CWGR_CHDIV(x) ((x) << 8) /* Clock High Divider */
#define TWI_CWGR_CLDIV(x) ((x) << 0) /* Clock Low Divider */
#define TWI_CWGR_DIV(rate) \
(at91_is_sam9() || at91_is_sam9xe() ? \
((at91_master_clock / (4 * (rate))) - 3) : \
((at91_master_clock / (4 * (rate))) - 2))
/* TWI_SR */
/* TWI_IER */
/* TWI_IDR */
/* TWI_IMR */
#define TWI_SR_TXCOMP (1U << 0) /* Transmission Completed */
#define TWI_SR_RXRDY (1U << 1) /* Receive Holding Register Ready */
#define TWI_SR_TXRDY (1U << 2) /* Transmit Holding Register Ready */
#define TWI_SR_SVREAD (1U << 3) /* Slave Read */
#define TWI_SR_SVACC (1U << 4) /* Slave Access */
#define TWI_SR_GCACC (1U << 5) /* General Call Access */
#define TWI_SR_OVRE (1U << 6) /* Overrun error */
#define TWI_SR_UNRE (1U << 7) /* Underrun Error */
#define TWI_SR_NACK (1U << 8) /* Not Acknowledged */
#define TWI_SR_ARBLST (1U << 9) /* Arbitration Lost */
#endif /* ARM_AT91_AT91_TWIREG_H */

View File

@ -1,131 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2005 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 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 AT91USARTREG_H_
#define AT91USARTREG_H_
#define USART_CR 0x00 /* Control register */
#define USART_CR_RSTRX (1UL << 2) /* Reset Receiver */
#define USART_CR_RSTTX (1UL << 3) /* Reset Transmitter */
#define USART_CR_RXEN (1UL << 4) /* Receiver Enable */
#define USART_CR_RXDIS (1UL << 5) /* Receiver Disable */
#define USART_CR_TXEN (1UL << 6) /* Transmitter Enable */
#define USART_CR_TXDIS (1UL << 7) /* Transmitter Disable */
#define USART_CR_RSTSTA (1UL << 8) /* Reset Status Bits */
#define USART_CR_STTBRK (1UL << 9) /* Start Break */
#define USART_CR_STPBRK (1UL << 10) /* Stop Break */
#define USART_CR_STTTO (1UL << 11) /* Start Time-out */
#define USART_CR_SENDA (1UL << 12) /* Send Address */
#define USART_CR_RSTIT (1UL << 13) /* Reset Iterations */
#define USART_CR_RSTNACK (1UL << 14) /* Reset Non Acknowledge */
#define USART_CR_RETTO (1UL << 15) /* Rearm Time-out */
#define USART_CR_DTREN (1UL << 16) /* Data Terminal ready Enable */
#define USART_CR_DTRDIS (1UL << 17) /* Data Terminal ready Disable */
#define USART_CR_RTSEN (1UL << 18) /* Request to Send enable */
#define USART_CR_RTSDIS (1UL << 19) /* Request to Send Disable */
#define USART_MR 0x04 /* Mode register */
#define USART_MR_MODE_NORMAL 0 /* Normal/Async/3-wire rs-232 */
#define USART_MR_MODE_RS485 1 /* RS485 */
#define USART_MR_MODE_HWFLOW 2 /* Hardware flow control/handshake */
#define USART_MR_MODE_MODEM 3 /* Full modem protocol */
#define USART_MR_MODE_ISO7816T0 4 /* ISO7816 T=0 */
#define USART_MR_MODE_ISO7816T1 6 /* ISO7816 T=1 */
#define USART_MR_MODE_IRDA 8 /* IrDA mode */
#define USART_MR_USCLKS_MCK (0U << 4) /* use MCK for baudclock */
#define USART_MR_USCLKS_MCKDIV (1U << 4) /* use MCK/DIV for baudclock */
#define USART_MR_USCLKS_SCK (3U << 4) /* use SCK (ext) for baudclock */
#define USART_MR_CHRL_5BITS (0U << 6)
#define USART_MR_CHRL_6BITS (1U << 6)
#define USART_MR_CHRL_7BITS (2U << 6)
#define USART_MR_CHRL_8BITS (3U << 6)
#define USART_MR_SYNC (1U << 8) /* 1 -> sync 0 -> async */
#define USART_MR_PAR_EVEN (0U << 9)
#define USART_MR_PAR_ODD (1U << 9)
#define USART_MR_PAR_SPACE (2U << 9)
#define USART_MR_PAR_MARK (3U << 9)
#define USART_MR_PAR_NONE (4U << 9)
#define USART_MR_PAR_MULTIDROP (6U << 9)
#define USART_MR_NBSTOP_1 (0U << 12)
#define USART_MR_NBSTOP_1_5 (1U << 12)
#define USART_MR_NBSTOP_2 (2U << 12)
#define USART_MR_CHMODE_NORMAL (0U << 14)
#define USART_MR_CHMODE_ECHO (1U << 14)
#define USART_MR_CHMODE_LOOP (2U << 14)
#define USART_MR_CHMODE_REMLOOP (3U << 14)
#define USART_MR_MSBF (1U << 16)
#define USART_MR_MODE9 (1U << 17)
#define USART_MR_CKLO_SCK (1U << 18)
#define USART_MR_OVER16 0
#define USART_MR_OVER8 (1U << 19)
#define USART_MR_INACK (1U << 20) /* Inhibit NACK generation */
#define USART_MR_DSNACK (1U << 21) /* Disable Successive NACK */
#define USART_MR_MAXITERATION(x) ((x) << 24)
#define USART_MR_FILTER (1U << 28) /* Filters for Ir lines */
#define USART_IER 0x08 /* Interrupt enable register */
#define USART_IDR 0x0c /* Interrupt disable register */
#define USART_IMR 0x10 /* Interrupt mask register */
#define USART_CSR 0x14 /* Channel status register */
#define USART_CSR_RXRDY (1UL << 0) /* Receiver ready */
#define USART_CSR_TXRDY (1UL << 1) /* Transmitter ready */
#define USART_CSR_RXBRK (1UL << 2) /* Break received */
#define USART_CSR_ENDRX (1UL << 3) /* End of Transfer RX from PDC */
#define USART_CSR_ENDTX (1UL << 4) /* End of Transfer TX from PDC */
#define USART_CSR_OVRE (1UL << 5) /* Overrun error */
#define USART_CSR_FRAME (1UL << 6) /* Framing error */
#define USART_CSR_PARE (1UL << 7) /* Parity Error */
#define USART_CSR_TIMEOUT (1UL << 8) /* Timeout since start-timeout */
#define USART_CSR_TXEMPTY (1UL << 9) /* Transmitter empty */
#define USART_CSR_ITERATION (1UL << 10) /* max repetitions since RSIT */
#define USART_CSR_TXBUFE (1UL << 11) /* Buffer empty from PDC */
#define USART_CSR_RXBUFF (1UL << 12) /* Buffer full from PDC */
#define USART_CSR_NACK (1UL << 13) /* NACK since last RSTNACK */
#define USART_CSR_RIIC (1UL << 16) /* RI delta since last csr read */
#define USART_CSR_DSRIC (1UL << 17) /* DSR delta */
#define USART_CSR_DCDIC (1UL << 18) /* DCD delta */
#define USART_CSR_CTSIC (1UL << 19) /* CTS delta */
#define USART_CSR_RI (1UL << 20) /* RI status */
#define USART_CSR_DSR (1UL << 21) /* DSR status */
#define USART_CSR_DCD (1UL << 22) /* DCD status */
#define USART_CSR_CTS (1UL << 23) /* CTS status */
#define USART_RHR 0x18 /* Receiver holding register */
#define USART_THR 0x1c /* Transmitter holding register */
#define USART_BRGR 0x20 /* Baud rate generator register */
#define USART_RTOR 0x24 /* Receiver time-out register */
#define USART_TTR 0x28 /* Transmitter timeguard register */
/* 0x2c to 0x3c reserved */
#define USART_FDRR 0x40 /* FI DI ratio register */
#define USART_NER 0x44 /* Number of errors register */
/* 0x48 reserved */
#define USART_IFR 0x48 /* IrDA filter register */
#endif /* AT91RM92REG_H_ */

View File

@ -1,239 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2010 Greg Ansley. 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.
*/
/*
* The SAM9 watchdog hardware can be programed only once. So we set the
* hardware watchdog to 16 s in wdt_attach and only reset it in the wdt_tick
* handler. The watchdog is halted in processor debug mode.
*/
#include "opt_platform.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/kdb.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/systm.h>
#include <sys/watchdog.h>
#include <machine/bus.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91_wdtreg.h>
#ifdef FDT
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#endif
struct wdt_softc {
struct mtx sc_mtx;
device_t sc_dev;
struct resource *mem_res;
struct callout tick_ch;
eventhandler_tag sc_wet;
void *intrhand;
u_int cmd;
u_int interval;
};
static inline uint32_t
RD4(struct wdt_softc *sc, bus_size_t off)
{
return (bus_read_4(sc->mem_res, off));
}
static inline void
WR4(struct wdt_softc *sc, bus_size_t off, uint32_t val)
{
bus_write_4(sc->mem_res, off, val);
}
static int
wdt_intr(void *argp)
{
struct wdt_softc *sc = argp;
if (RD4(sc, WDT_SR) & (WDT_WDUNF | WDT_WDERR)) {
#if defined(KDB) && !defined(KDB_UNATTENDED)
kdb_backtrace();
kdb_enter(KDB_WHY_WATCHDOG, "watchdog timeout");
#else
panic("watchdog timeout");
#endif
}
return (FILTER_STRAY);
}
/* User interface, see watchdog(9) */
static void
wdt_watchdog(void *argp, u_int cmd, int *error)
{
struct wdt_softc *sc = argp;
u_int interval;
mtx_lock(&sc->sc_mtx);
*error = 0;
sc->cmd = 0;
interval = cmd & WD_INTERVAL;
if (interval > WD_TO_16SEC)
*error = EOPNOTSUPP;
else if (interval > 0)
sc->cmd = interval | WD_ACTIVE;
/* We cannot turn off our watchdog so if user
* fails to turn us on go to passive mode. */
if ((sc->cmd & WD_ACTIVE) == 0)
sc->cmd = WD_PASSIVE;
mtx_unlock(&sc->sc_mtx);
}
/* This routine is called no matter what state the user sets the
* watchdog mode to. Called at a rate that is slightly less than
* half the hardware timeout. */
static void
wdt_tick(void *argp)
{
struct wdt_softc *sc = argp;
mtx_assert(&sc->sc_mtx, MA_OWNED);
if (sc->cmd & (WD_ACTIVE | WD_PASSIVE))
WR4(sc, WDT_CR, WDT_KEY|WDT_WDRSTT);
sc->cmd &= WD_PASSIVE;
callout_reset(&sc->tick_ch, sc->interval, wdt_tick, sc);
}
static int
wdt_probe(device_t dev)
{
#ifdef FDT
if (!ofw_bus_is_compatible(dev, "atmel,at91sam9260-wdt"))
return (ENXIO);
#endif
device_set_desc(dev, "WDT");
return (0);
}
static int
wdt_attach(device_t dev)
{
static struct wdt_softc *sc;
struct resource *irq;
uint32_t wdt_mr;
int rid, err;
sc = device_get_softc(dev);
sc->cmd = WD_PASSIVE;
sc->sc_dev = dev;
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), "at91_wdt", MTX_DEF);
callout_init_mtx(&sc->tick_ch, &sc->sc_mtx, 0);
rid = 0;
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (sc->mem_res == NULL)
panic("couldn't allocate wdt register resources");
wdt_mr = RD4(sc, WDT_MR);
if ((wdt_mr & WDT_WDRSTEN) == 0)
device_printf(dev, "Watchdog disabled! (Boot ROM?)\n");
else {
#ifdef WDT_RESET
/* Rude, full reset of whole system on watch dog timeout */
WR4(sc, WDT_MR, WDT_WDDBGHLT | WDT_WDD(0xC00)|
WDT_WDRSTEN| WDT_WDV(0xFFF));
#else
/* Generate stack trace and panic on watchdog timeout*/
WR4(sc, WDT_MR, WDT_WDDBGHLT | WDT_WDD(0xC00)|
WDT_WDFIEN| WDT_WDV(0xFFF));
#endif
/*
* This may have been set by Boot ROM so register value may
* not be what we just requested since this is a write once
* register.
*/
wdt_mr = RD4(sc, WDT_MR);
if (wdt_mr & WDT_WDFIEN) {
rid = 0;
irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE | RF_SHAREABLE);
if (!irq)
panic("could not allocate interrupt.\n");
err = bus_setup_intr(dev, irq, INTR_TYPE_CLK, wdt_intr,
NULL, sc, &sc->intrhand);
}
/* interval * hz */
sc->interval = (((wdt_mr & WDT_WDV(~0)) + 1) * WDT_DIV) /
(WDT_CLOCK/hz);
device_printf(dev, "watchdog timeout: %d seconds\n",
sc->interval / hz);
/* Slightly less than 1/2 of watchdog hardware timeout */
sc->interval = (sc->interval/2) - (sc->interval/20);
callout_reset(&sc->tick_ch, sc->interval, wdt_tick, sc);
/* Register us as a watchdog */
sc->sc_wet = EVENTHANDLER_REGISTER(watchdog_list,
wdt_watchdog, sc, 0);
}
return (0);
}
static device_method_t wdt_methods[] = {
DEVMETHOD(device_probe, wdt_probe),
DEVMETHOD(device_attach, wdt_attach),
DEVMETHOD_END
};
static driver_t wdt_driver = {
"at91_wdt",
wdt_methods,
sizeof(struct wdt_softc),
};
static devclass_t wdt_devclass;
#ifdef FDT
DRIVER_MODULE(at91_wdt, simplebus, wdt_driver, wdt_devclass, NULL, NULL);
#else
DRIVER_MODULE(at91_wdt, atmelarm, wdt_driver, wdt_devclass, NULL, NULL);
#endif

View File

@ -1,62 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2005 Gallon Sylvestre. 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 ARM_AT91_AT91WDTREG_H
#define ARM_AT91_AT91WDTREG_H
#ifndef WDT_CLOCK
#define WDT_CLOCK (32768)
#endif
#define WDT_DIV (128) /* Clock is slow clock / 128 */
#define WDT_CR 0x0 /* Control Register */
#define WDT_MR 0x4 /* Mode Register */
#define WDT_SR 0x8 /* Status Register */
/* WDT_CR */
#define WDT_KEY (0xa5<<24)
#define WDT_WDRSTT 0x1
/* WDT_MR */
#define WDT_WDV(x) (x & 0xfff) /* counter value*/
#define WDT_WDFIEN (1<<12) /* enable interrupt */
#define WDT_WDRSTEN (1<<13) /* enable reset */
#define WDT_WDRPROC (1<<14) /* processor reset */
#define WDT_WDDIS (1<<15) /* disable */
#define WDT_WDD(x) ((x & 0xfff) << 16) /* delta value */
#define WDT_WDDBGHLT (1<<28) /* halt in debug */
#define WDT_WDIDLEHLT (1<<29) /* halt in idle */
/* WDT_SR */
#define WDT_WDUNF 0x1
#define WDT_WDERR 0x2
#endif /* ARM_AT91_AT91WDTREG_H */

View File

@ -1,38 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2008 M. Warner Losh.
*
* 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 _ARM_AT91_AT91BOARD_H_
#define _ARM_AT91_AT91BOARD_H_
/*
* These routines are used by board init routines
*/
long at91_ramsize(void);
#endif /* _ARM_AT91_AT91BOARD_H_ */

View File

@ -1,92 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2009 Greg Ansley 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 _AT91REG_H_
#define _AT91REG_H_
#include "opt_at91.h"
/* Where builtin peripherals start in KVM */
#define AT91_BASE 0xd0000000
/* Where builtin peripherals start PA */
#define AT91_PA_BASE 0xf0000000
/* A few things that we count on being the same
* throughout the whole family of SOCs */
/* SYSC System Controller */
/* System Registers */
#define AT91_SYS_BASE 0xffff000
#define AT91_SYS_SIZE 0x1000
#define AT91_DBGU0 0x0ffff200 /* Most */
#define AT91_DBGU1 0x0fffee00 /* SAM9263, CAP9, and SAM9G45 */
#define AT91_DBGU_SIZE 0x200
#define DBGU_C1R (64) /* Chip ID1 Register */
#define DBGU_C2R (68) /* Chip ID2 Register */
#define DBGU_FNTR (72) /* Force NTRST Register */
#define AT91_CPU_VERSION_MASK 0x0000001f
#define AT91_CPU_FAMILY_MASK 0x0ff00000
#define AT91_CPU_RM9200 0x09290780
#define AT91_CPU_SAM9260 0x019803a0
#define AT91_CPU_SAM9261 0x019703a0
#define AT91_CPU_SAM9263 0x019607a0
#define AT91_CPU_SAM9G10 0x819903a0
#define AT91_CPU_SAM9G20 0x019905a0
#define AT91_CPU_SAM9G45 0x819b05a0
#define AT91_CPU_SAM9N12 0x819a07a0
#define AT91_CPU_SAM9RL64 0x019b03a0
#define AT91_CPU_SAM9X5 0x819a05a0
#define AT91_CPU_SAM9XE128 0x329973a0
#define AT91_CPU_SAM9XE256 0x329a93a0
#define AT91_CPU_SAM9XE512 0x329aa3a0
#define AT91_CPU_CAP9 0x039a03a0
#define AT91_EXID_SAM9M11 0x00000001
#define AT91_EXID_SAM9M10 0x00000002
#define AT91_EXID_SAM9G46 0x00000003
#define AT91_EXID_SAM9G45 0x00000004
#define AT91_EXID_SAM9G15 0x00000000
#define AT91_EXID_SAM9G35 0x00000001
#define AT91_EXID_SAM9X35 0x00000002
#define AT91_EXID_SAM9G25 0x00000003
#define AT91_EXID_SAM9X25 0x00000004
#define AT91_IRQ_SYSTEM 1
#endif /* _AT91REG_H_ */

View File

@ -1,211 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2005 Olivier Houchard. All rights reserved.
* Copyright (c) 2010 Greg Ansley. 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/bus.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
#define _ARM32_BUS_DMA_PRIVATE
#include <machine/bus.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91reg.h>
#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91_aicreg.h>
#include <arm/at91/at91_pmcreg.h>
#include <arm/at91/at91_streg.h>
#include <arm/at91/at91_pmcvar.h>
#include <arm/at91/at91soc.h>
/*
* Standard priority levels for the system. 0 is lowest and 7 is highest.
* These values are the ones Atmel uses for its Linux port, which differ
* a little form the ones that are in the standard distribution. Also,
* the ones marked with 'TWEEK' are different based on experience.
*/
static const int at91_irq_prio[32] =
{
7, /* Advanced Interrupt Controller (FIQ) */
7, /* System Peripherals */
1, /* Parallel IO Controller A */
1, /* Parallel IO Controller B */
1, /* Parallel IO Controller C */
1, /* Parallel IO Controller D */
5, /* USART 0 */
5, /* USART 1 */
5, /* USART 2 */
5, /* USART 3 */
0, /* Multimedia Card Interface */
2, /* USB Device Port */
4, /* Two-Wire Interface */ /* TWEEK */
5, /* Serial Peripheral Interface */
4, /* Serial Synchronous Controller 0 */
6, /* Serial Synchronous Controller 1 */ /* TWEEK */
4, /* Serial Synchronous Controller 2 */
0, /* Timer Counter 0 */
6, /* Timer Counter 1 */ /* TWEEK */
0, /* Timer Counter 2 */
0, /* Timer Counter 3 */
0, /* Timer Counter 4 */
0, /* Timer Counter 5 */
2, /* USB Host port */
3, /* Ethernet MAC */
0, /* Advanced Interrupt Controller (IRQ0) */
0, /* Advanced Interrupt Controller (IRQ1) */
0, /* Advanced Interrupt Controller (IRQ2) */
0, /* Advanced Interrupt Controller (IRQ3) */
0, /* Advanced Interrupt Controller (IRQ4) */
0, /* Advanced Interrupt Controller (IRQ5) */
0 /* Advanced Interrupt Controller (IRQ6) */
};
static const uint32_t at91_pio_base[] = {
AT91RM92_PIOA_BASE,
AT91RM92_PIOB_BASE,
AT91RM92_PIOC_BASE,
AT91RM92_PIOD_BASE,
};
#define DEVICE(_name, _id, _unit) \
{ \
_name, _unit, \
AT91RM92_ ## _id ##_BASE, \
AT91RM92_ ## _id ## _SIZE, \
AT91RM92_IRQ_ ## _id \
}
static const struct cpu_devs at91_devs[] =
{
DEVICE("at91_aic", AIC, 0),
DEVICE("at91_pmc", PMC, 0),
DEVICE("at91_st", ST, 0),
DEVICE("at91_pio", PIOA, 0),
DEVICE("at91_pio", PIOB, 1),
DEVICE("at91_pio", PIOC, 2),
DEVICE("at91_pio", PIOD, 3),
DEVICE("at91_rtc", RTC, 0),
DEVICE("at91_mci", MCI, 0),
DEVICE("at91_twi", TWI, 0),
DEVICE("at91_udp", UDP, 0),
DEVICE("ate", EMAC, 0),
DEVICE("at91_ssc", SSC0, 0),
DEVICE("at91_ssc", SSC1, 1),
DEVICE("at91_ssc", SSC2, 2),
DEVICE("spi", SPI, 0),
DEVICE("uart", DBGU, 0),
DEVICE("uart", USART0, 1),
DEVICE("uart", USART1, 2),
DEVICE("uart", USART2, 3),
DEVICE("uart", USART3, 4),
DEVICE("at91_mc", MC, 0),
DEVICE("at91_tc", TC0, 0),
DEVICE("at91_tc", TC1, 1),
DEVICE("ohci", OHCI, 0),
DEVICE("at91_cfata", CF, 0),
{ 0, 0, 0, 0, 0 }
};
static uint32_t
at91_pll_outb(int freq)
{
if (freq > 155000000)
return (0x0000);
else
return (0x8000);
}
#if 0
/* -- XXX are these needed? */
/* Disable all interrupts for RTC (0xe24 == RTC_IDR) */
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xe24, 0xffffffff);
/* Disable all interrupts for the SDRAM controller */
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xfa8, 0xffffffff);
#endif
static void
at91_clock_init(void)
{
struct at91_pmc_clock *clk;
/* Update USB device port clock info */
clk = at91_pmc_clock_ref("udpck");
clk->pmc_mask = PMC_SCER_UDP;
at91_pmc_clock_deref(clk);
/* Update USB host port clock info */
clk = at91_pmc_clock_ref("uhpck");
clk->pmc_mask = PMC_SCER_UHP;
at91_pmc_clock_deref(clk);
/* Each SOC has different PLL contraints */
clk = at91_pmc_clock_ref("plla");
clk->pll_min_in = RM9200_PLL_A_MIN_IN_FREQ; /* 1 MHz */
clk->pll_max_in = RM9200_PLL_A_MAX_IN_FREQ; /* 32 MHz */
clk->pll_min_out = RM9200_PLL_A_MIN_OUT_FREQ; /* 80 MHz */
clk->pll_max_out = RM9200_PLL_A_MAX_OUT_FREQ; /* 180 MHz */
clk->pll_mul_shift = RM9200_PLL_A_MUL_SHIFT;
clk->pll_mul_mask = RM9200_PLL_A_MUL_MASK;
clk->pll_div_shift = RM9200_PLL_A_DIV_SHIFT;
clk->pll_div_mask = RM9200_PLL_A_DIV_MASK;
clk->set_outb = at91_pll_outb;
at91_pmc_clock_deref(clk);
clk = at91_pmc_clock_ref("pllb");
clk->pll_min_in = RM9200_PLL_B_MIN_IN_FREQ; /* 100 KHz */
clk->pll_max_in = RM9200_PLL_B_MAX_IN_FREQ; /* 32 MHz */
clk->pll_min_out = RM9200_PLL_B_MIN_OUT_FREQ; /* 30 MHz */
clk->pll_max_out = RM9200_PLL_B_MAX_OUT_FREQ; /* 240 MHz */
clk->pll_mul_shift = RM9200_PLL_B_MUL_SHIFT;
clk->pll_mul_mask = RM9200_PLL_B_MUL_MASK;
clk->pll_div_shift = RM9200_PLL_B_DIV_SHIFT;
clk->pll_div_mask = RM9200_PLL_B_DIV_MASK;
clk->set_outb = at91_pll_outb;
at91_pmc_clock_deref(clk);
}
static struct at91_soc_data soc_data = {
.soc_delay = at91_st_delay,
.soc_reset = at91_st_cpu_reset,
.soc_clock_init = at91_clock_init,
.soc_irq_prio = at91_irq_prio,
.soc_children = at91_devs,
.soc_pio_base = at91_pio_base,
.soc_pio_count = nitems(at91_pio_base),
};
AT91_SOC(AT91_T_RM9200, &soc_data);

View File

@ -1,144 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2012 M. Warner Losh.
*
* 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/bus.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
#define _ARM32_BUS_DMA_PRIVATE
#include <machine/bus.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91board.h>
#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91rm9200var.h>
#include <arm/at91/at91_pioreg.h>
#include <arm/at91/at91_piovar.h>
/*
* The AT91RM9200 uses the same silicon for both the BGA and PQFP
* packages. There's no documented way to detect this at runtime,
* so we require the board code to register what type of SoC is on the
* board in question. The pinouts are not quite compatible, and we
* use this information to cope with the slight differences.
*/
void
at91rm9200_set_subtype(enum at91_soc_subtype st)
{
switch (st) {
case AT91_ST_RM9200_BGA:
case AT91_ST_RM9200_PQFP:
soc_info.subtype = st;
break;
default:
panic("Bad SoC subtype %d for at91rm9200_set_subtype.", st);
break;
}
}
void
at91rm9200_config_uart(unsigned devid, unsigned unit, unsigned pinmask)
{
/*
* Since the USART supports RS-485 multidrop mode, it allows the
* TX pins to float. However, for RS-232 operations, we don't want
* these pins to float. Instead, they should be pulled up to avoid
* mismatches. Linux does something similar when it configures the
* TX lines. This implies that we also allow the RX lines to float
* rather than be in the state they are left in by the boot loader.
* Since they are input pins, I think that this is the right thing
* to do.
*/
/*
* Current boards supported don't need the extras, but they should be
* implemented. But that should wait until the new pin api goes in.
*/
switch (devid) {
case AT91_ID_DBGU:
at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA30, 0); /* DRXD */
at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA31, 1); /* DTXD */
break;
case AT91RM9200_ID_USART0:
at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA17, 1); /* TXD0 */
at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA18, 0); /* RXD0 */
/* CTS PA20 */
/* RTS -- errata #39 PA21 */
break;
case AT91RM9200_ID_USART1:
at91_pio_use_periph_a(AT91RM92_PIOB_BASE, AT91C_PIO_PB20, 1); /* TXD1 */
at91_pio_use_periph_a(AT91RM92_PIOB_BASE, AT91C_PIO_PB21, 0); /* RXD1 */
/* RI - PB18 */
/* DTR - PB19 */
/* DCD - PB23 */
/* CTS - PB24 */
/* DSR - PB25 */
/* RTS - PB26 */
break;
case AT91RM9200_ID_USART2:
at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA22, 0); /* RXD2 */
at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA23, 1); /* TXD2 */
/* CTS - PA30 B periph */
/* RTS - PA31 B periph */
break;
case AT91RM9200_ID_USART3:
at91_pio_use_periph_b(AT91RM92_PIOA_BASE, AT91C_PIO_PA5, 1); /* TXD3 */
at91_pio_use_periph_b(AT91RM92_PIOA_BASE, AT91C_PIO_PA6, 0); /* RXD3 */
/* CTS - PB0 B periph */
/* RTS - PB1 B periph */
break;
default:
break;
}
}
void
at91rm9200_config_mci(int has_4wire)
{
/* XXX TODO chip changed GPIO, other slots, etc */
at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA27, 0); /* MCCK */
at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA28, 1); /* MCCDA */
at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA29, 1); /* MCDA0 */
if (has_4wire) {
at91_pio_use_periph_b(AT91RM92_PIOB_BASE, AT91C_PIO_PB3, 1); /* MCDA1 */
at91_pio_use_periph_b(AT91RM92_PIOB_BASE, AT91C_PIO_PB4, 1); /* MCDA2 */
at91_pio_use_periph_b(AT91RM92_PIOB_BASE, AT91C_PIO_PB5, 1); /* MCDA3 */
}
}

View File

@ -1,60 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2012 M. Warner Losh.
*
* 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 ARM_AT91_AT91RM9200VAR_H
#define ARM_AT91_AT91RM9200VAR_H
void at91rm9200_set_subtype(enum at91_soc_subtype st);
#define AT91RM9200_ID_USART0 1
#define AT91RM9200_ID_USART1 2
#define AT91RM9200_ID_USART2 3
#define AT91RM9200_ID_USART3 4
/*
* Serial port convenience routines
*/
/* uart pins that are wired... */
#define AT91_UART_CTS 0x01
#define AT91_UART_RTS 0x02
#define AT91_UART_RI 0x04
#define AT91_UART_DTR 0x08
#define AT91_UART_DCD 0x10
#define AT91_UART_DSR 0x20
#define AT91_ID_DBGU 0
void at91rm9200_config_uart(unsigned devid, unsigned unit, unsigned pinmask);
/*
* MCI (sd/mmc card support)
*/
void at91rm9200_config_mci(int has_4wire);
#endif /* ARM_AT91_AT91RM9200VAR_H */

View File

@ -1,308 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2005 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 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 AT91RM92REG_H_
#define AT91RM92REG_H_
/* Chip Specific limits */
#define RM9200_PLL_A_MIN_IN_FREQ 1000000 /* 1 MHz */
#define RM9200_PLL_A_MAX_IN_FREQ 32000000 /* 32 MHz */
#define RM9200_PLL_A_MIN_OUT_FREQ 80000000 /* 80 MHz */
#define RM9200_PLL_A_MAX_OUT_FREQ 180000000 /* 180 MHz */
#define RM9200_PLL_A_MUL_SHIFT 16
#define RM9200_PLL_A_MUL_MASK 0x7FF
#define RM9200_PLL_A_DIV_SHIFT 0
#define RM9200_PLL_A_DIV_MASK 0xFF
/*
* PLL B input frequency spec sheet says it must be between 1MHz and 32MHz,
* but it works down as low as 100kHz, a frequency necessary for some
* output frequencies to work.
*
* PLL Max output frequency is 240MHz. The errata says 180MHz is the max
* for some revisions of this part. Be more permissive and optimistic.
*/
#define RM9200_PLL_B_MIN_IN_FREQ 100000 /* 100 KHz */
#define RM9200_PLL_B_MAX_IN_FREQ 32000000 /* 32 MHz */
#define RM9200_PLL_B_MIN_OUT_FREQ 30000000 /* 30 MHz */
#define RM9200_PLL_B_MAX_OUT_FREQ 240000000 /* 240 MHz */
#define RM9200_PLL_B_MUL_SHIFT 16
#define RM9200_PLL_B_MUL_MASK 0x7FF
#define RM9200_PLL_B_DIV_SHIFT 0
#define RM9200_PLL_B_DIV_MASK 0xFF
/*
* Memory map, from datasheet :
* 0x00000000 - 0x0ffffffff : Internal Memories
* 0x10000000 - 0x1ffffffff : Chip Select 0
* 0x20000000 - 0x2ffffffff : Chip Select 1
* 0x30000000 - 0x3ffffffff : Chip Select 2
* 0x40000000 - 0x4ffffffff : Chip Select 3
* 0x50000000 - 0x5ffffffff : Chip Select 4
* 0x60000000 - 0x6ffffffff : Chip Select 5
* 0x70000000 - 0x7ffffffff : Chip Select 6
* 0x80000000 - 0x8ffffffff : Chip Select 7
* 0x90000000 - 0xeffffffff : Undefined (Abort)
* 0xf0000000 - 0xfffffffff : Peripherals
*/
/* Usart */
#define AT91RM92_USART_SIZE 0x4000
#define AT91RM92_USART0_BASE 0xffc0000
#define AT91RM92_USART0_PDC 0xffc0100
#define AT91RM92_USART0_SIZE AT91RM92_USART_SIZE
#define AT91RM92_USART1_BASE 0xffc4000
#define AT91RM92_USART1_PDC 0xffc4100
#define AT91RM92_USART1_SIZE AT91RM92_USART_SIZE
#define AT91RM92_USART2_BASE 0xffc8000
#define AT91RM92_USART2_PDC 0xffc8100
#define AT91RM92_USART2_SIZE AT91RM92_USART_SIZE
#define AT91RM92_USART3_BASE 0xffcc000
#define AT91RM92_USART3_PDC 0xffcc100
#define AT91RM92_USART3_SIZE AT91RM92_USART_SIZE
/* System Registers */
#define AT91RM92_SYS_BASE 0xffff000
#define AT91RM92_SYS_SIZE 0x1000
/*
* PIO
*/
#define AT91RM92_PIO_SIZE 0x200
#define AT91RM92_PIOA_BASE 0xffff400
#define AT91RM92_PIOA_SIZE AT91RM92_PIO_SIZE
#define AT91RM92_PIOB_BASE 0xffff600
#define AT91RM92_PIOB_SIZE AT91RM92_PIO_SIZE
#define AT91RM92_PIOC_BASE 0xffff800
#define AT91RM92_PIOC_SIZE AT91RM92_PIO_SIZE
#define AT91RM92_PIOD_BASE 0xffffa00
#define AT91RM92_PIOD_SIZE AT91RM92_PIO_SIZE
/*
* PMC
*/
#define AT91RM92_PMC_BASE 0xffffc00
#define AT91RM92_PMC_SIZE 0x100
/* IRQs : */
/*
* 0: AIC
* 1: System peripheral (System timer, RTC, DBGU)
* 2: PIO Controller A
* 3: PIO Controller B
* 4: PIO Controller C
* 5: PIO Controller D
* 6: USART 0
* 7: USART 1
* 8: USART 2
* 9: USART 3
* 10: MMC Interface
* 11: USB device port
* 12: Two-wire interface
* 13: SPI
* 14: SSC
* 15: SSC
* 16: SSC
* 17: Timer Counter 0
* 18: Timer Counter 1
* 19: Timer Counter 2
* 20: Timer Counter 3
* 21: Timer Counter 4
* 22: Timer Counter 5
* 23: USB Host port
* 24: Ethernet
* 25: AIC
* 26: AIC
* 27: AIC
* 28: AIC
* 29: AIC
* 30: AIC
* 31: AIC
*/
#define AT91RM92_IRQ_SYSTEM 1
#define AT91RM92_IRQ_PIOA 2
#define AT91RM92_IRQ_PIOB 3
#define AT91RM92_IRQ_PIOC 4
#define AT91RM92_IRQ_PIOD 5
#define AT91RM92_IRQ_USART0 6
#define AT91RM92_IRQ_USART1 7
#define AT91RM92_IRQ_USART2 8
#define AT91RM92_IRQ_USART3 9
#define AT91RM92_IRQ_MCI 10
#define AT91RM92_IRQ_UDP 11
#define AT91RM92_IRQ_TWI 12
#define AT91RM92_IRQ_SPI 13
#define AT91RM92_IRQ_SSC0 14
#define AT91RM92_IRQ_SSC1 15
#define AT91RM92_IRQ_SSC2 16
#define AT91RM92_IRQ_TC0 17,18,19
#define AT91RM92_IRQ_TC0C0 17
#define AT91RM92_IRQ_TC0C1 18
#define AT91RM92_IRQ_TC0C2 19
#define AT91RM92_IRQ_TC1 20,21,22
#define AT91RM92_IRQ_TC1C1 20
#define AT91RM92_IRQ_TC1C2 21
#define AT91RM92_IRQ_TC1C3 22
#define AT91RM92_IRQ_UHP 23
#define AT91RM92_IRQ_EMAC 24
#define AT91RM92_IRQ_AIC_IRQ0 25
#define AT91RM92_IRQ_AIC_IRQ1 26
#define AT91RM92_IRQ_AIC_IRQ2 27
#define AT91RM92_IRQ_AIC_IRQ3 28
#define AT91RM92_IRQ_AIC_IRQ4 29
#define AT91RM92_IRQ_AIC_IRQ5 30
#define AT91RM92_IRQ_AIC_IRQ6 31
/* Alias */
#define AT91RM92_IRQ_DBGU AT91RM92_IRQ_SYSTEM
#define AT91RM92_IRQ_PMC AT91RM92_IRQ_SYSTEM
#define AT91RM92_IRQ_ST AT91RM92_IRQ_SYSTEM
#define AT91RM92_IRQ_RTC AT91RM92_IRQ_SYSTEM
#define AT91RM92_IRQ_MC AT91RM92_IRQ_SYSTEM
#define AT91RM92_IRQ_OHCI AT91RM92_IRQ_UHP
#define AT91RM92_IRQ_AIC -1
#define AT91RM92_IRQ_CF -1
/* Timer */
#define AT91RM92_AIC_BASE 0xffff000
#define AT91RM92_AIC_SIZE 0x200
/* DBGU */
#define AT91RM92_DBGU_BASE 0xffff200
#define AT91RM92_DBGU_SIZE 0x200
#define AT91RM92_RTC_BASE 0xffffe00
#define AT91RM92_RTC_SIZE 0x100
#define AT91RM92_MC_BASE 0xfffff00
#define AT91RM92_MC_SIZE 0x100
#define AT91RM92_ST_BASE 0xffffd00
#define AT91RM92_ST_SIZE 0x100
#define AT91RM92_SPI_BASE 0xffe0000
#define AT91RM92_SPI_SIZE 0x4000
#define AT91RM92_SPI_PDC 0xffe0100
#define AT91RM92_SSC_SIZE 0x4000
#define AT91RM92_SSC0_BASE 0xffd0000
#define AT91RM92_SSC0_PDC 0xffd0100
#define AT91RM92_SSC0_SIZE AT91RM92_SSC_SIZE
#define AT91RM92_SSC1_BASE 0xffd4000
#define AT91RM92_SSC1_PDC 0xffd4100
#define AT91RM92_SSC1_SIZE AT91RM92_SSC_SIZE
#define AT91RM92_SSC2_BASE 0xffd8000
#define AT91RM92_SSC2_PDC 0xffd8100
#define AT91RM92_SSC2_SIZE AT91RM92_SSC_SIZE
#define AT91RM92_EMAC_BASE 0xffbc000
#define AT91RM92_EMAC_SIZE 0x4000
#define AT91RM92_TWI_BASE 0xffb8000
#define AT91RM92_TWI_SIZE 0x4000
#define AT91RM92_MCI_BASE 0xffb4000
#define AT91RM92_MCI_PDC 0xffb4100
#define AT91RM92_MCI_SIZE 0x4000
#define AT91RM92_UDP_BASE 0xffb0000
#define AT91RM92_UDP_SIZE 0x4000
#define AT91RM92_TC_SIZE 0x4000
#define AT91RM92_TC0_BASE 0xffa0000
#define AT91RM92_TC0_SIZE AT91RM92_TC_SIZE
#define AT91RM92_TC0C0_BASE 0xffa0000
#define AT91RM92_TC0C1_BASE 0xffa0040
#define AT91RM92_TC0C2_BASE 0xffa0080
#define AT91RM92_TC1_BASE 0xffa4000
#define AT91RM92_TC1_SIZE AT91RM92_TC_SIZE
#define AT91RM92_TC1C0_BASE 0xffa4000
#define AT91RM92_TC1C1_BASE 0xffa4040
#define AT91RM92_TC1C2_BASE 0xffa4080
/* XXX Needs to be carfully coordinated with
* other * soc's so phyical and vm address
* mapping are unique. XXX
*/
#define AT91RM92_OHCI_VA_BASE 0xdfe00000
#define AT91RM92_OHCI_BASE 0x00300000
#define AT91RM92_OHCI_SIZE 0x00100000
#define AT91RM92_CF_VA_BASE 0xdfd00000
#define AT91RM92_CF_BASE 0x51400000
#define AT91RM92_CF_SIZE 0x00100000
/* SDRAMC */
#define AT91RM92_SDRAMC_BASE 0xfffff90
#define AT91RM92_SDRAMC_MR 0x00
#define AT91RM92_SDRAMC_MR_MODE_NORMAL 0
#define AT91RM92_SDRAMC_MR_MODE_NOP 1
#define AT91RM92_SDRAMC_MR_MODE_PRECHARGE 2
#define AT91RM92_SDRAMC_MR_MODE_LOAD_MODE_REGISTER 3
#define AT91RM92_SDRAMC_MR_MODE_REFRESH 4
#define AT91RM92_SDRAMC_MR_DBW_16 0x10
#define AT91RM92_SDRAMC_TR 0x04
#define AT91RM92_SDRAMC_CR 0x08
#define AT91RM92_SDRAMC_CR_NC_8 0x0
#define AT91RM92_SDRAMC_CR_NC_9 0x1
#define AT91RM92_SDRAMC_CR_NC_10 0x2
#define AT91RM92_SDRAMC_CR_NC_11 0x3
#define AT91RM92_SDRAMC_CR_NC_MASK 0x00000003
#define AT91RM92_SDRAMC_CR_NR_11 0x0
#define AT91RM92_SDRAMC_CR_NR_12 0x4
#define AT91RM92_SDRAMC_CR_NR_13 0x8
#define AT91RM92_SDRAMC_CR_NR_RES 0xc
#define AT91RM92_SDRAMC_CR_NR_MASK 0x0000000c
#define AT91RM92_SDRAMC_CR_NB_2 0x00
#define AT91RM92_SDRAMC_CR_NB_4 0x10
#define AT91RM92_SDRAMC_CR_NB_MASK 0x00000010
#define AT91RM92_SDRAMC_CR_NCAS_MASK 0x00000060
#define AT91RM92_SDRAMC_CR_TWR_MASK 0x00000780
#define AT91RM92_SDRAMC_CR_TRC_MASK 0x00007800
#define AT91RM92_SDRAMC_CR_TRP_MASK 0x00078000
#define AT91RM92_SDRAMC_CR_TRCD_MASK 0x00780000
#define AT91RM92_SDRAMC_CR_TRAS_MASK 0x07800000
#define AT91RM92_SDRAMC_CR_TXSR_MASK 0x78000000
#define AT91RM92_SDRAMC_SRR 0x0c
#define AT91RM92_SDRAMC_LPR 0x10
#define AT91RM92_SDRAMC_IER 0x14
#define AT91RM92_SDRAMC_IDR 0x18
#define AT91RM92_SDRAMC_IMR 0x1c
#define AT91RM92_SDRAMC_ISR 0x20
#define AT91RM92_SDRAMC_IER_RES 0x1
#endif /* AT91RM92REG_H_ */

View File

@ -1,219 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2005 Olivier Houchard. All rights reserved.
* Copyright (c) 2010 Greg Ansley. 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/bus.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
#define _ARM32_BUS_DMA_PRIVATE
#include <machine/bus.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91reg.h>
#include <arm/at91/at91soc.h>
#include <arm/at91/at91_aicreg.h>
#include <arm/at91/at91sam9260reg.h>
#include <arm/at91/at91_pitreg.h>
#include <arm/at91/at91_pmcreg.h>
#include <arm/at91/at91_pmcvar.h>
#include <arm/at91/at91_rstreg.h>
/*
* Standard priority levels for the system. 0 is lowest and 7 is highest.
* These values are the ones Atmel uses for its Linux port
*/
static const int at91_irq_prio[32] =
{
7, /* Advanced Interrupt Controller */
7, /* System Peripherals */
1, /* Parallel IO Controller A */
1, /* Parallel IO Controller B */
1, /* Parallel IO Controller C */
0, /* Analog-to-Digital Converter */
5, /* USART 0 */
5, /* USART 1 */
5, /* USART 2 */
0, /* Multimedia Card Interface */
2, /* USB Device Port */
6, /* Two-Wire Interface */
5, /* Serial Peripheral Interface 0 */
5, /* Serial Peripheral Interface 1 */
5, /* Serial Synchronous Controller */
0, /* (reserved) */
0, /* (reserved) */
0, /* Timer Counter 0 */
0, /* Timer Counter 1 */
0, /* Timer Counter 2 */
2, /* USB Host port */
3, /* Ethernet */
0, /* Image Sensor Interface */
5, /* USART 3 */
5, /* USART 4 */
5, /* USART 5 */
0, /* Timer Counter 3 */
0, /* Timer Counter 4 */
0, /* Timer Counter 5 */
0, /* Advanced Interrupt Controller IRQ0 */
0, /* Advanced Interrupt Controller IRQ1 */
0, /* Advanced Interrupt Controller IRQ2 */
};
static const uint32_t at91_pio_base[] = {
AT91SAM9260_PIOA_BASE,
AT91SAM9260_PIOB_BASE,
AT91SAM9260_PIOC_BASE,
};
#define DEVICE(_name, _id, _unit) \
{ \
_name, _unit, \
AT91SAM9260_ ## _id ##_BASE, \
AT91SAM9260_ ## _id ## _SIZE, \
AT91SAM9260_IRQ_ ## _id \
}
static const struct cpu_devs at91_devs[] =
{
DEVICE("at91_aic", AIC, 0),
DEVICE("at91_pmc", PMC, 0),
DEVICE("at91_wdt", WDT, 0),
DEVICE("at91_rst", RSTC, 0),
DEVICE("at91_pit", PIT, 0),
DEVICE("at91_pio", PIOA, 0),
DEVICE("at91_pio", PIOB, 1),
DEVICE("at91_pio", PIOC, 2),
DEVICE("at91_twi", TWI, 0),
DEVICE("at91_mci", MCI, 0),
DEVICE("uart", DBGU, 0),
DEVICE("uart", USART0, 1),
DEVICE("uart", USART1, 2),
DEVICE("uart", USART2, 3),
DEVICE("uart", USART3, 4),
DEVICE("uart", USART4, 5),
DEVICE("uart", USART5, 6),
DEVICE("spi", SPI0, 0),
DEVICE("spi", SPI1, 1),
DEVICE("ate", EMAC, 0),
DEVICE("macb", EMAC, 0),
DEVICE("nand", NAND, 0),
DEVICE("ohci", OHCI, 0),
{ 0, 0, 0, 0, 0 }
};
/*
* The following is unused currently since we don't ever set the PLLA
* frequency of the device.
*/
static uint32_t
at91_pll_outa(int freq)
{
uint32_t outa = 0;
/*
* Set OUTA, per the data sheet. See Table 40-15 titled
* PLLA Characteristics in the SAM9260 doc.
*/
if (freq > 155000000)
outa = 2 << 14;
return ((1 << 29) | outa);
}
static uint32_t
at91_pll_outb(int freq)
{
return (1 << 14);
}
static void
at91_clock_init(void)
{
struct at91_pmc_clock *clk;
/* Update USB device port clock info */
clk = at91_pmc_clock_ref("udpck");
clk->pmc_mask = PMC_SCER_UDP_SAM9;
at91_pmc_clock_deref(clk);
/* Update USB host port clock info */
clk = at91_pmc_clock_ref("uhpck");
clk->pmc_mask = PMC_SCER_UHP_SAM9;
at91_pmc_clock_deref(clk);
/* Each SOC has different PLL contraints */
clk = at91_pmc_clock_ref("plla");
clk->pll_min_in = SAM9260_PLL_A_MIN_IN_FREQ; /* 1 MHz */
clk->pll_max_in = SAM9260_PLL_A_MAX_IN_FREQ; /* 32 MHz */
clk->pll_min_out = SAM9260_PLL_A_MIN_OUT_FREQ; /* 80 MHz */
clk->pll_max_out = SAM9260_PLL_A_MAX_OUT_FREQ; /* 240 MHz */
clk->pll_mul_shift = SAM9260_PLL_A_MUL_SHIFT;
clk->pll_mul_mask = SAM9260_PLL_A_MUL_MASK;
clk->pll_div_shift = SAM9260_PLL_A_DIV_SHIFT;
clk->pll_div_mask = SAM9260_PLL_A_DIV_MASK;
clk->set_outb = at91_pll_outa;
at91_pmc_clock_deref(clk);
/*
* Fudge MAX pll in frequence down below 3.0 MHz to ensure
* PMC alogrithm choose the divisor that causes the input clock
* to be near the optimal 2 MHz per datasheet. We know
* we are going to be using this for the USB clock at 96 MHz.
* Causes no extra frequency deviation for all recommended crystal
* values. See Note 1, table 40-16 SAM9260 doc.
*/
clk = at91_pmc_clock_ref("pllb");
clk->pll_min_in = SAM9260_PLL_B_MIN_IN_FREQ; /* 1 MHz */
clk->pll_max_in = 2999999; /* ~3 MHz */
clk->pll_min_out = SAM9260_PLL_B_MIN_OUT_FREQ; /* 70 MHz */
clk->pll_max_out = SAM9260_PLL_B_MAX_OUT_FREQ; /* 130 MHz */
clk->pll_mul_shift = SAM9260_PLL_B_MUL_SHIFT;
clk->pll_mul_mask = SAM9260_PLL_B_MUL_MASK;
clk->pll_div_shift = SAM9260_PLL_B_DIV_SHIFT;
clk->pll_div_mask = SAM9260_PLL_B_DIV_MASK;
clk->set_outb = at91_pll_outb;
at91_pmc_clock_deref(clk);
}
static struct at91_soc_data soc_data = {
.soc_delay = at91_pit_delay,
.soc_reset = at91_rst_cpu_reset,
.soc_clock_init = at91_clock_init,
.soc_irq_prio = at91_irq_prio,
.soc_children = at91_devs,
.soc_pio_base = at91_pio_base,
.soc_pio_count = nitems(at91_pio_base),
};
AT91_SOC(AT91_T_SAM9260, &soc_data);

View File

@ -1,306 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2010 Greg Ansley. 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 AT91SAM9260REG_H_
#define AT91SAM9260REG_H_
/* Chip Specific limits */
#define SAM9260_PLL_A_MIN_IN_FREQ 1000000 /* 1 Mhz */
#define SAM9260_PLL_A_MAX_IN_FREQ 32000000 /* 32 Mhz */
#define SAM9260_PLL_A_MIN_OUT_FREQ 80000000 /* 80 Mhz */
#define SAM9260_PLL_A_MAX_OUT_FREQ 240000000 /* 240 Mhz */
#define SAM9260_PLL_A_MUL_SHIFT 16
#define SAM9260_PLL_A_MUL_MASK 0x3FF
#define SAM9260_PLL_A_DIV_SHIFT 0
#define SAM9260_PLL_A_DIV_MASK 0xFF
#define SAM9260_PLL_B_MIN_IN_FREQ 1000000 /* 1 Mhz */
#define SAM9260_PLL_B_MAX_IN_FREQ 5000000 /* 5 Mhz */
#define SAM9260_PLL_B_MIN_OUT_FREQ 70000000 /* 70 Mhz */
#define SAM9260_PLL_B_MAX_OUT_FREQ 130000000 /* 130 Mhz */
#define SAM9260_PLL_B_MUL_SHIFT 16
#define SAM9260_PLL_B_MUL_MASK 0x3FF
#define SAM9260_PLL_B_DIV_SHIFT 0
#define SAM9260_PLL_B_DIV_MASK 0xFF
/*
* Memory map, from datasheet :
* 0x00000000 - 0x0ffffffff : Internal Memories
* 0x10000000 - 0x1ffffffff : Chip Select 0
* 0x20000000 - 0x2ffffffff : Chip Select 1
* 0x30000000 - 0x3ffffffff : Chip Select 2
* 0x40000000 - 0x4ffffffff : Chip Select 3
* 0x50000000 - 0x5ffffffff : Chip Select 4
* 0x60000000 - 0x6ffffffff : Chip Select 5
* 0x70000000 - 0x7ffffffff : Chip Select 6
* 0x80000000 - 0x8ffffffff : Chip Select 7
* 0x90000000 - 0xeffffffff : Undefined (Abort)
* 0xf0000000 - 0xfffffffff : Peripherals
*/
#define AT91_CHIPSELECT_0 0x10000000
#define AT91_CHIPSELECT_1 0x20000000
#define AT91_CHIPSELECT_2 0x30000000
#define AT91_CHIPSELECT_3 0x40000000
#define AT91_CHIPSELECT_4 0x50000000
#define AT91_CHIPSELECT_5 0x60000000
#define AT91_CHIPSELECT_6 0x70000000
#define AT91_CHIPSELECT_7 0x80000000
#define AT91SAM9260_EMAC_BASE 0xffc4000
#define AT91SAM9260_EMAC_SIZE 0x4000
#define AT91SAM9260_RSTC_BASE 0xffffd00
#define AT91SAM9260_RSTC_SIZE 0x10
#define RSTC_CR 0
#define RSTC_PROCRST (1 << 0)
#define RSTC_PERRST (1 << 2)
#define RSTC_KEY (0xa5 << 24)
/* USART*/
#define AT91SAM9260_USART_SIZE 0x4000
#define AT91SAM9260_USART0_BASE 0xffb0000
#define AT91SAM9260_USART0_PDC 0xffb0100
#define AT91SAM9260_USART0_SIZE AT91SAM9260_USART_SIZE
#define AT91SAM9260_USART1_BASE 0xffb4000
#define AT91SAM9260_USART1_PDC 0xffb4100
#define AT91SAM9260_USART1_SIZE AT91SAM9260_USART_SIZE
#define AT91SAM9260_USART2_BASE 0xffb8000
#define AT91SAM9260_USART2_PDC 0xffb8100
#define AT91SAM9260_USART2_SIZE AT91SAM9260_USART_SIZE
#define AT91SAM9260_USART3_BASE 0xffd0000
#define AT91SAM9260_USART3_PDC 0xffd0100
#define AT91SAM9260_USART3_SIZE AT91SAM9260_USART_SIZE
#define AT91SAM9260_USART4_BASE 0xffd4000
#define AT91SAM9260_USART4_PDC 0xffd4100
#define AT91SAM9260_USART4_SIZE AT91SAM9260_USART_SIZE
#define AT91SAM9260_USART5_BASE 0xffd8000
#define AT91SAM9260_USART5_PDC 0xffd8100
#define AT91SAM9260_USART5_SIZE AT91SAM9260_USART_SIZE
/*TC*/
#define AT91SAM9260_TC0_BASE 0xffa0000
#define AT91SAM9260_TC0_SIZE 0x4000
#define AT91SAM9260_TC0C0_BASE 0xffa0000
#define AT91SAM9260_TC0C1_BASE 0xffa0040
#define AT91SAM9260_TC0C2_BASE 0xffa0080
#define AT91SAM9260_TC1_BASE 0xffdc000
#define AT91SAM9260_TC1_SIZE 0x4000
/*SPI*/
#define AT91SAM9260_SPI0_BASE 0xffc8000
#define AT91SAM9260_SPI0_SIZE 0x4000
#define AT91SAM9260_IRQ_SPI0 12
#define AT91SAM9260_SPI1_BASE 0xffcc000
#define AT91SAM9260_SPI1_SIZE 0x4000
#define AT91SAM9260_IRQ_SPI1 13
/* System Registers */
#define AT91SAM9260_SYS_BASE 0xffff000
#define AT91SAM9260_SYS_SIZE 0x1000
#define AT91SAM9260_MATRIX_BASE 0xfffee00
#define AT91SAM9260_MATRIX_SIZE 0x1000
#define AT91SAM9260_EBICSA 0x011C
#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3)
#define AT91SAM9260_DBGU_BASE 0xffff200
#define AT91SAM9260_DBGU_SIZE 0x200
/*
* PIO
*/
#define AT91SAM9260_PIOA_BASE 0xffff400
#define AT91SAM9260_PIOA_SIZE 0x200
#define AT91SAM9260_PIOB_BASE 0xffff600
#define AT91SAM9260_PIOB_SIZE 0x200
#define AT91SAM9260_PIOC_BASE 0xffff800
#define AT91SAM9260_PIOC_SIZE 0x200
#define AT91RM92_PMC_BASE 0xffffc00
#define AT91RM92_PMC_SIZE 0x100
/* IRQs : */
/*
* 0: AIC
* 1: System peripheral (System timer, RTC, DBGU)
* 2: PIO Controller A
* 3: PIO Controller B
* 4: PIO Controller C
* 5: ADC
* 6: USART 0
* 7: USART 1
* 8: USART 2
* 9: MMC Interface
* 10: USB device port
* 11: Two-wire interface
* 12: SPI 0
* 13: SPI 1
* 14: SSC
* 15: - (reserved)
* 16: - (reserved)
* 17: Timer Counter 0
* 18: Timer Counter 1
* 19: Timer Counter 2
* 20: USB Host port
* 21: EMAC
* 22: ISI
* 23: USART 3
* 24: USART 4
* 25: USART 2
* 26: Timer Counter 3
* 27: Timer Counter 4
* 28: Timer Counter 5
* 29: AIC IRQ0
* 30: AIC IRQ1
* 31: AIC IRQ2
*/
#define AT91SAM9260_IRQ_SYSTEM 1
#define AT91SAM9260_IRQ_PIOA 2
#define AT91SAM9260_IRQ_PIOB 3
#define AT91SAM9260_IRQ_PIOC 4
#define AT91SAM9260_IRQ_USART0 6
#define AT91SAM9260_IRQ_USART1 7
#define AT91SAM9260_IRQ_USART2 8
#define AT91SAM9260_IRQ_MCI 9
#define AT91SAM9260_IRQ_UDP 10
#define AT91SAM9260_IRQ_TWI 11
#define AT91SAM9260_IRQ_SPI0 12
#define AT91SAM9260_IRQ_SPI1 13
#define AT91SAM9260_IRQ_SSC0 14
#define AT91SAM9260_IRQ_SSC1 15
#define AT91SAM9260_IRQ_SSC2 16
#define AT91SAM9260_IRQ_TC0 17
#define AT91SAM9260_IRQ_TC1 18
#define AT91SAM9260_IRQ_TC2 19
#define AT91SAM9260_IRQ_UHP 20
#define AT91SAM9260_IRQ_EMAC 21
#define AT91SAM9260_IRQ_USART3 23
#define AT91SAM9260_IRQ_USART4 24
#define AT91SAM9260_IRQ_USART5 25
#define AT91SAM9260_IRQ_AICBASE 29
/* Alias */
#define AT91SAM9260_IRQ_DBGU AT91SAM9260_IRQ_SYSTEM
#define AT91SAM9260_IRQ_PMC AT91SAM9260_IRQ_SYSTEM
#define AT91SAM9260_IRQ_WDT AT91SAM9260_IRQ_SYSTEM
#define AT91SAM9260_IRQ_PIT AT91SAM9260_IRQ_SYSTEM
#define AT91SAM9260_IRQ_RSTC AT91SAM9260_IRQ_SYSTEM
#define AT91SAM9260_IRQ_OHCI AT91SAM9260_IRQ_UHP
#define AT91SAM9260_IRQ_NAND (-1)
#define AT91SAM9260_IRQ_AIC (-1)
#define AT91SAM9260_AIC_BASE 0xffff000
#define AT91SAM9260_AIC_SIZE 0x200
/* Timer */
#define AT91SAM9260_WDT_BASE 0xffffd40
#define AT91SAM9260_WDT_SIZE 0x10
#define AT91SAM9260_PIT_BASE 0xffffd30
#define AT91SAM9260_PIT_SIZE 0x10
#define AT91SAM9260_SMC_BASE 0xfffec00
#define AT91SAM9260_SMC_SIZE 0x200
#define AT91SAM9260_PMC_BASE 0xffffc00
#define AT91SAM9260_PMC_SIZE 0x100
#define AT91SAM9260_UDP_BASE 0xffa4000
#define AT91SAM9260_UDP_SIZE 0x4000
#define AT91SAM9260_MCI_BASE 0xffa8000
#define AT91SAM9260_MCI_SIZE 0x4000
#define AT91SAM9260_TWI_BASE 0xffaC000
#define AT91SAM9260_TWI_SIZE 0x4000
/* XXX Needs to be carfully coordinated with
* other * soc's so phyical and vm address
* mapping are unique. XXX
*/
#define AT91SAM9260_OHCI_VA_BASE 0xdfc00000
#define AT91SAM9260_OHCI_BASE 0x00500000
#define AT91SAM9260_OHCI_SIZE 0x00100000
#define AT91SAM9260_NAND_VA_BASE 0xe0000000
#define AT91SAM9260_NAND_BASE 0x40000000
#define AT91SAM9260_NAND_SIZE 0x10000000
/* SDRAMC */
#define AT91SAM9260_SDRAMC_BASE 0xfffea00
#define AT91SAM9260_SDRAMC_MR 0x00
#define AT91SAM9260_SDRAMC_MR_MODE_NORMAL 0
#define AT91SAM9260_SDRAMC_MR_MODE_NOP 1
#define AT91SAM9260_SDRAMC_MR_MODE_PRECHARGE 2
#define AT91SAM9260_SDRAMC_MR_MODE_LOAD_MODE_REGISTER 3
#define AT91SAM9260_SDRAMC_MR_MODE_REFRESH 4
#define AT91SAM9260_SDRAMC_TR 0x04
#define AT91SAM9260_SDRAMC_CR 0x08
#define AT91SAM9260_SDRAMC_CR_NC_8 0x0
#define AT91SAM9260_SDRAMC_CR_NC_9 0x1
#define AT91SAM9260_SDRAMC_CR_NC_10 0x2
#define AT91SAM9260_SDRAMC_CR_NC_11 0x3
#define AT91SAM9260_SDRAMC_CR_NC_MASK 0x00000003
#define AT91SAM9260_SDRAMC_CR_NR_11 0x0
#define AT91SAM9260_SDRAMC_CR_NR_12 0x4
#define AT91SAM9260_SDRAMC_CR_NR_13 0x8
#define AT91SAM9260_SDRAMC_CR_NR_RES 0xc
#define AT91SAM9260_SDRAMC_CR_NR_MASK 0x0000000c
#define AT91SAM9260_SDRAMC_CR_NB_2 0x00
#define AT91SAM9260_SDRAMC_CR_NB_4 0x10
#define AT91SAM9260_SDRAMC_CR_DBW_16 0x80
#define AT91SAM9260_SDRAMC_CR_NB_MASK 0x00000010
#define AT91SAM9260_SDRAMC_CR_NCAS_MASK 0x00000060
#define AT91SAM9260_SDRAMC_CR_TWR_MASK 0x00000780
#define AT91SAM9260_SDRAMC_CR_TRC_MASK 0x00007800
#define AT91SAM9260_SDRAMC_CR_TRP_MASK 0x00078000
#define AT91SAM9260_SDRAMC_CR_TRCD_MASK 0x00780000
#define AT91SAM9260_SDRAMC_CR_TRAS_MASK 0x07800000
#define AT91SAM9260_SDRAMC_CR_TXSR_MASK 0x78000000
#define AT91SAM9260_SDRAMC_HSR 0x0c
#define AT91SAM9260_SDRAMC_LPR 0x10
#define AT91SAM9260_SDRAMC_IER 0x14
#define AT91SAM9260_SDRAMC_IDR 0x18
#define AT91SAM9260_SDRAMC_IMR 0x1c
#define AT91SAM9260_SDRAMC_ISR 0x20
#define AT91SAM9260_SDRAMC_MDR 0x24
#endif /* AT91SAM9260REG_H_*/

View File

@ -1,185 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2005 Olivier Houchard. All rights reserved.
* Copyright (c) 2010 Greg Ansley. 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/bus.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
#define _ARM32_BUS_DMA_PRIVATE
#include <machine/bus.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91reg.h>
#include <arm/at91/at91soc.h>
#include <arm/at91/at91_aicreg.h>
#include <arm/at91/at91sam9g20reg.h>
#include <arm/at91/at91_pitreg.h>
#include <arm/at91/at91_pmcreg.h>
#include <arm/at91/at91_pmcvar.h>
#include <arm/at91/at91_rstreg.h>
/*
* Standard priority levels for the system. 0 is lowest and 7 is highest.
* These values are the ones Atmel uses for its Linux port
*/
static const int at91_irq_prio[32] =
{
7, /* Advanced Interrupt Controller */
7, /* System Peripherals */
1, /* Parallel IO Controller A */
1, /* Parallel IO Controller B */
1, /* Parallel IO Controller C */
0, /* Analog-to-Digital Converter */
5, /* USART 0 */
5, /* USART 1 */
5, /* USART 2 */
0, /* Multimedia Card Interface */
2, /* USB Device Port */
6, /* Two-Wire Interface */
5, /* Serial Peripheral Interface 0 */
5, /* Serial Peripheral Interface 1 */
5, /* Serial Synchronous Controller */
0, /* (reserved) */
0, /* (reserved) */
0, /* Timer Counter 0 */
0, /* Timer Counter 1 */
0, /* Timer Counter 2 */
2, /* USB Host port */
3, /* Ethernet */
0, /* Image Sensor Interface */
5, /* USART 3 */
5, /* USART 4 */
5, /* USART 5 */
0, /* Timer Counter 3 */
0, /* Timer Counter 4 */
0, /* Timer Counter 5 */
0, /* Advanced Interrupt Controller IRQ0 */
0, /* Advanced Interrupt Controller IRQ1 */
0, /* Advanced Interrupt Controller IRQ2 */
};
static const uint32_t at91_pio_base[] = {
AT91SAM9G20_PIOA_BASE,
AT91SAM9G20_PIOB_BASE,
AT91SAM9G20_PIOC_BASE,
};
#define DEVICE(_name, _id, _unit) \
{ \
_name, _unit, \
AT91SAM9G20_ ## _id ##_BASE, \
AT91SAM9G20_ ## _id ## _SIZE, \
AT91SAM9G20_IRQ_ ## _id \
}
static const struct cpu_devs at91_devs[] =
{
DEVICE("at91_aic", AIC, 0),
DEVICE("at91_pmc", PMC, 0),
DEVICE("at91_wdt", WDT, 0),
DEVICE("at91_rst", RSTC, 0),
DEVICE("at91_pit", PIT, 0),
DEVICE("at91_pio", PIOA, 0),
DEVICE("at91_pio", PIOB, 1),
DEVICE("at91_pio", PIOC, 2),
DEVICE("at91_twi", TWI, 0),
DEVICE("at91_mci", MCI, 0),
DEVICE("uart", DBGU, 0),
DEVICE("uart", USART0, 1),
DEVICE("uart", USART1, 2),
DEVICE("uart", USART2, 3),
DEVICE("uart", USART3, 4),
DEVICE("uart", USART4, 5),
DEVICE("uart", USART5, 6),
DEVICE("spi", SPI0, 0),
DEVICE("spi", SPI1, 1),
DEVICE("ate", EMAC, 0),
DEVICE("macb", EMAC, 0),
DEVICE("nand", NAND, 0),
DEVICE("ohci", OHCI, 0),
{ 0, 0, 0, 0, 0 }
};
static void
at91_clock_init(void)
{
struct at91_pmc_clock *clk;
/* Update USB device port clock info */
clk = at91_pmc_clock_ref("udpck");
clk->pmc_mask = PMC_SCER_UDP_SAM9;
at91_pmc_clock_deref(clk);
/* Update USB host port clock info */
clk = at91_pmc_clock_ref("uhpck");
clk->pmc_mask = PMC_SCER_UHP_SAM9;
at91_pmc_clock_deref(clk);
/* Each SOC has different PLL contraints */
clk = at91_pmc_clock_ref("plla");
clk->pll_min_in = SAM9G20_PLL_A_MIN_IN_FREQ; /* 2 MHz */
clk->pll_max_in = SAM9G20_PLL_A_MAX_IN_FREQ; /* 32 MHz */
clk->pll_min_out = SAM9G20_PLL_A_MIN_OUT_FREQ; /* 400 MHz */
clk->pll_max_out = SAM9G20_PLL_A_MAX_OUT_FREQ; /* 800 MHz */
clk->pll_mul_shift = SAM9G20_PLL_A_MUL_SHIFT;
clk->pll_mul_mask = SAM9G20_PLL_A_MUL_MASK;
clk->pll_div_shift = SAM9G20_PLL_A_DIV_SHIFT;
clk->pll_div_mask = SAM9G20_PLL_A_DIV_MASK;
clk->set_outb = at91_pmc_800mhz_plla_outb;
at91_pmc_clock_deref(clk);
clk = at91_pmc_clock_ref("pllb");
clk->pll_min_in = SAM9G20_PLL_B_MIN_IN_FREQ; /* 2 MHz */
clk->pll_max_in = SAM9G20_PLL_B_MAX_IN_FREQ; /* 32 MHz */
clk->pll_min_out = SAM9G20_PLL_B_MIN_OUT_FREQ; /* 30 MHz */
clk->pll_max_out = SAM9G20_PLL_B_MAX_OUT_FREQ; /* 100 MHz */
clk->pll_mul_shift = SAM9G20_PLL_B_MUL_SHIFT;
clk->pll_mul_mask = SAM9G20_PLL_B_MUL_MASK;
clk->pll_div_shift = SAM9G20_PLL_B_DIV_SHIFT;
clk->pll_div_mask = SAM9G20_PLL_B_DIV_MASK;
clk->set_outb = at91_pmc_800mhz_pllb_outb;
at91_pmc_clock_deref(clk);
}
static struct at91_soc_data soc_data = {
.soc_delay = at91_pit_delay,
.soc_reset = at91_rst_cpu_reset,
.soc_clock_init = at91_clock_init,
.soc_irq_prio = at91_irq_prio,
.soc_children = at91_devs,
.soc_pio_base = at91_pio_base,
.soc_pio_count = nitems(at91_pio_base),
};
AT91_SOC(AT91_T_SAM9G20, &soc_data);

View File

@ -1,306 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2009 Sylvestre Gallon. All rights reserved.
* Copyright (c) 2010 Greg Ansley. 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 AT91SAM9G20REG_H_
#define AT91SAM9G20REG_H_
/* Chip Specific limits */
#define SAM9G20_PLL_A_MIN_IN_FREQ 2000000 /* 2 Mhz */
#define SAM9G20_PLL_A_MAX_IN_FREQ 32000000 /* 32 Mhz */
#define SAM9G20_PLL_A_MIN_OUT_FREQ 400000000 /* 400 Mhz */
#define SAM9G20_PLL_A_MAX_OUT_FREQ 800000000 /* 800 Mhz */
#define SAM9G20_PLL_A_MUL_SHIFT 16
#define SAM9G20_PLL_A_MUL_MASK 0xFF
#define SAM9G20_PLL_A_DIV_SHIFT 0
#define SAM9G20_PLL_A_DIV_MASK 0xFF
#define SAM9G20_PLL_B_MIN_IN_FREQ 2000000 /* 2 Mhz */
#define SAM9G20_PLL_B_MAX_IN_FREQ 32000000 /* 32 Mhz */
#define SAM9G20_PLL_B_MIN_OUT_FREQ 30000000 /* 30 Mhz */
#define SAM9G20_PLL_B_MAX_OUT_FREQ 100000000 /* 100 Mhz */
#define SAM9G20_PLL_B_MUL_SHIFT 16
#define SAM9G20_PLL_B_MUL_MASK 0x3F
#define SAM9G20_PLL_B_DIV_SHIFT 0
#define SAM9G20_PLL_B_DIV_MASK 0xFF
/*
* Memory map, from datasheet :
* 0x00000000 - 0x0ffffffff : Internal Memories
* 0x10000000 - 0x1ffffffff : Chip Select 0
* 0x20000000 - 0x2ffffffff : Chip Select 1
* 0x30000000 - 0x3ffffffff : Chip Select 2
* 0x40000000 - 0x4ffffffff : Chip Select 3
* 0x50000000 - 0x5ffffffff : Chip Select 4
* 0x60000000 - 0x6ffffffff : Chip Select 5
* 0x70000000 - 0x7ffffffff : Chip Select 6
* 0x80000000 - 0x8ffffffff : Chip Select 7
* 0x90000000 - 0xeffffffff : Undefined (Abort)
* 0xf0000000 - 0xfffffffff : Peripherals
*/
#define AT91_CHIPSELECT_0 0x10000000
#define AT91_CHIPSELECT_1 0x20000000
#define AT91_CHIPSELECT_2 0x30000000
#define AT91_CHIPSELECT_3 0x40000000
#define AT91_CHIPSELECT_4 0x50000000
#define AT91_CHIPSELECT_5 0x60000000
#define AT91_CHIPSELECT_6 0x70000000
#define AT91_CHIPSELECT_7 0x80000000
#define AT91SAM9G20_EMAC_BASE 0xffc4000
#define AT91SAM9G20_EMAC_SIZE 0x4000
#define AT91SAM9G20_RSTC_BASE 0xffffd00
#define AT91SAM9G20_RSTC_SIZE 0x10
#define RSTC_CR 0
#define RSTC_PROCRST (1 << 0)
#define RSTC_PERRST (1 << 2)
#define RSTC_KEY (0xa5 << 24)
/* USART*/
#define AT91SAM9G20_USART_SIZE 0x4000
#define AT91SAM9G20_USART0_BASE 0xffb0000
#define AT91SAM9G20_USART0_PDC 0xffb0100
#define AT91SAM9G20_USART0_SIZE AT91SAM9G20_USART_SIZE
#define AT91SAM9G20_USART1_BASE 0xffb4000
#define AT91SAM9G20_USART1_PDC 0xffb4100
#define AT91SAM9G20_USART1_SIZE AT91SAM9G20_USART_SIZE
#define AT91SAM9G20_USART2_BASE 0xffb8000
#define AT91SAM9G20_USART2_PDC 0xffb8100
#define AT91SAM9G20_USART2_SIZE AT91SAM9G20_USART_SIZE
#define AT91SAM9G20_USART3_BASE 0xffd0000
#define AT91SAM9G20_USART3_PDC 0xffd0100
#define AT91SAM9G20_USART3_SIZE AT91SAM9G20_USART_SIZE
#define AT91SAM9G20_USART4_BASE 0xffd4000
#define AT91SAM9G20_USART4_PDC 0xffd4100
#define AT91SAM9G20_USART4_SIZE AT91SAM9G20_USART_SIZE
#define AT91SAM9G20_USART5_BASE 0xffd8000
#define AT91SAM9G20_USART5_PDC 0xffd8100
#define AT91SAM9G20_USART5_SIZE AT91SAM9G20_USART_SIZE
/*TC*/
#define AT91SAM9G20_TC0_BASE 0xffa0000
#define AT91SAM9G20_TC0_SIZE 0x4000
#define AT91SAM9G20_TC0C0_BASE 0xffa0000
#define AT91SAM9G20_TC0C1_BASE 0xffa0040
#define AT91SAM9G20_TC0C2_BASE 0xffa0080
#define AT91SAM9G20_TC1_BASE 0xffdc000
#define AT91SAM9G20_TC1_SIZE 0x4000
/*SPI*/
#define AT91SAM9G20_SPI0_BASE 0xffc8000
#define AT91SAM9G20_SPI0_SIZE 0x4000
#define AT91SAM9G20_IRQ_SPI0 12
#define AT91SAM9G20_SPI1_BASE 0xffcc000
#define AT91SAM9G20_SPI1_SIZE 0x4000
#define AT91SAM9G20_IRQ_SPI1 13
/* System Registers */
#define AT91SAM9G20_SYS_BASE 0xffff000
#define AT91SAM9G20_SYS_SIZE 0x1000
#define AT91SAM9G20_MATRIX_BASE 0xfffee00
#define AT91SAM9G20_MATRIX_SIZE 0x1000
#define AT91SAM9G20_EBICSA 0x011C
#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3)
#define AT91SAM9G20_DBGU_BASE 0xffff200
#define AT91SAM9G20_DBGU_SIZE 0x200
/*
* PIO
*/
#define AT91SAM9G20_PIOA_BASE 0xffff400
#define AT91SAM9G20_PIOA_SIZE 0x200
#define AT91SAM9G20_PIOB_BASE 0xffff600
#define AT91SAM9G20_PIOB_SIZE 0x200
#define AT91SAM9G20_PIOC_BASE 0xffff800
#define AT91SAM9G20_PIOC_SIZE 0x200
#define AT91RM92_PMC_BASE 0xffffc00
#define AT91RM92_PMC_SIZE 0x100
/* IRQs : */
/*
* 0: AIC
* 1: System peripheral (System timer, RTC, DBGU)
* 2: PIO Controller A
* 3: PIO Controller B
* 4: PIO Controller C
* 5: ADC
* 6: USART 0
* 7: USART 1
* 8: USART 2
* 9: MMC Interface
* 10: USB device port
* 11: Two-wire interface
* 12: SPI 0
* 13: SPI 1
* 14: SSC
* 15: - (reserved)
* 16: - (reserved)
* 17: Timer Counter 0
* 18: Timer Counter 1
* 19: Timer Counter 2
* 20: USB Host port
* 21: EMAC
* 22: ISI
* 23: USART 3
* 24: USART 4
* 25: USART 2
* 26: Timer Counter 3
* 27: Timer Counter 4
* 28: Timer Counter 5
* 29: AIC IRQ0
* 30: AIC IRQ1
* 31: AIC IRQ2
*/
#define AT91SAM9G20_IRQ_SYSTEM 1
#define AT91SAM9G20_IRQ_PIOA 2
#define AT91SAM9G20_IRQ_PIOB 3
#define AT91SAM9G20_IRQ_PIOC 4
#define AT91SAM9G20_IRQ_USART0 6
#define AT91SAM9G20_IRQ_USART1 7
#define AT91SAM9G20_IRQ_USART2 8
#define AT91SAM9G20_IRQ_MCI 9
#define AT91SAM9G20_IRQ_UDP 10
#define AT91SAM9G20_IRQ_TWI 11
#define AT91SAM9G20_IRQ_SPI0 12
#define AT91SAM9G20_IRQ_SPI1 13
#define AT91SAM9G20_IRQ_SSC0 14
#define AT91SAM9G20_IRQ_SSC1 15
#define AT91SAM9G20_IRQ_SSC2 16
#define AT91SAM9G20_IRQ_TC0 17
#define AT91SAM9G20_IRQ_TC1 18
#define AT91SAM9G20_IRQ_TC2 19
#define AT91SAM9G20_IRQ_UHP 20
#define AT91SAM9G20_IRQ_EMAC 21
#define AT91SAM9G20_IRQ_USART3 23
#define AT91SAM9G20_IRQ_USART4 24
#define AT91SAM9G20_IRQ_USART5 25
#define AT91SAM9G20_IRQ_AICBASE 29
/* Alias */
#define AT91SAM9G20_IRQ_DBGU AT91SAM9G20_IRQ_SYSTEM
#define AT91SAM9G20_IRQ_PMC AT91SAM9G20_IRQ_SYSTEM
#define AT91SAM9G20_IRQ_WDT AT91SAM9G20_IRQ_SYSTEM
#define AT91SAM9G20_IRQ_PIT AT91SAM9G20_IRQ_SYSTEM
#define AT91SAM9G20_IRQ_RSTC AT91SAM9G20_IRQ_SYSTEM
#define AT91SAM9G20_IRQ_OHCI AT91SAM9G20_IRQ_UHP
#define AT91SAM9G20_IRQ_NAND (-1)
#define AT91SAM9G20_IRQ_AIC (-1)
#define AT91SAM9G20_AIC_BASE 0xffff000
#define AT91SAM9G20_AIC_SIZE 0x200
/* Timer */
#define AT91SAM9G20_WDT_BASE 0xffffd40
#define AT91SAM9G20_WDT_SIZE 0x10
#define AT91SAM9G20_PIT_BASE 0xffffd30
#define AT91SAM9G20_PIT_SIZE 0x10
#define AT91SAM9G20_SMC_BASE 0xfffec00
#define AT91SAM9G20_SMC_SIZE 0x200
#define AT91SAM9G20_PMC_BASE 0xffffc00
#define AT91SAM9G20_PMC_SIZE 0x100
#define AT91SAM9G20_UDP_BASE 0xffa4000
#define AT91SAM9G20_UDP_SIZE 0x4000
#define AT91SAM9G20_MCI_BASE 0xffa8000
#define AT91SAM9G20_MCI_SIZE 0x4000
#define AT91SAM9G20_TWI_BASE 0xffaC000
#define AT91SAM9G20_TWI_SIZE 0x4000
/* XXX Needs to be carfully coordinated with
* other * soc's so phyical and vm address
* mapping are unique. XXX
*/
#define AT91SAM9G20_OHCI_VA_BASE 0xdfc00000
#define AT91SAM9G20_OHCI_BASE 0x00500000
#define AT91SAM9G20_OHCI_SIZE 0x00100000
#define AT91SAM9G20_NAND_VA_BASE 0xe0000000
#define AT91SAM9G20_NAND_BASE 0x40000000
#define AT91SAM9G20_NAND_SIZE 0x10000000
/* SDRAMC */
#define AT91SAM9G20_SDRAMC_BASE 0xfffea00
#define AT91SAM9G20_SDRAMC_MR 0x00
#define AT91SAM9G20_SDRAMC_MR_MODE_NORMAL 0
#define AT91SAM9G20_SDRAMC_MR_MODE_NOP 1
#define AT91SAM9G20_SDRAMC_MR_MODE_PRECHARGE 2
#define AT91SAM9G20_SDRAMC_MR_MODE_LOAD_MODE_REGISTER 3
#define AT91SAM9G20_SDRAMC_MR_MODE_REFRESH 4
#define AT91SAM9G20_SDRAMC_TR 0x04
#define AT91SAM9G20_SDRAMC_CR 0x08
#define AT91SAM9G20_SDRAMC_CR_NC_8 0x0
#define AT91SAM9G20_SDRAMC_CR_NC_9 0x1
#define AT91SAM9G20_SDRAMC_CR_NC_10 0x2
#define AT91SAM9G20_SDRAMC_CR_NC_11 0x3
#define AT91SAM9G20_SDRAMC_CR_NC_MASK 0x00000003
#define AT91SAM9G20_SDRAMC_CR_NR_11 0x0
#define AT91SAM9G20_SDRAMC_CR_NR_12 0x4
#define AT91SAM9G20_SDRAMC_CR_NR_13 0x8
#define AT91SAM9G20_SDRAMC_CR_NR_RES 0xc
#define AT91SAM9G20_SDRAMC_CR_NR_MASK 0x0000000c
#define AT91SAM9G20_SDRAMC_CR_NB_2 0x00
#define AT91SAM9G20_SDRAMC_CR_NB_4 0x10
#define AT91SAM9G20_SDRAMC_CR_DBW_16 0x80
#define AT91SAM9G20_SDRAMC_CR_NB_MASK 0x00000010
#define AT91SAM9G20_SDRAMC_CR_NCAS_MASK 0x00000060
#define AT91SAM9G20_SDRAMC_CR_TWR_MASK 0x00000780
#define AT91SAM9G20_SDRAMC_CR_TRC_MASK 0x00007800
#define AT91SAM9G20_SDRAMC_CR_TRP_MASK 0x00078000
#define AT91SAM9G20_SDRAMC_CR_TRCD_MASK 0x00780000
#define AT91SAM9G20_SDRAMC_CR_TRAS_MASK 0x07800000
#define AT91SAM9G20_SDRAMC_CR_TXSR_MASK 0x78000000
#define AT91SAM9G20_SDRAMC_HSR 0x0c
#define AT91SAM9G20_SDRAMC_LPR 0x10
#define AT91SAM9G20_SDRAMC_IER 0x14
#define AT91SAM9G20_SDRAMC_IDR 0x18
#define AT91SAM9G20_SDRAMC_IMR 0x1c
#define AT91SAM9G20_SDRAMC_ISR 0x20
#define AT91SAM9G20_SDRAMC_MDR 0x24
#endif /* AT91SAM9G20REG_H_*/

View File

@ -1,172 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2005 Olivier Houchard. All rights reserved.
* Copyright (c) 2010 Greg Ansley. All rights reserved.
* Copyright (c) 2012 Andrew Turner. 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/bus.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
#define _ARM32_BUS_DMA_PRIVATE
#include <machine/bus.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91reg.h>
#include <arm/at91/at91soc.h>
#include <arm/at91/at91_aicreg.h>
#include <arm/at91/at91sam9g45reg.h>
#include <arm/at91/at91_pitreg.h>
#include <arm/at91/at91_pmcreg.h>
#include <arm/at91/at91_pmcvar.h>
#include <arm/at91/at91_rstreg.h>
/*
* Standard priority levels for the system. 0 is lowest and 7 is highest.
* These values are the ones Atmel uses for its Linux port
*/
static const int at91_irq_prio[32] =
{
7, /* Advanced Interrupt Controller */
7, /* System Peripherals */
1, /* Parallel IO Controller A */
1, /* Parallel IO Controller B */
1, /* Parallel IO Controller C */
1, /* Parallel IO Controller D and E */
0,
5, /* USART 0 */
5, /* USART 1 */
5, /* USART 2 */
5, /* USART 3 */
0, /* Multimedia Card Interface 0 */
6, /* Two-Wire Interface 0 */
6, /* Two-Wire Interface 1 */
5, /* Serial Peripheral Interface 0 */
5, /* Serial Peripheral Interface 1 */
4, /* Serial Synchronous Controller 0 */
4, /* Serial Synchronous Controller 1 */
0, /* Timer Counter 0, 1, 2, 3, 4 and 5 */
0, /* Pulse Width Modulation Controller */
0, /* Touch Screen Controller */
0, /* DMA Controller */
2, /* USB Host High Speed port */
3, /* LCD Controller */
5, /* AC97 Controller */
3, /* Ethernet */
0, /* Image Sensor Interface */
2, /* USB Device High Speed port */
0, /* (reserved) */
0, /* Multimedia Card Interface 1 */
0, /* (reserved) */
0, /* Advanced Interrupt Controller IRQ0 */
};
static const uint32_t at91_pio_base[] = {
AT91SAM9G45_PIOA_BASE,
AT91SAM9G45_PIOB_BASE,
AT91SAM9G45_PIOC_BASE,
AT91SAM9G45_PIOD_BASE,
AT91SAM9G45_PIOE_BASE,
};
#define DEVICE(_name, _id, _unit) \
{ \
_name, _unit, \
AT91SAM9G45_ ## _id ##_BASE, \
AT91SAM9G45_ ## _id ## _SIZE, \
AT91SAM9G45_IRQ_ ## _id \
}
static const struct cpu_devs at91_devs[] =
{
DEVICE("at91_pmc", PMC, 0),
DEVICE("at91_wdt", WDT, 0),
DEVICE("at91_rst", RSTC, 0),
DEVICE("at91_pit", PIT, 0),
DEVICE("at91_pio", PIOA, 0),
DEVICE("at91_pio", PIOB, 1),
DEVICE("at91_pio", PIOC, 2),
DEVICE("at91_pio", PIOD, 3),
DEVICE("at91_pio", PIOE, 4),
DEVICE("at91_twi", TWI0, 0),
DEVICE("at91_twi", TWI1, 1),
DEVICE("at91_mci", HSMCI0, 0),
DEVICE("at91_mci", HSMCI1, 1),
DEVICE("uart", DBGU, 0),
DEVICE("uart", USART0, 1),
DEVICE("uart", USART1, 2),
DEVICE("uart", USART2, 3),
DEVICE("uart", USART3, 4),
DEVICE("spi", SPI0, 0),
DEVICE("spi", SPI1, 1),
DEVICE("ate", EMAC, 0),
DEVICE("macb", EMAC, 0),
DEVICE("nand", NAND, 0),
DEVICE("ohci", OHCI, 0),
{ 0, 0, 0, 0, 0 }
};
static void
at91_clock_init(void)
{
struct at91_pmc_clock *clk;
/* Update USB host port clock info */
clk = at91_pmc_clock_ref("uhpck");
clk->pmc_mask = PMC_SCER_UHP_SAM9;
at91_pmc_clock_deref(clk);
/* Each SOC has different PLL contraints */
clk = at91_pmc_clock_ref("plla");
clk->pll_min_in = SAM9G45_PLL_A_MIN_IN_FREQ; /* 2 MHz */
clk->pll_max_in = SAM9G45_PLL_A_MAX_IN_FREQ; /* 32 MHz */
clk->pll_min_out = SAM9G45_PLL_A_MIN_OUT_FREQ; /* 400 MHz */
clk->pll_max_out = SAM9G45_PLL_A_MAX_OUT_FREQ; /* 800 MHz */
clk->pll_mul_shift = SAM9G45_PLL_A_MUL_SHIFT;
clk->pll_mul_mask = SAM9G45_PLL_A_MUL_MASK;
clk->pll_div_shift = SAM9G45_PLL_A_DIV_SHIFT;
clk->pll_div_mask = SAM9G45_PLL_A_DIV_MASK;
clk->set_outb = at91_pmc_800mhz_plla_outb;
at91_pmc_clock_deref(clk);
}
static struct at91_soc_data soc_data = {
.soc_delay = at91_pit_delay,
.soc_reset = at91_rst_cpu_reset,
.soc_clock_init = at91_clock_init,
.soc_irq_prio = at91_irq_prio,
.soc_children = at91_devs,
.soc_pio_base = at91_pio_base,
.soc_pio_count = nitems(at91_pio_base),
};
AT91_SOC(AT91_T_SAM9G45, &soc_data);

View File

@ -1,295 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2009 Sylvestre Gallon. All rights reserved.
* Copyright (c) 2010 Greg Ansley. All rights reserved.
* Copyright (c) 2012 Andrew Turner. 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 AT91SAM9G45REG_H_
#define AT91SAM9G45REG_H_
/* Chip Specific limits */
#define SAM9G45_PLL_A_MIN_IN_FREQ 2000000 /* 2 Mhz */
#define SAM9G45_PLL_A_MAX_IN_FREQ 32000000 /* 32 Mhz */
#define SAM9G45_PLL_A_MIN_OUT_FREQ 400000000 /* 400 Mhz */
#define SAM9G45_PLL_A_MAX_OUT_FREQ 800000000 /* 800 Mhz */
#define SAM9G45_PLL_A_MUL_SHIFT 16
#define SAM9G45_PLL_A_MUL_MASK 0xFF
#define SAM9G45_PLL_A_DIV_SHIFT 0
#define SAM9G45_PLL_A_DIV_MASK 0xFF
/*
* Memory map, from datasheet :
* 0x00000000 - 0x0ffffffff : Internal Memories
* 0x10000000 - 0x1ffffffff : Chip Select 0
* 0x20000000 - 0x2ffffffff : Chip Select 1
* 0x30000000 - 0x3ffffffff : Chip Select 2
* 0x40000000 - 0x4ffffffff : Chip Select 3
* 0x50000000 - 0x5ffffffff : Chip Select 4
* 0x60000000 - 0x6ffffffff : Chip Select 5
* 0x70000000 - 0x7ffffffff : DDR SDRC 0
* 0x80000000 - 0xeffffffff : Undefined (Abort)
* 0xf0000000 - 0xfffffffff : Peripherals
*/
#define AT91_CHIPSELECT_0 0x10000000
#define AT91_CHIPSELECT_1 0x20000000
#define AT91_CHIPSELECT_2 0x30000000
#define AT91_CHIPSELECT_3 0x40000000
#define AT91_CHIPSELECT_4 0x50000000
#define AT91_CHIPSELECT_5 0x60000000
#define AT91SAM9G45_EMAC_BASE 0xffbc000
#define AT91SAM9G45_EMAC_SIZE 0x4000
#define AT91SAM9G45_RSTC_BASE 0xffffd00
#define AT91SAM9G45_RSTC_SIZE 0x10
/* USART*/
#define AT91SAM9G45_USART_SIZE 0x4000
#define AT91SAM9G45_USART0_BASE 0xff8c000
#define AT91SAM9G45_USART0_SIZE AT91SAM9G45_USART_SIZE
#define AT91SAM9G45_USART1_BASE 0xff90000
#define AT91SAM9G45_USART1_SIZE AT91SAM9G45_USART_SIZE
#define AT91SAM9G45_USART2_BASE 0xff94000
#define AT91SAM9G45_USART2_SIZE AT91SAM9G45_USART_SIZE
#define AT91SAM9G45_USART3_BASE 0xff98000
#define AT91SAM9G45_USART3_SIZE AT91SAM9G45_USART_SIZE
/*TC*/
#define AT91SAM9G45_TC0_BASE 0xff7c000
#define AT91SAM9G45_TC0_SIZE 0x4000
#define AT91SAM9G45_TC0C0_BASE 0xff7c000
#define AT91SAM9G45_TC0C1_BASE 0xff7c040
#define AT91SAM9G45_TC0C2_BASE 0xff7c080
#define AT91SAM9G45_TC1_BASE 0xffd4000
#define AT91SAM9G45_TC1_SIZE 0x4000
#define AT91SAM9G45_TC1C0_BASE 0xffd4000
#define AT91SAM9G45_TC1C1_BASE 0xffd4040
#define AT91SAM9G45_TC1C2_BASE 0xffd4080
/*SPI*/
#define AT91SAM9G45_SPI0_BASE 0xffa48000
#define AT91SAM9G45_SPI0_SIZE 0x4000
#define AT91SAM9G45_SPI1_BASE 0xffa8000
#define AT91SAM9G45_SPI1_SIZE 0x4000
/* System Registers */
#define AT91SAM9G45_SYS_BASE 0xffff000
#define AT91SAM9G45_SYS_SIZE 0x1000
#define AT91SAM9G45_MATRIX_BASE 0xfffea00
#define AT91SAM9G45_MATRIX_SIZE 0x200
#define AT91SAM9G45_DBGU_BASE 0xfffee00
#define AT91SAM9G45_DBGU_SIZE 0x200
/*
* PIO
*/
#define AT91SAM9G45_PIOA_BASE 0xffff200
#define AT91SAM9G45_PIOA_SIZE 0x200
#define AT91SAM9G45_PIOB_BASE 0xffff400
#define AT91SAM9G45_PIOB_SIZE 0x200
#define AT91SAM9G45_PIOC_BASE 0xffff600
#define AT91SAM9G45_PIOC_SIZE 0x200
#define AT91SAM9G45_PIOD_BASE 0xffff800
#define AT91SAM9G45_PIOD_SIZE 0x200
#define AT91SAM9G45_PIOE_BASE 0xffffa00
#define AT91SAM9G45_PIOE_SIZE 0x200
#define AT91SAM9G45_PMC_BASE 0xffffc00
#define AT91SAM9G45_PMC_SIZE 0x100
/* IRQs : */
/*
* 0: AIC
* 1: System peripheral (System timer, RTC, DBGU)
* 2: PIO Controller A
* 3: PIO Controller B
* 4: PIO Controller C
* 5: PIO Controller D/E
* 6: TRNG
* 7: USART 0
* 8: USART 1
* 9: USART 2
* 10: USART 3
* 11: Multimedia Card interface 0
* 12: Two-wire interface 0
* 13: Two-wire interface 1
* 14: SPI 0
* 15: SPI 1
* 16: SSC 0
* 17: SSC 1
* 18: Timer Counter 0, 1, 2, 3, 4, 5
* 19: PWM
* 20: Touch Screen ADC
* 21: DMA
* 22: USB Host port
* 23: LCD
* 24: AC97
* 25: EMAC
* 26: Image Sensor Interface
* 27: USB Device High Speed
* 28: -
* 29: Multimedia Card interface 1
* 30: Reserved
* 31: AIC
*/
#define AT91SAM9G45_IRQ_SYSTEM 1
#define AT91SAM9G45_IRQ_PIOA 2
#define AT91SAM9G45_IRQ_PIOB 3
#define AT91SAM9G45_IRQ_PIOC 4
#define AT91SAM9G45_IRQ_PIODE 5
#define AT91SAM9G45_IRQ_TRNG 6
#define AT91SAM9G45_IRQ_USART0 7
#define AT91SAM9G45_IRQ_USART1 8
#define AT91SAM9G45_IRQ_USART2 9
#define AT91SAM9G45_IRQ_USART3 10
#define AT91SAM9G45_IRQ_HSMCI0 11
#define AT91SAM9G45_IRQ_TWI0 12
#define AT91SAM9G45_IRQ_TWI1 13
#define AT91SAM9G45_IRQ_SPI0 14
#define AT91SAM9G45_IRQ_SPI1 15
#define AT91SAM9G45_IRQ_SSC0 16
#define AT91SAM9G45_IRQ_SSC1 17
#define AT91SAM9G45_IRQ_TC0_TC5 18
#define AT91SAM9G45_IRQ_PWM 19
#define AT91SAM9G45_IRQ_TSADCC 20
#define AT91SAM9G45_IRQ_DMA 21
#define AT91SAM9G45_IRQ_UHP 22
#define AT91SAM9G45_IRQ_LCDC 23
#define AT91SAM9G45_IRQ_AC97C 24
#define AT91SAM9G45_IRQ_EMAC 25
#define AT91SAM9G45_IRQ_ISI 26
#define AT91SAM9G45_IRQ_UDPHS 27
/* Reserved 28 */
#define AT91SAM9G45_IRQ_HSMCI1 29
/* Reserved 30 */
#define AT91SAM9G45_IRQ_AICBASE 31
/* Alias */
#define AT91SAM9G45_IRQ_DBGU AT91SAM9G45_IRQ_SYSTEM
#define AT91SAM9G45_IRQ_PMC AT91SAM9G45_IRQ_SYSTEM
#define AT91SAM9G45_IRQ_WDT AT91SAM9G45_IRQ_SYSTEM
#define AT91SAM9G45_IRQ_PIT AT91SAM9G45_IRQ_SYSTEM
#define AT91SAM9G45_IRQ_RSTC AT91SAM9G45_IRQ_SYSTEM
#define AT91SAM9G45_IRQ_PIOD AT91SAM9G45_IRQ_PIODE
#define AT91SAM9G45_IRQ_PIOE AT91SAM9G45_IRQ_PIODE
#define AT91SAM9G45_IRQ_OHCI AT91SAM9G45_IRQ_UHP
#define AT91SAM9G45_IRQ_TC0 AT91SAM9G45_IRQ_TC0_TC5
#define AT91SAM9G45_IRQ_TC1 AT91SAM9G45_IRQ_TC0_TC5
#define AT91SAM9G45_IRQ_TC2 AT91SAM9G45_IRQ_TC0_TC5
#define AT91SAM9G45_IRQ_TC3 AT91SAM9G45_IRQ_TC0_TC5
#define AT91SAM9G45_IRQ_TC4 AT91SAM9G45_IRQ_TC0_TC5
#define AT91SAM9G45_IRQ_TC5 AT91SAM9G45_IRQ_TC0_TC5
#define AT91SAM9G45_IRQ_NAND (-1)
#define AT91SAM9G45_AIC_BASE 0xffff000
#define AT91SAM9G45_AIC_SIZE 0x200
/* Timer */
#define AT91SAM9G45_WDT_BASE 0xffffd40
#define AT91SAM9G45_WDT_SIZE 0x10
#define AT91SAM9G45_PIT_BASE 0xffffd30
#define AT91SAM9G45_PIT_SIZE 0x10
#define AT91SAM9G45_SMC_BASE 0xfffe800
#define AT91SAM9G45_SMC_SIZE 0x200
#define AT91SAM9G45_HSMCI0_BASE 0xff80000
#define AT91SAM9G45_HSMCI0_SIZE 0x4000
#define AT91SAM9G45_HSMCI1_BASE 0xffd0000
#define AT91SAM9G45_HSMCI1_SIZE 0x4000
#define AT91SAM9G45_TWI0_BASE 0xff84000
#define AT91SAM9G45_TWI0_SIZE 0x4000
#define AT91SAM9G45_TWI1_BASE 0xff88000
#define AT91SAM9G45_TWI1_SIZE 0x4000
/* XXX Needs to be carfully coordinated with
* other * soc's so phyical and vm address
* mapping are unique. XXX
*/
#define AT91SAM9G45_OHCI_VA_BASE 0xdfb00000
#define AT91SAM9G45_OHCI_BASE 0x00700000
#define AT91SAM9G45_OHCI_SIZE 0x00100000
#define AT91SAM9G45_NAND_VA_BASE 0xe0000000
#define AT91SAM9G45_NAND_BASE 0x40000000
#define AT91SAM9G45_NAND_SIZE 0x10000000
/* DDRSDRC */
#define AT91SAM9G45_DDRSDRC1_BASE 0xfffea00
#define AT91SAM9G45_DDRSDRC0_BASE 0xfffe600
#define AT91SAM9G45_DDRSDRC_MR 0x00
#define AT91SAM9G45_DDRSDRC_TR 0x04
#define AT91SAM9G45_DDRSDRC_CR 0x08
#define AT91SAM9G45_DDRSDRC_CR_NC_8 0x0
#define AT91SAM9G45_DDRSDRC_CR_NC_9 0x1
#define AT91SAM9G45_DDRSDRC_CR_NC_10 0x2
#define AT91SAM9G45_DDRSDRC_CR_NC_11 0x3
#define AT91SAM9G45_DDRSDRC_CR_NC_MASK 0x00000003
#define AT91SAM9G45_DDRSDRC_CR_NR_11 0x0
#define AT91SAM9G45_DDRSDRC_CR_NR_12 0x4
#define AT91SAM9G45_DDRSDRC_CR_NR_13 0x8
#define AT91SAM9G45_DDRSDRC_CR_NR_14 0xc
#define AT91SAM9G45_DDRSDRC_CR_NR_MASK 0x0000000c
#define AT91SAM9G45_DDRSDRC_TPR0 0x0c
#define AT91SAM9G45_DDRSDRC_TPR1 0x10
#define AT91SAM9G45_DDRSDRC_TPR2 0x14
/* Reserved 0x18 */
#define AT91SAM9G45_DDRSDRC_LPR 0x1c
#define AT91SAM9G45_DDRSDRC_MDR 0x20
#define AT91SAM9G45_DDRSDRC_MDR_SDR 0x0
#define AT91SAM9G45_DDRSDRC_MDR_LPSDR 0x1
#define AT91SAM9G45_DDRSDRC_MDR_LPDDR1 0x3
#define AT91SAM9G45_DDRSDRC_MDR_DDR2 0x6
#define AT91SAM9G45_DDRSDRC_MDR_MASK 0x00000007
#define AT91SAM9G45_DDRSDRC_MDR_DBW_16 0x10
#define AT91SAM9G45_DDRSDRC_DLL 0x24
#define AT91SAM9G45_DDRSDRC_HSR 0x2c
#define AT91SAM9G45_DDRSDRC_DELAY1R 0x40
#define AT91SAM9G45_DDRSDRC_DELAY2R 0x44
#define AT91SAM9G45_DDRSDRC_DELAY3R 0x48
#define AT91SAM9G45_DDRSDRC_DELAY4R 0x4c
/* Reserved 0x50 - 0xe0 */
#define AT91SAM9G45_DDRSDRC_WPMR 0xe4
#define AT91SAM9G45_DDRSDRC_WPSR 0xe8
#endif /* AT91SAM9G45REG_H_*/

View File

@ -1,189 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2005 Olivier Houchard. All rights reserved.
* Copyright (c) 2010 Greg Ansley. All rights reserved.
* Copyright (c) 2012 M. Warner Losh.
*
* 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/bus.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <machine/bus.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91reg.h>
#include <arm/at91/at91soc.h>
#include <arm/at91/at91_aicreg.h>
#include <arm/at91/at91sam9x5reg.h>
#include <arm/at91/at91_pitreg.h>
#include <arm/at91/at91_pmcreg.h>
#include <arm/at91/at91_pmcvar.h>
#include <arm/at91/at91_rstreg.h>
/*
* Standard priority levels for the system. 0 is lowest and 7 is highest.
* These values are the ones Atmel uses for its Linux port
*/
static const int at91_irq_prio[32] =
{
7, /* Advanced Interrupt Controller (FIQ) */
7, /* System Peripherals */
1, /* Parallel IO Controller A and B */
1, /* Parallel IO Controller C and D */
4, /* Soft Modem */
5, /* USART 0 */
5, /* USART 1 */
5, /* USART 2 */
5, /* USART 3 */
6, /* Two-Wire Interface 0 */
6, /* Two-Wire Interface 1 */
6, /* Two-Wire Interface 2 */
0, /* Multimedia Card Interface 0 */
5, /* Serial Peripheral Interface 0 */
5, /* Serial Peripheral Interface 1 */
5, /* UART 0 */
5, /* UART 1 */
0, /* Timer Counter 0, 1, 2, 3, 4 and 5 */
0, /* Pulse Width Modulation Controller */
0, /* ADC Controller */
0, /* DMA Controller 0 */
0, /* DMA Controller 1 */
2, /* USB Host High Speed port */
2, /* USB Device High speed port */
3, /* Ethernet MAC 0 */
3, /* LDC Controller or Image Sensor Interface */
0, /* Multimedia Card Interface 1 */
3, /* Ethernet MAC 1 */
4, /* Synchronous Serial Interface */
4, /* CAN Controller 0 */
4, /* CAN Controller 1 */
0, /* Advanced Interrupt Controller (IRQ0) */
};
static const uint32_t at91_pio_base[] = {
AT91SAM9X25_PIOA_BASE,
AT91SAM9X25_PIOB_BASE,
AT91SAM9X25_PIOC_BASE,
AT91SAM9X25_PIOD_BASE,
};
#define DEVICE(_name, _id, _unit) \
{ \
_name, _unit, \
AT91SAM9X25_ ## _id ##_BASE, \
AT91SAM9X25_ ## _id ## _SIZE, \
AT91SAM9X25_IRQ_ ## _id \
}
static const struct cpu_devs at91_devs[] =
{
DEVICE("at91_aic", AIC, 0),
DEVICE("at91_pmc", PMC, 0),
DEVICE("at91_wdt", WDT, 0),
DEVICE("at91_rst", RSTC, 0),
DEVICE("at91_pit", PIT, 0),
DEVICE("at91_pio", PIOA, 0),
DEVICE("at91_pio", PIOB, 1),
DEVICE("at91_pio", PIOC, 2),
DEVICE("at91_pio", PIOD, 3),
DEVICE("at91_twi", TWI0, 0),
DEVICE("at91_twi", TWI1, 1),
DEVICE("at91_twi", TWI2, 2),
DEVICE("at91_mci", HSMCI0, 0),
DEVICE("at91_mci", HSMCI1, 1),
DEVICE("uart", DBGU, 0),
DEVICE("uart", USART0, 1),
DEVICE("uart", USART1, 2),
DEVICE("uart", USART2, 3),
DEVICE("uart", USART3, 4),
DEVICE("spi", SPI0, 0),
DEVICE("spi", SPI1, 1),
DEVICE("macb", EMAC0, 0),
DEVICE("macb", EMAC1, 0),
DEVICE("nand", NAND, 0),
DEVICE("ohci", OHCI, 0),
DEVICE("ehci", EHCI, 0),
{ 0, 0, 0, 0, 0 }
};
static void
at91_clock_init(void)
{
struct at91_pmc_clock *clk;
/* Update USB device port clock info */
clk = at91_pmc_clock_ref("udpck");
clk->pmc_mask = PMC_SCER_UDP_SAM9;
at91_pmc_clock_deref(clk);
/* Update USB host port clock info */
clk = at91_pmc_clock_ref("uhpck");
clk->pmc_mask = PMC_SCER_UHP_SAM9;
at91_pmc_clock_deref(clk);
/* Each SOC has different PLL contraints */
clk = at91_pmc_clock_ref("plla");
clk->pll_min_in = SAM9X25_PLL_A_MIN_IN_FREQ; /* 2 MHz */
clk->pll_max_in = SAM9X25_PLL_A_MAX_IN_FREQ; /* 32 MHz */
clk->pll_min_out = SAM9X25_PLL_A_MIN_OUT_FREQ; /* 400 MHz */
clk->pll_max_out = SAM9X25_PLL_A_MAX_OUT_FREQ; /* 800 MHz */
clk->pll_mul_shift = SAM9X25_PLL_A_MUL_SHIFT;
clk->pll_mul_mask = SAM9X25_PLL_A_MUL_MASK;
clk->pll_div_shift = SAM9X25_PLL_A_DIV_SHIFT;
clk->pll_div_mask = SAM9X25_PLL_A_DIV_MASK;
clk->set_outb = at91_pmc_800mhz_plla_outb;
at91_pmc_clock_deref(clk);
clk = at91_pmc_clock_ref("pllb");
clk->pll_min_in = SAM9X25_PLL_B_MIN_IN_FREQ; /* 2 MHz */
clk->pll_max_in = SAM9X25_PLL_B_MAX_IN_FREQ; /* 32 MHz */
clk->pll_min_out = SAM9X25_PLL_B_MIN_OUT_FREQ; /* 30 MHz */
clk->pll_max_out = SAM9X25_PLL_B_MAX_OUT_FREQ; /* 100 MHz */
clk->pll_mul_shift = SAM9X25_PLL_B_MUL_SHIFT;
clk->pll_mul_mask = SAM9X25_PLL_B_MUL_MASK;
clk->pll_div_shift = SAM9X25_PLL_B_DIV_SHIFT;
clk->pll_div_mask = SAM9X25_PLL_B_DIV_MASK;
clk->set_outb = at91_pmc_800mhz_pllb_outb;
at91_pmc_clock_deref(clk);
}
static struct at91_soc_data soc_data = {
.soc_delay = at91_pit_delay,
.soc_reset = at91_rst_cpu_reset,
.soc_clock_init = at91_clock_init,
.soc_irq_prio = at91_irq_prio,
.soc_children = at91_devs,
.soc_pio_base = at91_pio_base,
.soc_pio_count = nitems(at91_pio_base),
};
AT91_SOC_SUB(AT91_T_SAM9X5, AT91_ST_SAM9X25, &soc_data);

View File

@ -1,317 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2009 Sylvestre Gallon. All rights reserved.
* Copyright (c) 2010 Greg Ansley. All rights reserved.
* Copyright (c) 2012 M. Warener Losh. 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 AT91SAM9X5REG_H_
#define AT91SAM9X5REG_H_
#ifndef AT91SAM9X25_MASTER_CLOCK
#define AT91SAM9X25_MASTER_CLOCK ((18432000 * 43)/6)
#endif
/* Chip Specific limits */
#define SAM9X25_PLL_A_MIN_IN_FREQ 2000000 /* 2 Mhz */
#define SAM9X25_PLL_A_MAX_IN_FREQ 32000000 /* 32 Mhz */
#define SAM9X25_PLL_A_MIN_OUT_FREQ 400000000 /* 400 Mhz */
#define SAM9X25_PLL_A_MAX_OUT_FREQ 800000000 /* 800 Mhz */
#define SAM9X25_PLL_A_MUL_SHIFT 16
#define SAM9X25_PLL_A_MUL_MASK 0xFF
#define SAM9X25_PLL_A_DIV_SHIFT 0
#define SAM9X25_PLL_A_DIV_MASK 0xFF
#define SAM9X25_PLL_B_MIN_IN_FREQ 2000000 /* 2 Mhz */
#define SAM9X25_PLL_B_MAX_IN_FREQ 32000000 /* 32 Mhz */
#define SAM9X25_PLL_B_MIN_OUT_FREQ 30000000 /* 30 Mhz */
#define SAM9X25_PLL_B_MAX_OUT_FREQ 100000000 /* 100 Mhz */
#define SAM9X25_PLL_B_MUL_SHIFT 16
#define SAM9X25_PLL_B_MUL_MASK 0x3F
#define SAM9X25_PLL_B_DIV_SHIFT 0
#define SAM9X25_PLL_B_DIV_MASK 0xFF
/*
* Memory map, from datasheet :
* 0x00000000 - 0x0ffffffff : Internal Memories
* 0x10000000 - 0x1ffffffff : Chip Select 0
* 0x20000000 - 0x2ffffffff : Chip Select 1 DDR2/LPDDR/SDR/LPSDR
* 0x30000000 - 0x3ffffffff : Chip Select 2
* 0x40000000 - 0x4ffffffff : Chip Select 3 NAND Flash
* 0x50000000 - 0x5ffffffff : Chip Select 4
* 0x60000000 - 0x6ffffffff : Chip Select 5
* 0x70000000 - 0xeffffffff : Undefined (Abort)
* 0xf0000000 - 0xfffffffff : Peripherals
*/
#define AT91_CHIPSELECT_0 0x10000000
#define AT91_CHIPSELECT_1 0x20000000
#define AT91_CHIPSELECT_2 0x30000000
#define AT91_CHIPSELECT_3 0x40000000
#define AT91_CHIPSELECT_4 0x50000000
#define AT91_CHIPSELECT_5 0x60000000
#define AT91SAM9X25_EMAC_SIZE 0x4000
#define AT91SAM9X25_EMAC0_BASE 0x802c000
#define AT91SAM9X25_EMAC0_SIZE AT91SAM9X25_EMAC_SIZE
#define AT91SAM9X25_EMAC1_BASE 0x8030000
#define AT91SAM9X25_EMAC1_SIZE AT91SAM9X25_EMAC_SIZE
#define AT91SAM9X25_RSTC_BASE 0xffffe00
#define AT91SAM9X25_RSTC_SIZE 0x10
/* USART*/
#define AT91SAM9X25_USART_SIZE 0x4000
#define AT91SAM9X25_USART0_BASE 0x801c000
#define AT91SAM9X25_USART0_PDC 0x801c100
#define AT91SAM9X25_USART0_SIZE AT91SAM9X25_USART_SIZE
#define AT91SAM9X25_USART1_BASE 0x8020000
#define AT91SAM9X25_USART1_PDC 0x8020100
#define AT91SAM9X25_USART1_SIZE AT91SAM9X25_USART_SIZE
#define AT91SAM9X25_USART2_BASE 0x8024000
#define AT91SAM9X25_USART2_PDC 0x8024100
#define AT91SAM9X25_USART2_SIZE AT91SAM9X25_USART_SIZE
#define AT91SAM9X25_USART3_BASE 0x8028000
#define AT91SAM9X25_USART3_PDC 0x8028100
#define AT91SAM9X25_USART3_SIZE AT91SAM9X25_USART_SIZE
/*TC*/
#define AT91SAM9X25_TC0_BASE 0x8008000
#define AT91SAM9X25_TC0_SIZE 0x4000
#define AT91SAM9X25_TC0C0_BASE 0x8008000
#define AT91SAM9X25_TC0C1_BASE 0x8008040
#define AT91SAM9X25_TC0C2_BASE 0x8008080
#define AT91SAM9X25_TC1_BASE 0x800c000
#define AT91SAM9X25_TC1_SIZE 0x4000
/*SPI*/
#define AT91SAM9X25_SPI0_BASE 0x0000000
#define AT91SAM9X25_SPI0_SIZE 0x4000
#define AT91SAM9X25_SPI1_BASE 0x0004000
#define AT91SAM9X25_SPI1_SIZE 0x4000
/* System Registers */
#define AT91SAM9X25_SYS_BASE 0xffff000
#define AT91SAM9X25_SYS_SIZE 0x1000
#define AT91SAM9X25_MATRIX_BASE 0xfffde00
#define AT91SAM9X25_MATRIX_SIZE 0x200
#define AT91SAM9X25_DBGU_BASE 0xffff200
#define AT91SAM9X25_DBGU_SIZE 0x200
/*
* PIO
*/
#define AT91SAM9X25_PIOA_BASE 0xffff400
#define AT91SAM9X25_PIOA_SIZE 0x200
#define AT91SAM9X25_PIOB_BASE 0xffff600
#define AT91SAM9X25_PIOB_SIZE 0x200
#define AT91SAM9X25_PIOC_BASE 0xffff800
#define AT91SAM9X25_PIOC_SIZE 0x200
#define AT91SAM9X25_PIOD_BASE 0xffffa00
#define AT91SAM9X25_PIOD_SIZE 0x200
#define AT91RM92_PMC_BASE 0xffffc00
#define AT91RM92_PMC_SIZE 0x100
/* IRQs :
* 0: AIC
* 1: System peripheral (System timer, RTC, DBGU)
* 2: PIO Controller A,B
* 3: PIO Controller C,D
* 4: SMD Soft Modem
* 5: USART 0
* 6: USART 1
* 7: USART 2
* 8: USART 3
* 9: Two-wire interface
* 10: Two-wire interface
* 11: Two-wire interface
* 12: HSMCI Interface
* 13: SPI 0
* 14: SPI 1
* 15: UART0
* 16: UART1
* 17: Timer Counter 0,1
* 18: PWM
* 19: ADC
* 20: DMAC 0
* 21: DMAC 1
* 22: UHPHS - USB Host controller
* 23: UDPHS - USB Device Controller
* 24: EMAC0
* 25: LCD controller or Image Sensor Interface
* 26: HSMCI1
* 27: EMAC1
* 28: SSC
* 29: CAN0
* 30: CAN1
* 31: AIC IRQ0
*/
#define AT91SAM9X25_IRQ_AIC 0
#define AT91SAM9X25_IRQ_SYSTEM 1
#define AT91SAM9X25_IRQ_PIOAB 2
#define AT91SAM9X25_IRQ_PIOCD 3
#define AT91SAM9X25_IRQ_SMD 4
#define AT91SAM9X25_IRQ_USART0 5
#define AT91SAM9X25_IRQ_USART1 6
#define AT91SAM9X25_IRQ_USART2 7
#define AT91SAM9X25_IRQ_USART3 8
#define AT91SAM9X25_IRQ_TWI0 9
#define AT91SAM9X25_IRQ_TWI1 10
#define AT91SAM9X25_IRQ_TWI2 11
#define AT91SAM9X25_IRQ_HSMCI0 12
#define AT91SAM9X25_IRQ_SPI0 13
#define AT91SAM9X25_IRQ_SPI1 14
#define AT91SAM9X25_IRQ_UART0 15
#define AT91SAM9X25_IRQ_UART1 16
#define AT91SAM9X25_IRQ_TC01 17
#define AT91SAM9X25_IRQ_PWM 18
#define AT91SAM9X25_IRQ_ADC 19
#define AT91SAM9X25_IRQ_DMAC0 20
#define AT91SAM9X25_IRQ_DMAC1 21
#define AT91SAM9X25_IRQ_UHPHS 22
#define AT91SAM9X25_IRQ_UDPHS 23
#define AT91SAM9X25_IRQ_EMAC0 24
#define AT91SAM9X25_IRQ_HSMCI1 26
#define AT91SAM9X25_IRQ_EMAC1 27
#define AT91SAM9X25_IRQ_SSC 28
#define AT91SAM9X25_IRQ_CAN0 29
#define AT91SAM9X25_IRQ_CAN1 30
#define AT91SAM9X25_IRQ_AICBASE 31
/* Alias */
#define AT91SAM9X25_IRQ_DBGU AT91SAM9X25_IRQ_SYSTEM
#define AT91SAM9X25_IRQ_PMC AT91SAM9X25_IRQ_SYSTEM
#define AT91SAM9X25_IRQ_WDT AT91SAM9X25_IRQ_SYSTEM
#define AT91SAM9X25_IRQ_PIT AT91SAM9X25_IRQ_SYSTEM
#define AT91SAM9X25_IRQ_RSTC AT91SAM9X25_IRQ_SYSTEM
#define AT91SAM9X25_IRQ_OHCI AT91SAM9X25_IRQ_UHPHS
#define AT91SAM9X25_IRQ_EHCI AT91SAM9X25_IRQ_UHPHS
#define AT91SAM9X25_IRQ_PIOA AT91SAM9X25_IRQ_PIOAB
#define AT91SAM9X25_IRQ_PIOB AT91SAM9X25_IRQ_PIOAB
#define AT91SAM9X25_IRQ_PIOC AT91SAM9X25_IRQ_PIOCD
#define AT91SAM9X25_IRQ_PIOD AT91SAM9X25_IRQ_PIOCD
#define AT91SAM9X25_IRQ_NAND (-1)
#define AT91SAM9X25_AIC_BASE 0xffff000
#define AT91SAM9X25_AIC_SIZE 0x200
/* Timer */
#define AT91SAM9X25_WDT_BASE 0xffffd40
#define AT91SAM9X25_WDT_SIZE 0x10
#define AT91SAM9X25_PIT_BASE 0xffffd30
#define AT91SAM9X25_PIT_SIZE 0x10
#define AT91SAM9X25_SMC_BASE 0xfffea00
#define AT91SAM9X25_SMC_SIZE 0x200
#define AT91SAM9X25_PMC_BASE 0xffffc00
#define AT91SAM9X25_PMC_SIZE 0x100
#define AT91SAM9X25_UDPHS_BASE 0x803c000
#define AT91SAM9X25_UDPHS_SIZE 0x4000
#define AT91SAM9X25_HSMCI_SIZE 0x4000
#define AT91SAM9X25_HSMCI0_BASE 0x0008000
#define AT91SAM9X25_HSMCI0_SIZE AT91SAM9X25_HSMCI_SIZE
#define AT91SAM9X25_HSMCI1_BASE 0x000c000
#define AT91SAM9X25_HSMCI1_SIZE AT91SAM9X25_HSMCI_SIZE
#define AT91SAM9X25_TWI_SIZE 0x4000
#define AT91SAM9X25_TWI0_BASE 0xffaC000
#define AT91SAM9X25_TWI0_SIZE AT91SAM9X25_TWI_SIZE
#define AT91SAM9X25_TWI1_BASE 0xffaC000
#define AT91SAM9X25_TWI1_SIZE AT91SAM9X25_TWI_SIZE
#define AT91SAM9X25_TWI2_BASE 0xffaC000
#define AT91SAM9X25_TWI2_SIZE AT91SAM9X25_TWI_SIZE
/* XXX Needs to be carfully coordinated with
* other * soc's so phyical and vm address
* mapping are unique. XXX
*/
#define AT91SAM9X25_OHCI_BASE 0xdfc00000 /* SAME as 9c40 */
#define AT91SAM9X25_OHCI_PA_BASE 0x00600000
#define AT91SAM9X25_OHCI_SIZE 0x00100000
#define AT91SAM9X25_EHCI_BASE 0xdfd00000
#define AT91SAM9X25_EHCI_PA_BASE 0x00700000
#define AT91SAM9X25_EHCI_SIZE 0x00100000
#define AT91SAM9X25_NAND_BASE 0xe0000000
#define AT91SAM9X25_NAND_PA_BASE 0x40000000
#define AT91SAM9X25_NAND_SIZE 0x10000000
/* SDRAMC */
#define AT91SAM9X25_SDRAMC_BASE 0xfffea00 /* SAME as SMC? */
#define AT91SAM9X25_SDRAMC_MR 0x00
#define AT91SAM9X25_SDRAMC_MR_MODE_NORMAL 0
#define AT91SAM9X25_SDRAMC_MR_MODE_NOP 1
#define AT91SAM9X25_SDRAMC_MR_MODE_PRECHARGE 2
#define AT91SAM9X25_SDRAMC_MR_MODE_LOAD_MODE_REGISTER 3
#define AT91SAM9X25_SDRAMC_MR_MODE_REFRESH 4
#define AT91SAM9X25_SDRAMC_TR 0x04
#define AT91SAM9X25_SDRAMC_CR 0x08
#define AT91SAM9X25_SDRAMC_CR_NC_8 0x0
#define AT91SAM9X25_SDRAMC_CR_NC_9 0x1
#define AT91SAM9X25_SDRAMC_CR_NC_10 0x2
#define AT91SAM9X25_SDRAMC_CR_NC_11 0x3
#define AT91SAM9X25_SDRAMC_CR_NC_MASK 0x00000003
#define AT91SAM9X25_SDRAMC_CR_NR_11 0x0
#define AT91SAM9X25_SDRAMC_CR_NR_12 0x4
#define AT91SAM9X25_SDRAMC_CR_NR_13 0x8
#define AT91SAM9X25_SDRAMC_CR_NR_RES 0xc
#define AT91SAM9X25_SDRAMC_CR_NR_MASK 0x0000000c
#define AT91SAM9X25_SDRAMC_CR_NB_2 0x00
#define AT91SAM9X25_SDRAMC_CR_NB_4 0x10
#define AT91SAM9X25_SDRAMC_CR_DBW_16 0x80
#define AT91SAM9X25_SDRAMC_CR_NB_MASK 0x00000010
#define AT91SAM9X25_SDRAMC_CR_NCAS_MASK 0x00000060
#define AT91SAM9X25_SDRAMC_CR_TWR_MASK 0x00000780
#define AT91SAM9X25_SDRAMC_CR_TRC_MASK 0x00007800
#define AT91SAM9X25_SDRAMC_CR_TRP_MASK 0x00078000
#define AT91SAM9X25_SDRAMC_CR_TRCD_MASK 0x00780000
#define AT91SAM9X25_SDRAMC_CR_TRAS_MASK 0x07800000
#define AT91SAM9X25_SDRAMC_CR_TXSR_MASK 0x78000000
#define AT91SAM9X25_SDRAMC_HSR 0x0c
#define AT91SAM9X25_SDRAMC_LPR 0x10
#define AT91SAM9X25_SDRAMC_IER 0x14
#define AT91SAM9X25_SDRAMC_IDR 0x18
#define AT91SAM9X25_SDRAMC_IMR 0x1c
#define AT91SAM9X25_SDRAMC_ISR 0x20
#define AT91SAM9X25_SDRAMC_MDR 0x24
#endif /* AT91SAM9X5REG_H_*/

View File

@ -1,53 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2012 M. Warner Losh.
*
* 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 <arm/at91/at91var.h>
#include <arm/at91/at91soc.h>
SET_DECLARE(at91_socs, const struct at91_soc);
struct at91_soc_data *
at91_match_soc(enum at91_soc_type type, enum at91_soc_subtype subtype)
{
const struct at91_soc **socp;
SET_FOREACH(socp, at91_socs) {
if ((*socp)->soc_type != type)
continue;
if ((*socp)->soc_subtype != AT91_ST_ANY &&
(*socp)->soc_subtype != subtype)
continue;
return (*socp)->soc_data;
}
return NULL;
}

View File

@ -1,60 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2012 M. Warner Losh.
*
* 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 _ARM_AT91_AT91SOC_H_
#define _ARM_AT91_AT91SOC_H_
#include <sys/linker_set.h>
struct at91_soc {
enum at91_soc_type soc_type; /* Family of mail type of SoC */
enum at91_soc_subtype soc_subtype; /* More specific soc, if any */
struct at91_soc_data *soc_data;
};
// Make varadic
#define AT91_SOC(type, data) \
static struct at91_soc this_soc = { \
.soc_type = type, \
.soc_subtype = AT91_ST_ANY, \
.soc_data = data, \
}; \
DATA_SET(at91_socs, this_soc);
#define AT91_SOC_SUB(type, subtype, data) \
static struct at91_soc this_soc = { \
.soc_type = type, \
.soc_subtype = subtype, \
.soc_data = data, \
}; \
DATA_SET(at91_socs, this_soc);
struct at91_soc_data *at91_match_soc(enum at91_soc_type, enum at91_soc_subtype);
#endif /* _ARM_AT91_AT91SOC_H_ */

View File

@ -1,175 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2005 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 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 _AT91VAR_H_
#define _AT91VAR_H_
#include <sys/bus.h>
#include <sys/rman.h>
#include <arm/at91/at91reg.h>
struct at91_softc {
device_t dev;
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
bus_space_handle_t sc_aic_sh;
struct rman sc_irq_rman;
struct rman sc_mem_rman;
};
struct at91_ivar {
struct resource_list resources;
};
struct cpu_devs
{
const char *name;
int unit;
bus_addr_t mem_base;
bus_size_t mem_len;
int irq0;
int irq1;
int irq2;
const char *parent_clk;
};
enum at91_soc_type {
AT91_T_NONE = 0,
AT91_T_CAP9,
AT91_T_RM9200,
AT91_T_SAM9260,
AT91_T_SAM9261,
AT91_T_SAM9263,
AT91_T_SAM9G10,
AT91_T_SAM9G20,
AT91_T_SAM9G45,
AT91_T_SAM9N12,
AT91_T_SAM9RL,
AT91_T_SAM9X5,
};
enum at91_soc_subtype {
AT91_ST_ANY = -1, /* Match any type */
AT91_ST_NONE = 0,
/* AT91RM9200 */
AT91_ST_RM9200_BGA,
AT91_ST_RM9200_PQFP,
/* AT91SAM9260 */
AT91_ST_SAM9XE,
/* AT91SAM9G45 */
AT91_ST_SAM9G45,
AT91_ST_SAM9M10,
AT91_ST_SAM9G46,
AT91_ST_SAM9M11,
/* AT91SAM9X5 */
AT91_ST_SAM9G15,
AT91_ST_SAM9G25,
AT91_ST_SAM9G35,
AT91_ST_SAM9X25,
AT91_ST_SAM9X35,
};
enum at91_soc_family {
AT91_FAMILY_SAM9 = 0x19,
AT91_FAMILY_SAM9XE = 0x29,
AT91_FAMILY_RM92 = 0x92,
};
#define AT91_SOC_NAME_MAX 50
typedef void (*DELAY_t)(int);
typedef void (*cpu_reset_t)(void);
typedef void (*clk_init_t)(void);
struct at91_soc_data {
DELAY_t soc_delay; /* SoC specific delay function */
cpu_reset_t soc_reset; /* SoC specific reset function */
clk_init_t soc_clock_init; /* SoC specific clock init function */
const int *soc_irq_prio; /* SoC specific IRQ priorities */
const struct cpu_devs *soc_children; /* SoC specific children list */
const uint32_t *soc_pio_base; /* SoC specific PIO base registers */
size_t soc_pio_count; /* Count of PIO units (not pins) in SoC */
};
struct at91_soc_info {
enum at91_soc_type type;
enum at91_soc_subtype subtype;
enum at91_soc_family family;
uint32_t cidr;
uint32_t exid;
char name[AT91_SOC_NAME_MAX];
uint32_t dbgu_base;
struct at91_soc_data *soc_data;
};
extern struct at91_soc_info soc_info;
static inline int at91_is_rm92(void);
static inline int at91_is_sam9(void);
static inline int at91_is_sam9xe(void);
static inline int at91_cpu_is(u_int cpu);
static inline int
at91_is_rm92(void)
{
return (soc_info.type == AT91_T_RM9200);
}
static inline int
at91_is_sam9(void)
{
return (soc_info.family == AT91_FAMILY_SAM9);
}
static inline int
at91_is_sam9xe(void)
{
return (soc_info.family == AT91_FAMILY_SAM9XE);
}
static inline int
at91_cpu_is(u_int cpu)
{
return (soc_info.type == cpu);
}
void at91_add_child(device_t dev, int prio, const char *name, int unit,
bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2);
extern uint32_t at91_irq_system;
extern uint32_t at91_master_clock;
void at91_pmc_init_clock(void);
void at91_soc_id(void);
#endif /* _AT91VAR_H_ */

View File

@ -1,56 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2005-2008 Olivier Houchard. All rights reserved.
* Copyright (c) 2005-2012 M. Warner Losh.
*
* 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 <machine/board.h>
#include <arm/at91/at91board.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91rm9200var.h>
BOARD_INIT long
board_init(void)
{
at91rm9200_set_subtype(AT91_ST_RM9200_BGA);
/*
* I don't know anything at all about this board.
*/
at91rm9200_config_uart(AT91_ID_DBGU, 0, 0); /* DBGU just Tx and Rx */
at91rm9200_config_mci(0);
/* Configure ethernet */
return (at91_ramsize());
}
ARM_BOARD(NONE, "BWCT special");

View File

@ -1,70 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2005-2008 Olivier Houchard. All rights reserved.
* Copyright (c) 2005-2012 M. Warner Losh.
*
* 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 <machine/board.h>
#include <arm/at91/at91board.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91rm9200var.h>
BOARD_INIT long
board_init(void)
{
at91rm9200_set_subtype(AT91_ST_RM9200_BGA);
/*
* Setup the serial ports.
* DBGU and USART0 are DB9 ports.
* USART2 is IrDA.
*/
at91rm9200_config_uart(AT91_ID_DBGU, 0, 0); /* DBGU just Tx and Rx */
at91rm9200_config_uart(AT91RM9200_ID_USART0, 1,
AT91_UART_CTS | AT91_UART_RTS | AT91_UART_DTR | AT91_UART_DSR |
AT91_UART_DCD | AT91_UART_RI);
at91rm9200_config_uart(AT91RM9200_ID_USART1, 2, 0);
at91rm9200_config_mci(1);
/* CFE interface */
/* SPI interface */
/* ethernet interface */
/* USB host */
/* USB device (gadget) */
/* TWI */
/* CF interface */
/* SmartMedia Interface */
return (at91_ramsize());
}
ARM_BOARD(ATEB9200, "Embest ATEB9200")

View File

@ -1,151 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2012 Marius Strobl <marius@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.
*/
/*
* Ethernut 5 board support
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <machine/board.h>
#include <arm/at91/at91_pioreg.h>
#include <arm/at91/at91_piovar.h>
#include <arm/at91/at91board.h>
#include <arm/at91/at91sam9260reg.h>
BOARD_INIT long
board_init(void)
{
/*
* DBGU
*/
/* DRXD */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB14, 0);
/* DTXD */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB15, 1);
/*
* EMAC
*/
/* ETX0 */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA12, 0);
/* ETX1 */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA13, 0);
/* ERX0 */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA14, 0);
/* ERX1 */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA15, 0);
/* ETXEN */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA16, 0);
/* ERXDV */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA17, 0);
/* ERXER */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA18, 0);
/* ETXCK */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA19, 0);
/* EMDC */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA20, 0);
/* EMDIO */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA21, 0);
/*
* MMC
*/
/* MCDA0 */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA6, 1);
/* MCCDA */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA7, 1);
/* MCCK */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA8, 1);
/* MCDA1 */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA9, 1);
/* MCDA2 */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA10, 1);
/* MCDA3 */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA11, 1);
/*
* SPI0
*/
/* MISO */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA0, 0);
/* MOSI */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA1, 0);
/* SPCK */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA2, 0);
/* NPCS0 */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA3, 0);
/*
* TWI
*/
/* TWD */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA23, 1);
/* TWCK */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA24, 1);
/*
* USART0
*/
/* TXD0 */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB4, 1);
/* RXD0 */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB5, 0);
/* DSR0 */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB22, 0);
/* DCD0 */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB23, 0);
/* DTR0 */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB24, 1);
/* RI0 */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB25, 0);
/* RTS0 */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB26, 1);
/* CTS0 */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB27, 0);
/*
* USART2
*/
/* RTS2 */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA4, 1);
/* CTS2 */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA5, 0);
/* TXD2 */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB8, 1);
/* RXD2 */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB9, 0);
return (at91_ramsize());
}
ARM_BOARD(ETHERNUT5, "Ethernut 5")

View File

@ -1,67 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2005-2008 Olivier Houchard. All rights reserved.
* Copyright (c) 2005-2012 M. Warner Losh.
*
* 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 <machine/board.h>
#include <arm/at91/at91board.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91rm9200var.h>
BOARD_INIT long
board_init(void)
{
at91rm9200_set_subtype(AT91_ST_RM9200_BGA);
/*
* Unsure what all is in the HOTe HL200, but I do know there's
* one serial port that isn't DBGU. There's many other peripherals
* that need to be configured here.
*/
at91rm9200_config_uart(AT91_ID_DBGU, 0, 0); /* DBGU just Tx and Rx */
at91rm9200_config_uart(AT91RM9200_ID_USART0, 1, 0); /* Tx and Rx */
at91rm9200_config_mci(0); /* HOTe HL200 unknown 1 vs 4 wire */
/* Enable CF card slot */
/* Enable sound thing */
/* Enable VGA chip */
/* Enable ethernet */
/* Enable TWI + RTC */
/* Enable USB Host */
/* Enable USB Device (gadget) */
return (at91_ramsize());
}
ARM_BOARD(NONE, "HOTe 200");

View File

@ -1,123 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2005-2008 Olivier Houchard. All rights reserved.
* Copyright (c) 2005-2008 M. Warner Losh.
*
* 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 <machine/board.h>
#include <arm/at91/at91board.h>
#include <arm/at91/at91sam9g20reg.h>
#include <arm/at91/at91_piovar.h>
#include <arm/at91/at91_pio_sam9g20.h>
#include <arm/at91/at91_smc.h>
#include <arm/at91/at91_gpio.h>
#include <dev/nand/nfc_at91.h>
static struct at91_smc_init nand_smc = {
.ncs_rd_setup = 0,
.nrd_setup = 2,
.ncs_wr_setup = 0,
.nwe_setup = 2,
.ncs_rd_pulse = 4,
.nrd_pulse = 4,
.ncs_wr_pulse = 4,
.nwe_pulse = 4,
.nrd_cycle = 7,
.nwe_cycle = 7,
.mode = SMC_MODE_READ | SMC_MODE_WRITE | SMC_MODE_EXNW_DISABLED,
.tdf_cycles = 3,
};
static struct at91_nand_params nand_param = {
.ale = 1u << 21,
.cle = 1u << 22,
.width = 8,
.rnb_pin = AT91_PIN_PC13, /* Note: These pins not confirmed */
.nce_pin = AT91_PIN_PC14,
.cs = 3,
};
BOARD_INIT long
board_init(void)
{
/* Setup Ethernet Pins */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, 1<<7, 0);
at91_pio_gpio_input(AT91SAM9G20_PIOA_BASE, 1<<7);
at91_pio_gpio_set_deglitch(AT91SAM9G20_PIOA_BASE, 1<<7, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA19, 0); /* ETXCK_EREFCK */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA17, 0); /* ERXDV */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA14, 0); /* ERX0 */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA15, 0); /* ERX1 */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA18, 0); /* ERXER */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA16, 0); /* ETXEN */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA12, 0); /* ETX0 */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA13, 0); /* ETX1 */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA21, 0); /* EMDIO */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA20, 0); /* EMDC */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA28, 0); /* ECRS */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA29, 0); /* ECOL */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA25, 0); /* ERX2 */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA26, 0); /* ERX3 */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA27, 0); /* ERXCK */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA23, 0); /* ETX2 */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA24, 0); /* ETX3 */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA22, 0); /* ETXER */
/* Setup Static Memory Controller */
at91_smc_setup(0, 3, &nand_smc);
at91_enable_nand(&nand_param);
/*
* This assumes
* - RNB is on pin PC13
* - CE is on pin PC14
*
* Nothing actually uses RNB right now.
*
* For CE, this currently asserts it during board setup and leaves it
* that way forever.
*
* All this can go away when the gpio pin-renumbering happens...
*/
at91_pio_use_gpio(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC13 | AT91C_PIO_PC14);
at91_pio_gpio_input(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC13); /* RNB */
at91_pio_gpio_output(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC14, 0); /* nCS */
at91_pio_gpio_clear(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC14); /* Assert nCS */
return (at91_ramsize());
}
ARM_BOARD(NONE, "HOTe 201");

View File

@ -1,68 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2005-2008 Olivier Houchard. All rights reserved.
* Copyright (c) 2005-2012 M. Warner Losh.
*
* 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 <machine/board.h>
#include <arm/at91/at91board.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91rm9200var.h>
BOARD_INIT long
board_init(void)
{
at91rm9200_set_subtype(AT91_ST_RM9200_PQFP);
/*
* Setup the serial ports.
* DBGU is the main one, although jumpers can make USART0 default.
* USART1 is IrDA, and USART3 is optional RS485.
*/
at91rm9200_config_uart(AT91_ID_DBGU, 0, 0); /* DBGU just Tx and Rx */
at91rm9200_config_uart(AT91RM9200_ID_USART0, 1, 0); /* Tx and Rx */
at91rm9200_config_uart(AT91RM9200_ID_USART1, 2, 0); /* Tx and Rx - IRDA */
at91rm9200_config_uart(AT91RM9200_ID_USART3, 3, /* Tx, Rx, CTS, RTS - RS485 */
AT91_UART_CTS | AT91_UART_RTS);
at91rm9200_config_mci(1);
/* CFE interface */
/* ethernet interface */
/* lcd interface */
/* USB host */
/* USB device (gadget) */
/* TWI */
return (at91_ramsize());
}
ARM_BOARD(KB9200, "Kwikbyte KB920x")

View File

@ -1,110 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2009 Greg Ansley. 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.
*/
/* Calao Systems QIL-9G20-Cxx
* http://www.calao-systems.com
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <machine/board.h>
#include <arm/at91/at91board.h>
#include <arm/at91/at91reg.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91sam9g20reg.h>
#include <arm/at91/at91_piovar.h>
#include <arm/at91/at91_pio_sam9g20.h>
//#include <arm/at91/at91_led.h>
#define AT91SAM9G20_LED_BASE AT91SAM9G20_PIOA_BASE
#define AT91SAM9G20_LED_SIZE AT91SAM9G20_PIO_SIZE
#define AT91SAM9G20_IRQ_LED AT91SAM9G20_IRQ_PIOA
BOARD_INIT long
board_init(void)
{
//at91_led_create("power", 0, 9, 0);
/* PIOB's A periph: Turn USART 0's TX/RX pins */
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB14_DRXD, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB15_DTXD, 1);
/* PIOB's A periph: Turn USART 0's TX/RX pins */
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB4_TXD0, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB5_RXD0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB22_DSR0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB23_DCD0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB24_DTR0, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB25_RI0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB26_RTS0, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB27_CTS0, 0);
/* PIOB's A periph: Turn USART 1's TX/RX pins */
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB6_TXD1, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB7_RXD1, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB28_RTS1, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB29_CTS1, 0);
/* TWI Two-wire Serial Data */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA23_TWD, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA24_TWCK, 1);
/* Multimedia Card */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA6_MCDA0, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA7_MCCDA, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA8_MCCK, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA9_MCDA1, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA10_MCDA2, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA11_MCDA3, 1);
/* SPI0 to DataFlash */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PA0_SPI0_MISO, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PA1_SPI0_MOSI, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PA2_SPI0_SPCK, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PA3_SPI0_NPCS0, 0);
/* EMAC */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA19_ETXCK, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA21_EMDIO, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA20_EMDC, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA17_ERXDV, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA16_ETXEN, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA12_ETX0 , 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA13_ETX1, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA14_ERX0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA15_ERX1, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA18_ERXER, 0);
return (at91_ramsize());
}
ARM_BOARD(QIL_A9G20, "Calico System QIL-9G20-Cxx");

View File

@ -1,264 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2012 Marius Strobl <marius@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.
*/
/*
* Ethernut 5 board support
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <machine/board.h>
#include <arm/at91/at91_pioreg.h>
#include <arm/at91/at91_piovar.h>
#include <arm/at91/at91board.h>
#include <arm/at91/at91sam9260reg.h>
#include <arm/at91/at91_smc.h>
#include <arm/at91/at91_gpio.h>
#include <dev/nand/nfc_at91.h>
static struct at91_smc_init nand_smc = {
.ncs_rd_setup = 0,
.nrd_setup = 1,
.ncs_wr_setup = 0,
.nwe_setup = 1,
.ncs_rd_pulse = 3,
.nrd_pulse = 3,
.ncs_wr_pulse = 3,
.nwe_pulse = 3,
.nrd_cycle = 5,
.nwe_cycle = 5,
.mode = SMC_MODE_READ | SMC_MODE_WRITE | SMC_MODE_EXNW_DISABLED,
.tdf_cycles = 2,
};
static struct at91_nand_params nand_param = {
.ale = 1u << 21,
.cle = 1u << 22,
.width = 8,
.rnb_pin = AT91_PIN_PC13,
.nce_pin = AT91_PIN_PC14,
.cs = 3,
};
static void
bi_dbgu(void)
{
/*
* DBGU
*/
/* DRXD */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB14, 0);
/* DTXD */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB15, 1);
}
static void
bi_emac(void)
{
/*
* EMAC
*/
/* ETX0 */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA12, 0);
/* ETX1 */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA13, 0);
/* ERX0 */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA14, 0);
/* ERX1 */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA15, 0);
/* ETXEN */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA16, 0);
/* ERXDV */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA17, 0);
/* ERXER */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA18, 0);
/* ETXCK */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA19, 0);
/* EMDC */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA20, 0);
/* EMDIO */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA21, 0);
/* Not RMII */
/* ETX2 */
at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA10, 0);
/* ETX3 */
at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA11, 0);
/* ETXER */
at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA22, 0);
/* ERX2 */
at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA25, 0);
/* ERX3 */
at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA26, 0);
/* ERXCK */
at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA27, 0);
/* ECRS */
at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA28, 0);
/* ECOL */
at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA29, 0);
}
static void
bi_mmc(void)
{
/*
* MMC, wired to socket B.
*/
/* MCDB0 */
at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA0, 1);
/* MCCDB */
at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA1, 1);
/* MCDB3 */
at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA3, 1);
/* MCDB2 */
at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA4, 1);
/* MCDB1 */
at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA5, 1);
/* MCCK */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA8, 1);
/*
* SPI0 and MMC are wired together, since we don't support sharing
* don't support the dataflash. But if you did, you'd have to
* use CS0 and CS1.
*/
}
static void
bi_iic(void)
{
/*
* TWI. Only one child on the iic bus, which we take care of
* via hints.
*/
/* TWD */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA23, 1);
/* TWCK */
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA24, 1);
}
static void
bi_usart0(void)
{
/*
* USART0
*/
/* TXD0 */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB4, 1);
/* RXD0 */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB5, 0);
/* DSR0 */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB22, 0);
/* DCD0 */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB23, 0);
/* DTR0 */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB24, 1);
/* RI0 */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB25, 0);
/* RTS0 */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB26, 1);
/* CTS0 */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB27, 0);
}
static void
bi_usart1(void)
{
/*
* USART1
*/
/* RTS1 */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB28, 1);
/* CTS1 */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB29, 0);
/* TXD1 */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB6, 1);
/* RXD1 */
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB7, 0);
}
static void
bi_nand(void)
{
/* Samsung 256MB SLC Flash */
/* Setup Static Memory Controller */
at91_smc_setup(0, 3, &nand_smc);
at91_enable_nand(&nand_param);
/*
* This assumes
* - RNB is on pin PC13
* - CE is on pin PC14
*
* Nothing actually uses RNB right now.
*
* For CE, this currently asserts it during board setup and leaves it
* that way forever.
*
* All this can go away when the gpio pin-renumbering happens...
*/
at91_pio_use_gpio(AT91SAM9260_PIOC_BASE, AT91C_PIO_PC13 | AT91C_PIO_PC14);
at91_pio_gpio_input(AT91SAM9260_PIOC_BASE, AT91C_PIO_PC13); /* RNB */
at91_pio_gpio_output(AT91SAM9260_PIOC_BASE, AT91C_PIO_PC14, 0); /* nCS */
at91_pio_gpio_clear(AT91SAM9260_PIOC_BASE, AT91C_PIO_PC14); /* Assert nCS */
}
BOARD_INIT long
board_init(void)
{
bi_dbgu();
bi_emac();
bi_mmc();
/*
* SPI1 is wired to a audio CODEC that we don't support, so
* give it a pass.
*/
bi_iic();
bi_usart0();
bi_usart1();
/* USART2 - USART5 aren't wired up, except via PIO pins, ignore them. */
bi_nand();
return (at91_ramsize());
}
ARM_BOARD(AT91SAM9260EK, "Atmel SMA9260-EK")

View File

@ -1,129 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2009 Greg Ansley. 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.
*/
/*
* This board file can be used for both:
* Atmel SAM9G20-EK Development Card
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <machine/board.h>
#include <arm/at91/at91board.h>
#include <arm/at91/at91reg.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91sam9g20reg.h>
#include <arm/at91/at91_piovar.h>
#include <arm/at91/at91_pio_sam9g20.h>
//#include <arm/at91/at91_led.h>
BOARD_INIT long
board_init(void)
{
/* PIOB's A periph: Turn USART 0's TX/RX pins */
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB14_DRXD, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB15_DTXD, 1);
/* PIOB's A periph: Turn USART 0's TX/RX pins */
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB4_TXD0, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB5_RXD0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB22_DSR0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB23_DCD0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB24_DTR0, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB25_RI0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB26_RTS0, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB27_CTS0, 0);
/* PIOB's A periph: Turn USART 1's TX/RX pins */
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB6_TXD1, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB7_RXD1, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB28_RTS1, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB29_CTS1, 0);
/* TWI Two-wire Serial Data */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA23_TWD, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA24_TWCK, 1);
#if 1
/*
* Turn off Clock to DataFlash, conflicts with MCI clock.
*/
at91_pio_use_gpio(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA2);
at91_pio_gpio_input(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA2);
/* Turn off chip select to DataFlash */
at91_pio_gpio_output(AT91SAM9G20_PIOC_BASE,AT91C_PIO_PC11, 0);
at91_pio_gpio_set(AT91SAM9G20_PIOC_BASE,AT91C_PIO_PC11);
at91_pio_use_gpio(AT91SAM9G20_PIOC_BASE,AT91C_PIO_PC11);
/* Multimedia Card */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA0_MCDB0, 1);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA1_MCCDB, 1);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA3_MCDB3, 1);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA4_MCDB2, 1);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA5_MCDB1, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA8_MCCK, 1);
at91_pio_use_gpio(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC9);
#else
/* SPI0 to DataFlash */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA1, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA2, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC11,0);
at91_pio_gpio_input(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA8);
at91_pio_use_gpio(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA8);
#endif
/* EMAC */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA12_ETX0 , 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA13_ETX1, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA14_ERX0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA15_ERX1, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA16_ETXEN, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA17_ERXDV, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA18_ERXER, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA19_ETXCK, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA20_EMDC, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA21_EMDIO, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA10_ETX2_0, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA11_ETX3_0, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA22_ETXER, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA25_ERX2, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA26_ERX3, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA27_ERXCK, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA28_ECRS, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA29_ECOL, 0);
return (at91_ramsize());
}
ARM_BOARD(AT91SAM9G20, "Atmel SAM9G20-EK Development Card");

View File

@ -1,130 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2009 Greg Ansley. 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.
*/
/*
* This board file can be used for both:
* SAM9X26EK board
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <machine/board.h>
#include <arm/at91/at91board.h>
#include <arm/at91/at91reg.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91sam9g20reg.h>
#include <arm/at91/at91_piovar.h>
#include <arm/at91/at91_pio_sam9g20.h>
//#include <arm/at91/at91_led.h>
BOARD_INIT long
board_init(void)
{
#if 0
/* PIOB's A periph: Turn USART 0's TX/RX pins */
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB14_DRXD, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB15_DTXD, 1);
/* PIOB's A periph: Turn USART 0's TX/RX pins */
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB4_TXD0, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB5_RXD0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB22_DSR0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB23_DCD0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB24_DTR0, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB25_RI0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB26_RTS0, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB27_CTS0, 0);
/* PIOB's A periph: Turn USART 1's TX/RX pins */
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB6_TXD1, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB7_RXD1, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB28_RTS1, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB29_CTS1, 0);
/* TWI Two-wire Serial Data */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA23_TWD, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA24_TWCK, 1);
#if 1
/*
* Turn off Clock to DataFlash, conflicts with MCI clock.
*/
at91_pio_use_gpio(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA2);
at91_pio_gpio_input(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA2);
/* Turn off chip select to DataFlash */
at91_pio_gpio_output(AT91SAM9G20_PIOC_BASE,AT91C_PIO_PC11, 0);
at91_pio_gpio_set(AT91SAM9G20_PIOC_BASE,AT91C_PIO_PC11);
at91_pio_use_gpio(AT91SAM9G20_PIOC_BASE,AT91C_PIO_PC11);
/* Multimedia Card */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA0_MCDB0, 1);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA1_MCCDB, 1);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA3_MCDB3, 1);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA4_MCDB2, 1);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA5_MCDB1, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA8_MCCK, 1);
at91_pio_use_gpio(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC9);
#else
/* SPI0 to DataFlash */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA1, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA2, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC11,0);
at91_pio_gpio_input(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA8);
at91_pio_use_gpio(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA8);
#endif
/* EMAC */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA12_ETX0 , 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA13_ETX1, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA14_ERX0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA15_ERX1, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA16_ETXEN, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA17_ERXDV, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA18_ERXER, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA19_ETXCK, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA20_EMDC, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA21_EMDIO, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA10_ETX2_0, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA11_ETX3_0, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA22_ETXER, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA25_ERX2, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA26_ERX3, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA27_ERXCK, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA28_ECRS, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA29_ECOL, 0);
#endif
return (at91_ramsize());
}
ARM_BOARD(AT91SAM9X5EK, "Atmel AT91SAM9x-EK Evaluation Board");

View File

@ -1,57 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2009 Greg Ansley. 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.
*/
/*
* DesignA Electronics Snapper9g45
* http://www.designa-electronics.com/
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <machine/board.h>
#include <arm/at91/at91board.h>
#include <arm/at91/at91reg.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91sam9g45reg.h>
#include <arm/at91/at91_piovar.h>
#include <arm/at91/at91_pio_sam9g45.h>
BOARD_INIT long
board_init(void)
{
/* PIOB's A periph: Turn the debug USART's TX/RX pins */
at91_pio_use_periph_a(AT91SAM9G45_PIOB_BASE, AT91C_PB12_DRXD, 0);
at91_pio_use_periph_a(AT91SAM9G45_PIOB_BASE, AT91C_PB13_DTXD, 1);
return (at91_ramsize());
}
ARM_BOARD(SNAPPER9G45, "DesignA Electronics Snapper9G45");

View File

@ -1,610 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2005-2008 Olivier Houchard. All rights reserved.
* Copyright (c) 2005-2012 M. Warner Losh.
* Copyright (c) 2007-2014 Ian Lepore. 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.
*/
/*
* Board init code for the TSC4370, and all other current TSC mainboards.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <arm/at91/at91_pioreg.h>
#include <arm/at91/at91_piovar.h>
#include <arm/at91/at91_pmcreg.h>
#include <arm/at91/at91_pmcvar.h>
#include <arm/at91/at91_twireg.h>
#include <arm/at91/at91_usartreg.h>
#include <arm/at91/at91board.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91rm9200var.h>
#include <arm/at91/at91rm92reg.h>
#include <arm/at91/if_atereg.h>
#include <machine/board.h>
#include <machine/cpu.h>
#include <machine/machdep.h>
#include <net/ethernet.h>
#include <sys/reboot.h>
/*
* RD4HW()/WR4HW() read and write at91rm9200 hardware register space directly.
* They serve the same purpose as the RD4()/WR4() idiom you see in many drivers,
* except that those translate to bus_space calls, but in this code we need to
* access the registers directly before the at91 bus_space stuff is set up.
*/
static inline uint32_t
RD4HW(uint32_t devbase, uint32_t regoff)
{
return *(volatile uint32_t *)(AT91_BASE + devbase + regoff);
}
static inline void
WR4HW(uint32_t devbase, uint32_t regoff, uint32_t val)
{
*(volatile uint32_t *)(AT91_BASE + devbase + regoff) = val;
}
/*
* This is the same calculation the at91 uart driver does, we use it to update
* the console uart baud rate after changing the MCK rate.
*/
#ifndef BAUD2DIVISOR
#define BAUD2DIVISOR(b) \
((((at91_master_clock * 10) / ((b) * 16)) + 5) / 10)
#endif
/*
* If doing an in-house build, use tsc_bootinfo.h which is shared with our
* custom boot2. Otherwise define some crucial bits of it here, enough to allow
* this code to compile.
*/
#ifdef TSC_BUILD
#include <machine/tsc_bootinfo.h>
#else
struct tsc_bootinfo {
uint32_t bi_size;
uint32_t bi_version;
uint32_t bi_flags; /* RB_xxxxx flags from sys/reboot.h */
char bi_rootdevname[64];
};
#define TSC_BOOTINFO_MAGIC 0x06C30000
#endif
static struct arm_boot_params boot_params;
static struct tsc_bootinfo inkernel_bootinfo;
/*
* Change the master clock config and wait for it to stabilize.
*/
static void
change_mckr(uint32_t mckr)
{
int i;
WR4HW(AT91RM92_PMC_BASE, PMC_MCKR, mckr);
for (i = 0; i < 1000; ++i)
if ((RD4HW(AT91RM92_PMC_BASE, PMC_SR) & PMC_IER_MCKRDY))
return;
}
/*
* Allow the master clock frequency to be changed from whatever the bootloader
* set up, because sometimes it's harder to change/update a bootloader than it
* is to change/update the kernel once a product is in the field.
*/
static void
master_clock_init(void)
{
uint32_t mckr = RD4HW(AT91RM92_PMC_BASE, PMC_MCKR);
int hintvalue = 0;
int newmckr = 0;
/*
* If there's a hint that specifies the contents of MCKR, use it
* without question (it had better be right).
*
* If there's a "mckfreq" hint it might be in hertz or mhz (convert the
* latter to hz). Calculate the new MCK divider. If the CPU frequency
* is not a sane multiple of the hinted MCK frequency this is likely to
* behave badly. The moral is: don't hint at impossibilities.
*/
if (resource_int_value("at91", 0, "mckr", &hintvalue) == 0) {
newmckr = hintvalue;
} else {
hintvalue = 90; /* Default to 90mhz if not specified. */
resource_int_value("at91", 0, "mckfreq", &hintvalue);
if (hintvalue != 0) {
if (hintvalue < 1000)
hintvalue *= 1000000;
if (hintvalue != at91_master_clock) {
uint32_t divider;
struct at91_pmc_clock * cpuclk;
cpuclk = at91_pmc_clock_ref("cpu");
divider = (cpuclk->hz / hintvalue) - 1;
newmckr = (mckr & 0xFFFFFCFF) | ((divider & 0x03) << 8);
at91_pmc_clock_deref(cpuclk);
}
}
}
/* If the new mckr value is different than what's in the register now,
* make the change and wait for the clocks to settle (MCKRDY status).
*
* MCKRDY will never be asserted unless either the selected clock or the
* prescaler value changes (but not both at once) [this is detailed in
* the rm9200 errata]. This code assumes the prescaler value is always
* zero and that by time we get to here we're running on something other
* than the slow clock, so to change the mckr divider we first change
* back to the slow clock (keeping prescaler and divider unchanged),
* then go back to the original selected clock with the new divider.
*
* After changing MCK, go re-init everything clock-related, and reset
* the baud rate generator for the console (doing this here is kind of a
* rude hack, but hey, you do what you have to to run MCK faster).
*/
if (newmckr != 0 && newmckr != mckr) {
if (mckr & 0x03)
change_mckr(mckr & ~0x03);
change_mckr(newmckr);
at91_pmc_init_clock();
WR4HW(AT91RM92_DBGU_BASE, USART_BRGR, BAUD2DIVISOR(115200));
}
}
/*
* TSC-specific code to read the ID eeprom on the mainboard and extract the
* unit's EUI-64 which gets translated into a MAC-48 for ethernet.
*/
static void
eeprom_init(void)
{
const uint32_t twiHz = 400000;
const uint32_t twiCkDiv = 1 << 16;
const uint32_t twiChDiv = ((at91_master_clock / twiHz) - 2) << 8;
const uint32_t twiClDiv = ((at91_master_clock / twiHz) - 2);
/*
* Set the TWCK and TWD lines for Periph A, no pullup, open-drain.
*/
at91_pio_use_periph_a(AT91RM92_PIOA_BASE,
AT91C_PIO_PA25 | AT91C_PIO_PA26, 0);
at91_pio_gpio_high_z(AT91RM92_PIOA_BASE, AT91C_PIO_PA25, 1);
/*
* Enable TWI power (irq numbers are also device IDs for power)
*/
WR4HW(AT91RM92_PMC_BASE, PMC_PCER, 1u << AT91RM92_IRQ_TWI);
/*
* Disable TWI interrupts, reset device, enable Master mode,
* disable Slave mode, set the clock.
*/
WR4HW(AT91RM92_TWI_BASE, TWI_IDR, 0xffffffff);
WR4HW(AT91RM92_TWI_BASE, TWI_CR, TWI_CR_SWRST);
WR4HW(AT91RM92_TWI_BASE, TWI_CR, TWI_CR_MSEN | TWI_CR_SVDIS);
WR4HW(AT91RM92_TWI_BASE, TWI_CWGR, twiCkDiv | twiChDiv | twiClDiv);
}
static int
eeprom_read(uint32_t EE_DEV_ADDR, uint32_t ee_off, void * buf, uint32_t size)
{
uint8_t *bufptr = (uint8_t *)buf;
uint32_t status;
uint32_t count;
/* Clean out any old status and received byte. */
status = RD4HW(AT91RM92_TWI_BASE, TWI_SR);
status = RD4HW(AT91RM92_TWI_BASE, TWI_RHR);
/* Set the TWI Master Mode Register */
WR4HW(AT91RM92_TWI_BASE, TWI_MMR,
TWI_MMR_DADR(EE_DEV_ADDR) | TWI_MMR_IADRSZ(2) | TWI_MMR_MREAD);
/* Set TWI Internal Address Register */
WR4HW(AT91RM92_TWI_BASE, TWI_IADR, ee_off);
/* Start transfer */
WR4HW(AT91RM92_TWI_BASE, TWI_CR, TWI_CR_START);
status = RD4HW(AT91RM92_TWI_BASE, TWI_SR);
while (size-- > 1){
/* Wait until Receive Holding Register is full */
count = 1000000;
while (!(RD4HW(AT91RM92_TWI_BASE, TWI_SR) & TWI_SR_RXRDY) &&
--count != 0)
continue;
if (count <= 0)
return -1;
/* Read and store byte */
*bufptr++ = (uint8_t)RD4HW(AT91RM92_TWI_BASE, TWI_RHR);
}
WR4HW(AT91RM92_TWI_BASE, TWI_CR, TWI_CR_STOP);
status = RD4HW(AT91RM92_TWI_BASE, TWI_SR);
/* Wait until transfer is finished */
while (!(RD4HW(AT91RM92_TWI_BASE, TWI_SR) & TWI_SR_TXCOMP))
continue;
/* Read last byte */
*bufptr = (uint8_t)RD4HW(AT91RM92_TWI_BASE, TWI_RHR);
return 0;
}
static int
set_mac_from_idprom(void)
{
#define SIGNATURE_SIZE 4
#define EETYPE_SIZE 2
#define BSLENGTH_SIZE 2
#define RAW_SIZE 52
#define EUI64_SIZE 8
#define BS_SIGNATURE 0x21706d69
#define BSO_SIGNATURE 0x216f7362
#define DEVOFFSET_BSO_SIGNATURE 0x20
#define OFFSET_BS_SIGNATURE 0
#define SIZE_BS_SIGNATURE SIGNATURE_SIZE
#define OFFSET_EETYPE (OFFSET_BS_SIGNATURE + SIZE_BS_SIGNATURE)
#define SIZE_EETYPE EETYPE_SIZE
#define OFFSET_BOOTSECTSIZE (OFFSET_EETYPE + SIZE_EETYPE)
#define SIZE_BOOTSECTSIZE BSLENGTH_SIZE
#define OFFSET_RAW (OFFSET_BOOTSECTSIZE + SIZE_BOOTSECTSIZE)
#define OFFSET_EUI64 (OFFSET_RAW + RAW_SIZE)
#define EE_DEV_ADDR 0xA0 /* eeprom is AT24C256 at address 0xA0 */
int status;
uint32_t dev_offset = 0;
uint32_t sig;
uint8_t eui64[EUI64_SIZE];
uint8_t eaddr[ETHER_ADDR_LEN];
eeprom_init();
/* Check for the boot section signature at offset 0. */
status = eeprom_read(EE_DEV_ADDR, OFFSET_BS_SIGNATURE, &sig, sizeof(sig));
if (status == -1)
return -1;
if (sig != BS_SIGNATURE) {
/* Check for the boot section offset signature. */
status = eeprom_read(EE_DEV_ADDR,
DEVOFFSET_BSO_SIGNATURE, &sig, sizeof(sig));
if ((status == -1) || (sig != BSO_SIGNATURE))
return -1;
/* Read the device offset of the boot section structure. */
status = eeprom_read(EE_DEV_ADDR,
DEVOFFSET_BSO_SIGNATURE + sizeof(sig),
&dev_offset, sizeof(dev_offset));
if (status == -1)
return -1;
/* Check for the boot section signature. */
status = eeprom_read(EE_DEV_ADDR,
dev_offset + OFFSET_BS_SIGNATURE, &sig, sizeof(sig));
if ((status == -1) || (sig != BS_SIGNATURE))
return -1;
}
dev_offset += OFFSET_EUI64;
/* Read the EUI64 from the device. */
if (eeprom_read(EE_DEV_ADDR, dev_offset, eui64, sizeof(eui64)) == -1)
return -1;
/* Transcribe the EUI-64 to a MAC-48.
*
* Given an EUI-64 of aa:bb:cc:dd:ee:ff:gg:hh
*
* if (ff is zero and ee is non-zero)
* mac is aa:bb:cc:ee:gg:hh
* else
* mac is aa:bb:cc:ff:gg:hh
*
* This logic fixes a glitch in our mfg process in which the ff byte was
* always zero and the ee byte contained a non-zero value. This
* resulted in duplicate MAC addresses because we discarded the ee byte.
* Now they've fixed the process so that the ff byte is non-zero and
* unique addresses are formed from the ff:gg:hh bytes. If the ff byte
* is zero, then we have a unit manufactured during the glitch era, and
* we fix the problem by grabbing the ee byte rather than the ff byte.
*/
eaddr[0] = eui64[0];
eaddr[1] = eui64[1];
eaddr[2] = eui64[2];
eaddr[3] = eui64[5];
eaddr[4] = eui64[6];
eaddr[5] = eui64[7];
if (eui64[5] == 0 && eui64[4] != 0) {
eaddr[3] = eui64[4];
}
/*
* Set the address in the hardware regs where the ate driver
* looks for it.
*/
WR4HW(AT91RM92_EMAC_BASE, ETH_SA1L,
(eaddr[3] << 24) | (eaddr[2] << 16) | (eaddr[1] << 8) | eaddr[0]);
WR4HW(AT91RM92_EMAC_BASE, ETH_SA1H,
(eaddr[5] << 8) | (eaddr[4]));
printf(
"ID: EUI-64 %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n"
" MAC-48 %02x:%02x:%02x:%02x:%02x:%02x\n"
" read from i2c device 0x%02X offset 0x%x\n",
eui64[0], eui64[1], eui64[2], eui64[3],
eui64[4], eui64[5], eui64[6], eui64[7],
eaddr[0], eaddr[1], eaddr[2],
eaddr[3], eaddr[4], eaddr[5],
EE_DEV_ADDR, dev_offset);
return (0);
}
/*
* Assign SPI chip select pins based on which chip selects are found in hints.
*/
static void
assign_spi_pins(void)
{
struct {
uint32_t num;
const char * name;
} chipsel_pins[] = {
{ AT91C_PIO_PA3, "PA3", },
{ AT91C_PIO_PA4, "PA4", },
{ AT91C_PIO_PA5, "PA5", },
{ AT91C_PIO_PA6, "PA6", },
};
int anchor = 0;
uint32_t chipsel_inuse = 0;
/*
* Search through all device hints looking for any that have
* ".at=spibus0". For each one found, ensure that there is also a
* chip select hint ".cs=<num>" and that <num> is 0-3, and assign the
* corresponding pin to the SPI peripheral. Whine if we find a SPI
* device with a missing or invalid chipsel hint.
*/
for (;;) {
const char * rName = "";
int unit = 0;
int cs = 0;
int ret;
ret = resource_find_match(&anchor, &rName, &unit, "at", "spibus0");
if (ret != 0)
break;
ret = resource_int_value(rName, unit, "cs", &cs);
if (ret != 0) {
printf( "Error: hint for SPI device %s%d "
"without a chip select hint; "
"device will not function.\n",
rName, unit);
continue;
}
if (cs < 0 || cs > 3) {
printf( "Error: hint for SPI device %s%d "
"contains an invalid chip select "
"value: %d\n",
rName, unit, cs);
continue;
}
if (chipsel_inuse & (1 << cs)) {
printf( "Error: hint for SPI device %s%d "
"specifies chip select %d, which "
"is already used by another device\n",
rName, unit, cs);
continue;
}
chipsel_inuse |= 1 << cs;
at91_pio_use_periph_a(AT91RM92_PIOA_BASE,
chipsel_pins[cs].num, 1);
printf( "Configured pin %s as SPI chip "
"select %d for %s%d\n",
chipsel_pins[cs].name, cs, rName, unit);
}
/*
* If there were hints for any SPI devices, assign the basic SPI IO pins
* and enable SPI power (irq numbers are also device IDs for power).
*/
if (chipsel_inuse != 0) {
at91_pio_use_periph_a(AT91RM92_PIOA_BASE,
AT91C_PIO_PA1 | AT91C_PIO_PA0 | AT91C_PIO_PA2, 0);
WR4HW(AT91RM92_PMC_BASE, PMC_PCER, 1u << AT91RM92_IRQ_SPI);
}
}
BOARD_INIT long
board_init(void)
{
int is_bga, rev_mii;
/*
* Deal with bootinfo (if any) passed in from the boot2 bootloader and
* copied to the static inkernel_bootinfo earlier in the init. Do this
* early so that bootverbose is set from this point on.
*/
if (inkernel_bootinfo.bi_size > 0 &&
(inkernel_bootinfo.bi_flags & RB_BOOTINFO)) {
struct tsc_bootinfo *bip = &inkernel_bootinfo;
printf("TSC_BOOTINFO: size %u howtoflags=0x%08x rootdev='%s'\n",
bip->bi_size, bip->bi_flags, bip->bi_rootdevname);
boothowto = bip->bi_flags;
bootverbose = (boothowto & RB_VERBOSE);
if (bip->bi_rootdevname[0] != 0)
rootdevnames[0] = bip->bi_rootdevname;
}
/*
* The only way to know if we're in a BGA package (and thus have PIOD)
* is to be told via a hint; there's nothing detectable in the silicon.
* This is esentially an rm92-specific extension to getting the chip ID
* (which was done by at91_machdep just before calling this routine).
* If it is the BGA package, enable the clock for PIOD.
*/
is_bga = 0;
resource_int_value("at91", 0, "is_bga_package", &is_bga);
if (is_bga)
WR4HW(AT91RM92_PMC_BASE, PMC_PCER, 1u << AT91RM92_IRQ_PIOD);
#if __FreeBSD_version >= 1000000
at91rm9200_set_subtype(is_bga ? AT91_ST_RM9200_BGA :
AT91_ST_RM9200_PQFP);
#endif
/*
* Go reprogram the MCK frequency based on hints.
*/
master_clock_init();
/* From this point on you can use printf. */
/*
* Configure UARTs.
*/
at91rm9200_config_uart(AT91_ID_DBGU, 0, 0); /* DBGU just Tx and Rx */
at91rm9200_config_uart(AT91RM9200_ID_USART0, 1, 0); /* Tx and Rx */
at91rm9200_config_uart(AT91RM9200_ID_USART1, 2, 0); /* Tx and Rx */
at91rm9200_config_uart(AT91RM9200_ID_USART2, 3, 0); /* Tx and Rx */
at91rm9200_config_uart(AT91RM9200_ID_USART3, 4, 0); /* Tx and Rx */
/*
* Configure MCI (sdcard)
*/
at91rm9200_config_mci(0);
/*
* Assign the pins needed by the emac device, and power it up. Also,
* configure it for RMII operation unless the 'revmii_mode' hint is set,
* in which case configure the full set of MII pins. The revmii_mode
* hint is for so-called reverse-MII, used for connections to a Broadcom
* 5325E switch on some boards. Note that order is important here:
* configure pins, then power on the device, then access the device's
* config registers.
*/
rev_mii = 0;
resource_int_value("ate", 0, "phy_revmii_mode", &rev_mii);
at91_pio_use_periph_a(AT91RM92_PIOA_BASE,
AT91C_PIO_PA7 | AT91C_PIO_PA8 | AT91C_PIO_PA9 |
AT91C_PIO_PA10 | AT91C_PIO_PA11 | AT91C_PIO_PA12 |
AT91C_PIO_PA13 | AT91C_PIO_PA14 | AT91C_PIO_PA15 |
AT91C_PIO_PA16, 0);
if (rev_mii) {
at91_pio_use_periph_b(AT91RM92_PIOB_BASE,
AT91C_PIO_PB12 | AT91C_PIO_PB13 | AT91C_PIO_PB14 |
AT91C_PIO_PB15 | AT91C_PIO_PB16 | AT91C_PIO_PB17 |
AT91C_PIO_PB18 | AT91C_PIO_PB19, 0);
}
WR4HW(AT91RM92_PMC_BASE, PMC_PCER, 1u << AT91RM92_IRQ_EMAC);
if (!rev_mii) {
WR4HW(AT91RM92_EMAC_BASE, ETH_CFG,
RD4HW(AT91RM92_EMAC_BASE, ETH_CFG) | ETH_CFG_RMII);
}
/*
* Get our ethernet MAC address from the ID eeprom.
* Configures TWI as a side effect.
*/
set_mac_from_idprom();
/*
* Configure SPI
*/
assign_spi_pins();
/*
* Configure SSC
*/
at91_pio_use_periph_a(
AT91RM92_PIOB_BASE,
AT91C_PIO_PB6 | AT91C_PIO_PB7 | AT91C_PIO_PB8 | /* transmit */
AT91C_PIO_PB9 | AT91C_PIO_PB10 | AT91C_PIO_PB11, /* receive */
0); /* no pullup */
/*
* We're using TC1's A1 input for PPS measurements that drive the
* kernel PLL and our NTP refclock. On some old boards we route a 5mhz
* signal to TC1's A2 input (pin PA21), but we have never used that
* clock (it rolls over too fast for hz=100), and now newer boards are
* using pin PA21 as a CTS0 for USART1, so we no longer assign it to
* the timer block like we used to here.
*/
at91_pio_use_periph_b(AT91RM92_PIOA_BASE, AT91C_PIO_PA19, 0);
/*
* Configure pins used to bitbang-upload the firmware to the main FPGA.
*/
at91_pio_use_gpio(AT91RM92_PIOB_BASE,
AT91C_PIO_PB16 | AT91C_PIO_PB17 | AT91C_PIO_PB18 | AT91C_PIO_PB19);
return (at91_ramsize());
}
/*
* Override the default boot param parser (supplied via weak linkage) with one
* that knows how to handle our custom tsc_bootinfo passed in from boot2.
*/
vm_offset_t
parse_boot_param(struct arm_boot_params *abp)
{
boot_params = *abp;
/*
* If the right magic is in r0 and a non-NULL pointer is in r1, then
* it's our bootinfo, copy it. The pointer in r1 is a physical address
* passed from boot2. This routine is called immediately upon entry to
* initarm() and is in very nearly the same environment as boot2. In
* particular, va=pa and we can safely copy the args before we lose easy
* access to the memory they're stashed in right now.
*
* Note that all versions of boot2 that we've ever shipped have put
* zeroes into r2 and r3. Maybe that'll be useful some day.
*/
if (abp->abp_r0 == TSC_BOOTINFO_MAGIC && abp->abp_r1 != 0) {
inkernel_bootinfo = *(struct tsc_bootinfo *)(abp->abp_r1);
}
return fake_preload_metadata(abp, NULL, 0);
}
ARM_BOARD(NONE, "TSC4370 Controller Board");

View File

@ -1,73 +0,0 @@
# $FreeBSD$
arm/at91/at91_machdep.c standard
arm/at91/at91_aic.c standard
arm/at91/at91.c standard
arm/at91/at91_aic.c standard
arm/at91/at91_pio.c standard
arm/at91/at91_pmc.c standard
arm/at91/at91_smc.c standard
arm/at91/at91_cfata.c optional at91_cfata
arm/at91/at91_common.c optional fdt
arm/at91/at91_mci.c optional at91_mci
arm/at91/at91_ohci.c optional ohci ! fdt
arm/at91/at91_ohci_fdt.c optional ohci fdt
arm/at91/at91_pinctrl.c optional fdt fdt_pinctrl
arm/at91/at91_pit.c optional at91sam9
arm/at91/at91_reset.S optional at91sam9
arm/at91/at91_rst.c optional at91sam9
arm/at91/at91_rtc.c optional at91_rtc
arm/at91/at91_sdramc.c optional fdt
arm/at91/at91_shdwc.c optional fdt
arm/at91/at91_spi.c optional at91_spi \
dependency "spibus_if.h"
arm/at91/at91_ssc.c optional at91_ssc
arm/at91/at91_st.c optional at91rm9200
arm/at91/at91_tcb.c optional fdt
arm/at91/at91_twi.c optional at91_twi
arm/at91/at91_wdt.c optional at91_wdt
arm/at91/if_ate.c optional ate
arm/at91/if_macb.c optional macb
arm/at91/uart_bus_at91usart.c optional uart ! fdt
arm/at91/uart_cpu_at91usart.c optional uart ! fdt
arm/at91/uart_dev_at91usart.c optional uart
dev/uart/uart_cpu_fdt.c optional uart fdt
dev/nand/nfc_at91.c optional nand
#
# All the "systems on a chip" we support
#
arm/at91/at91soc.c standard
arm/at91/at91rm9200.c optional at91rm9200
arm/at91/at91rm9200_devices.c optional at91rm9200
arm/at91/at91sam9260.c optional at91sam9260
arm/at91/at91sam9g20.c optional at91sam9g20
arm/at91/at91sam9g45.c optional at91sam9g45
arm/at91/at91sam9x5.c optional at91sam9x5
#
# All the boards we support
#
arm/at91/board_bwct.c optional at91_board_bwct
arm/at91/board_eb9200.c optional at91_board_eb9200
arm/at91/board_ethernut5.c optional at91_board_ethernut5
arm/at91/board_hl200.c optional at91_board_hl200
arm/at91/board_hl201.c optional at91_board_hl201
arm/at91/board_kb920x.c optional at91_board_kb920x
arm/at91/board_qila9g20.c optional at91_board_qila9g20
arm/at91/board_sam9260ek.c optional at91_board_sam9260ek
arm/at91/board_sam9g20ek.c optional at91_board_sam9g20ek
arm/at91/board_sam9x25ek.c optional at91_board_sam9x25ek
arm/at91/board_sn9g45.c optional at91_board_sn9g45
arm/at91/board_tsc4370.c optional at91_board_tsc4370
#
# usb
#
# XXX these should likely move to sys/at91 as well. They are also
# XXX slightly inconsistent with sys/conf/files and that ambiguity
# XXX should be fixed when this can be tested on real kit. The dci
# XXX code has hard-coded GPIO pins which is almost certainly wrong.
dev/usb/controller/at91dci.c optional at91_dci
dev/usb/controller/at91dci_atmelarm.c optional at91_dci ! fdt
dev/usb/controller/at91dci_fdt.c optional at91_dci fdt
# We need this for both FDT and !FDT since we use arm_base_bs_ta
# files.arm picks it up for FDT.
arm/arm/bus_space_base.c optional !fdt

File diff suppressed because it is too large Load Diff

View File

@ -1,216 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2006 M. Warner Losh.
*
* 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 ARM_AT91_IF_ATEREG_H
#define ARM_AT91_IF_ATEREG_H
/* Defines beginning ETHB_ are EMACB (newer SAM9 hardware) versions only. */
#define ETH_CTL 0x00 /* EMAC Control Register */
#define ETH_CFG 0x04 /* EMAC Configuration Register */
#define ETH_SR 0x08 /* EMAC STatus Register */
#define ETH_TAR 0x0c /* EMAC Transmit Address Register */
#define ETH_TCR 0x10 /* EMAC Transmit Control Register */
#define ETH_TSR 0x14 /* EMAC Transmit Status Register */
#define ETH_RBQP 0x18 /* EMAC Receive Buffer Queue Pointer */
#define ETHB_TBQP 0x1c /* reserved */
#define ETH_RSR 0x20 /* EMAC Receive Status Register */
#define ETH_ISR 0x24 /* EMAC Interrupt Status Register */
#define ETH_IER 0x28 /* EMAC Interrupt Enable Register */
#define ETH_IDR 0x2c /* EMAC Interrupt Disable Register */
#define ETH_IMR 0x30 /* EMAC Interrupt Mask Register */
#define ETH_MAN 0x34 /* EMAC PHY Maintenance Register */
/* 0x38 reserved */
/* 0x3c reserved */
#define ETH_FRA 0x40 /* Frames Transmitted OK Register */
#define ETH_SCOL 0x44 /* Single Collision Frame Register */
#define ETH_MCOL 0x48 /* Multiple Collision Frame Register */
#define ETH_OK 0x4c /* Frames Received OK Register */
#define ETH_SEQE 0x50 /* Frame Check Sequence Error Reg */
#define ETH_ALE 0x54 /* Alignment Error Register */
#define ETH_DTE 0x58 /* Deferred Transmittion Frame Reg */
#define ETH_LCOL 0x5c /* Late Collision Register */
#define ETH_ECOL 0x60 /* Excessive Collision Register */
#define ETH_TUE 0x64 /* Transmit Underrun Error Register */
#define ETH_CSE 0x68 /* Carrier Sense Error Register */
#define ETH_DRFC 0x6c /* Discarded RX Frame Register */
#define ETH_ROV 0x68 /* Receive Overrun Register */
#define ETH_CDE 0x64 /* Code Error Register */
#define ETH_ELR 0x78 /* Excessive Length Error Register */
#define ETH_RJB 0x7c /* Receive Jabber Register */
#define ETH_USF 0x80 /* Undersize Frame Register */
#define ETH_SQEE 0x84 /* SQE Test Error Register */
/* 0x88 reserved */
/* 0x8c reserved */
#define ETH_HSL 0x90 /* EMAC Hash Address Low [31:0] */
#define ETH_HSH 0x94 /* EMAC Hash Address High [63:32] */
#define ETH_SA1L 0x98 /* EMAC Specific Address 1 Low */
#define ETH_SA1H 0x9c /* EMAC Specific Address 1 High */
#define ETH_SA2L 0xa0 /* EMAC Specific Address 2 Low */
#define ETH_SA2H 0xa4 /* EMAC Specific Address 2 High */
#define ETH_SA3L 0xa8 /* EMAC Specific Address 3 Low */
#define ETH_SA3H 0xac /* EMAC Specific Address 3 High */
#define ETH_SA4L 0xb0 /* EMAC Specific Address 4 Low */
#define ETH_SA4H 0xb4 /* EMAC Specific Address 4 High */
#define ETHB_TID 0xb8 /* EMAC Type ID Checking */
#define ETHB_UIO 0xC0 /* EMAC User I/O Reg */
/* ETH_CTL */
#define ETH_CTL_LB (1U << 0) /* LB: Loopback */
#define ETH_CTL_LBL (1U << 1) /* LBL: Loopback Local */
#define ETH_CTL_RE (1U << 2) /* RE: Receive Enable */
#define ETH_CTL_TE (1U << 3) /* TE: Transmit Enable */
#define ETH_CTL_MPE (1U << 4) /* MPE: Management Port Enable */
#define ETH_CTL_CSR (1U << 5) /* CSR: Clear Statistics Registers */
#define ETH_CTL_ISR (1U << 6) /* ISR: Incremenet Statistics Regs */
#define ETH_CTL_WES (1U << 7) /* WES: Write Enable Statistics regs */
#define ETH_CTL_BP (1U << 8) /* BP: Back Pressure */
#define ETHB_CTL_TGO (1U << 9) /* TGO: Transmitter Start */
#define ETHB_CTL_TSTP (1U << 10) /* TSTP: Transmitter Stop */
/* ETH_CFG */
#define ETH_CFG_SPD (1U << 0) /* SPD: Speed 1 == 100: 0 == 10 */
#define ETH_CFG_FD (1U << 1) /* FD: Full duplex */
#define ETH_CFG_BR (1U << 2) /* BR: Bit Rate (optional?) */
/* bit 3 reserved */
#define ETH_CFG_CAF (1U << 4) /* CAF: Copy All Frames */
#define ETH_CFG_NBC (1U << 5) /* NBC: No Broadcast */
#define ETH_CFG_MTI (1U << 6) /* MTI: Multicast Hash Enable */
#define ETH_CFG_UNI (1U << 7) /* UNI: Unicast Hash Enable */
#define ETH_CFG_BIG (1U << 8) /* BIG: Receive 1522 Bytes */
#define ETH_CFG_EAE (1U << 9) /* EAE: External Address Match En */
#define ETH_CFG_CLK_8 (0U << 10) /* CLK: Clock / 8 */
#define ETH_CFG_CLK_16 (1U << 10) /* CLK: Clock / 16 */
#define ETH_CFG_CLK_32 (2U << 10) /* CLK: Clock / 32 */
#define ETH_CFG_CLK_64 (3U << 10) /* CLK: Clock / 64 */
#define ETH_CFG_RTY (1U << 12) /* RTY: Retry Test*/
#define ETH_CFG_RMII (1U << 13) /* RMII: Reduce MII */
#define ETHB_CFG_JBO (1U << 3) /* JBO: Jumbo Frames */
#define ETHB_CFG_PAE (1U << 13) /* PAE: Pause Enable */
#define ETHB_CFG_RBOF_0 (0U << 14) /* RBOF: Rx Buffer Offset */
#define ETHB_CFG_RBOF_1 (1U << 14) /* RBOF: Rx Buffer Offset */
#define ETHB_CFG_RBOF_2 (3U << 14) /* RBOF: Rx Buffer Offset */
#define ETHB_CFG_RBOF_3 (3U << 14) /* RBOF: Rx Buffer Offset */
#define ETHB_CFG_RCLE (1U << 16) /* RCLE: Rx Length Check Enable */
#define ETHB_CFG_DRFC (1U << 17) /* DRFC: Discard Rx FCS */
#define ETHB_CFG_RHD (1U << 18) /* RHD: RX TX'ed frame in half-duplex */
#define ETHB_CFG_IFCS (1U << 19) /* IFCS: Ignore bad RX FCS */
/* ETH_SR */
#define ETH_SR_LINK (1U << 0) /* Reserved! */
#define ETH_SR_MDIO (1U << 1) /* MDIO pin status */
#define ETH_SR_IDLE (1U << 2) /* IDLE (PHY logic) */
/* ETH_TCR */
#define ETH_TCR_NCRC (1U << 15) /* NCRC: No CRC */
/* ETH_TSR */
#define ETH_TSR_OVR (1U << 0) /* OVR: Ethernet Transmit Overrun */
#define ETH_TSR_COL (1U << 1) /* COL: Collision Occurred */
#define ETH_TSR_RLE (1U << 2) /* RLE: Retry Limit Exceeded */
#define ETH_TSR_IDLE (1U << 3) /* IDLE: Transmitter Idle */
#define ETH_TSR_BNQ (1U << 4) /* BNQ: Enet Tran Buff not Queued */
#define ETH_TSR_COMP (1U << 5) /* COMP: Transmit Complete */
#define ETH_TSR_UND (1U << 6) /* UND: Transmit Underrun */
#define ETH_TSR_WR_MASK (0x67) /* write 1 to clear bits */
/* ETH_RSR */
#define ETH_RSR_BNA (1U << 0) /* BNA: Buffer Not Available */
#define ETH_RSR_REC (1U << 1) /* REC: Frame Received */
#define ETH_RSR_OVR (1U << 2) /* OVR: RX Overrun */
/* ETH_ISR */
#define ETH_ISR_DONE (1U << 0) /* DONE: Management Done */
#define ETH_ISR_RCOM (1U << 1) /* RCOM: Receive Complete */
#define ETH_ISR_RBNA (1U << 2) /* RBNA: Receive Buffer Not Avail */
#define ETH_ISR_TOVR (1U << 3) /* TOVR: Transmit Buffer Overrun */
#define ETH_ISR_TUND (1U << 4) /* TUND: Transmit Buffer Underrun */
#define ETH_ISR_RTRY (1U << 5) /* RTRY: Retry Limit */
#define ETH_ISR_TBRE (1U << 6) /* TBRE: Trasnmit Buffer Reg empty */
#define ETH_ISR_TCOM (1U << 7) /* TCOM: Transmit Complete */
#define ETH_ISR_TIDLE (1U << 8) /* TIDLE: Transmit Idle */
#define ETH_ISR_LINK (1U << 9) /* LINK: Link pin delta (optional) */
#define ETH_ISR_ROVR (1U << 10) /* ROVR: RX Overrun */
#define ETH_ISR_ABT (1U << 11) /* ABT: Abort */
/* ETHB_UIO */
#define ETHB_UIO_RMII (1U << 0) /* RMII: Reduce MII */
#define ETHB_UIO_CLKE (1U << 1) /* CLKE: Clock Enable */
/* ETH_MAN */
#define ETH_MAN_BITS 0x40020000 /* HIGH and CODE bits */
#define ETH_MAN_READ (2U << 28)
#define ETH_MAN_WRITE (1U << 28)
#define ETH_MAN_PHYA_BIT 23
#define ETH_MAN_REGA_BIT 18
#define ETH_MAN_VALUE_MASK 0xffffU
#define ETH_MAN_REG_WR(phy, reg, val) \
(ETH_MAN_BITS | ETH_MAN_WRITE | ((phy) << ETH_MAN_PHYA_BIT) | \
((reg) << ETH_MAN_REGA_BIT) | ((val) & ETH_MAN_VALUE_MASK))
#define ETH_MAN_REG_RD(phy, reg) \
(ETH_MAN_BITS | ETH_MAN_READ | ((phy) << ETH_MAN_PHYA_BIT) | \
((reg) << ETH_MAN_REGA_BIT))
typedef struct {
uint32_t addr;
#define ETH_CPU_OWNER (1U << 0)
#define ETH_WRAP_BIT (1U << 1)
#define ETH_ADR_MASK ~(EHT_CPU_OWNER | ETH_WRAP_BIT)
uint32_t status;
#define ETH_LEN_MASK 0x7ff
#define ETH_BUF_FIRST (1U << 14) /* Packet matched addr 4 */
#define ETH_BUF_LAST (1U << 15) /* Packet matched addr 4 */
#define ETH_MAC_LOCAL_4 (1U << 23) /* Packet matched addr 4 */
#define ETH_MAC_LOCAL_3 (1U << 24) /* Packet matched addr 3 */
#define ETH_MAC_LOCAL_2 (1U << 25) /* Packet matched addr 2 */
#define ETH_MAC_LOCAL_1 (1U << 26) /* Packet matched addr 1 */
#define ETH_MAC_UNK (1U << 27) /* Unknown source address RFU */
#define ETH_MAC_EXT (1U << 28) /* External Address */
#define ETH_MAC_UCAST (1U << 29) /* Unicast hash match */
#define ETH_MAC_MCAST (1U << 30) /* Multicast hash match */
#define ETH_MAC_ONES (1U << 31) /* Global all ones bcast addr */
} eth_rx_desc_t;
typedef struct {
uint32_t addr;
uint32_t status;
#define ETHB_TX_LEN_MASK 0x7ff
#define ETHB_TX_BUF_LAST (1U << 15) /* Last buffer in packet */
#define ETHB_TX_NOCRC (1U << 16) /* Don't xmit CRC*/
#define ETHB_TX_BUFE (1U << 27) /* Buffers exhausted mid frame */
#define ETHB_TX_TUND (1U << 28) /* Transmit Underrun */
#define ETHB_TX_RTRYE (1U << 29) /* Re-try limit exceeded */
#define ETHB_TX_WRAP (1U << 30) /* Last descritor in list */
#define ETHB_TX_USED (1U << 31) /* Packet Transmitted */
} eth_tx_desc_t;
#endif /* ARM_AT91_IF_ATEREG_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,107 +0,0 @@
/*
* $FreeBSD$
*/
#ifndef MACB_REG_H
#define MACB_REG_H
#define EMAC_NCR 0x00
#define EMAC_NCFGR 0x04
#define EMAC_TSR 0x14
#define EMAC_RSR 0x20
#define EMAC_ISR 0x24
#define EMAC_IER 0x28
#define EMAC_IDR 0x2C
#define EMAC_IMR 0x30
#define EMAC_RBQP 0x18
#define EMAC_TBQP 0x1C
#define EMAC_HRB 0x90
#define EMAC_HRT 0x94
#define EMAC_SA1B 0x98
#define EMAC_SA1T 0x9C
#define EMAC_USRIO 0xC0
#define EMAC_MAN 0x34 /* EMAC PHY Maintenance Register */
#define EMAC_SR 0x08 /* EMAC STatus Register */
#define EMAC_SR_LINK (1U << 0) /* Reserved! */
#define EMAC_SR_MDIO (1U << 1) /* MDIO pin status */
#define EMAC_SR_IDLE (1U << 2) /* IDLE (PHY logic) */
#define RX_ENABLE (1 << 2)
#define TX_ENABLE (1 << 3)
#define MPE_ENABLE (1 << 4)
/* EMAC_MAN */
#define EMAC_MAN_BITS 0x40020000 /* HIGH and CODE bits */
#define EMAC_MAN_READ (2U << 28)
#define EMAC_MAN_WRITE (1U << 28)
#define EMAC_MAN_PHYA_BIT 23
#define EMAC_MAN_REGA_BIT 18
#define EMAC_MAN_VALUE_MASK 0xffffU
#define EMAC_MAN_REG_WR(phy, reg, val) \
(EMAC_MAN_BITS | EMAC_MAN_WRITE | ((phy) << EMAC_MAN_PHYA_BIT) | \
((reg) << EMAC_MAN_REGA_BIT) | ((val) & EMAC_MAN_VALUE_MASK))
#define EMAC_MAN_REG_RD(phy, reg) \
(EMAC_MAN_BITS | EMAC_MAN_READ | ((phy) << EMAC_MAN_PHYA_BIT) | \
((reg) << EMAC_MAN_REGA_BIT))
#define RCOMP_INTERRUPT (1 << 1)
#define RXUBR_INTERRUPT (1 << 2)
#define TUBR_INTERRUPT (1 << 3)
#define TUND_INTERRUPT (1 << 4)
#define RLE_INTERRUPT (1 << 5)
#define TXERR_INTERRUPT (1 << 6)
#define ROVR_INTERRUPT (1 << 10)
#define HRESP_INTERRUPT (1 << 11)
#define TCOMP_INTERRUPT (1 << 7)
#define CLEAR_STAT (1 << 5)
#define TRANSMIT_START (1 << 9)
#define TRANSMIT_STOP (1 << 10)
/*Transmit status register flags*/
#define TSR_UND (1 << 6)
#define TSR_COMP (1 << 5)
#define TSR_BEX (1 << 4)
#define TSR_TGO (1 << 3)
#define TSR_RLE (1 << 2)
#define TSR_COL (1 << 1)
#define TSR_UBR (1 << 0)
#define CFG_SPD (1 << 0)
#define CFG_FD (1 << 1)
#define CFG_CAF (1 << 4)
#define CFG_NBC (1 << 5)
#define CFG_MTI (1 << 6)
#define CFG_UNI (1 << 7)
#define CFG_BIG (1 << 8)
#define CFG_CLK_8 (0)
#define CFG_CLK_16 (1)
#define CFG_CLK_32 (2)
#define CFG_CLK_64 (3)
#define CFG_PAE (1 << 13)
#define CFG_RBOF_0 (0 << 14)
#define CFG_RBOF_1 (1 << 14)
#define CFG_RBOF_2 (2 << 14)
#define CFG_RBOF_3 (3 << 14)
#define CFG_DRFCS (1 << 17)
#define USRIO_RMII (1 << 0) /* RMII vs MII pins */
#define USRIO_CLOCK (1 << 1) /* Enable the clock! */
#endif

View File

@ -1,138 +0,0 @@
/*
* $FreeBSD$
*/
#ifndef _IF_MACB_H
#define _IF_MACB_H
#define MACB_MAX_TX_BUFFERS 64
#define MACB_MAX_RX_BUFFERS 256
#define MAX_FRAGMENT 20
#define DATA_SIZE 128
#define MACB_DESC_INC(x, y) ((x) = ((x) + 1) % (y))
#define MACB_TIMEOUT 1000
struct eth_tx_desc {
uint32_t addr;
uint32_t flags;
#define TD_OWN (1U << 31)
#define TD_LAST (1 << 15)
#define TD_WRAP_MASK (1 << 30)
};
struct eth_rx_desc {
uint32_t addr;
#define RD_LEN_MASK 0x7ff
#define RD_WRAP_MASK 0x00000002
#define RD_OWN 0x00000001
uint32_t flags;
#define RD_BROADCAST (1U << 31)
#define RD_MULTICAST (1 << 30)
#define RD_UNICAST (1 << 29)
#define RD_EXTERNAL (1 << 28)
#define RD_TYPE_ID (1 << 22)
#define RD_PRIORITY (1 << 20)
#define RD_VLAN (1 << 21)
#define RD_CONCAT (1 << 16)
#define RD_EOF (1 << 15)
#define RD_SOF (1 << 14)
#define RD_OFFSET_MASK (1 << 13)|(1 << 12)
#define RD_LENGTH_MASK (0x00000FFF)
};
struct rx_desc_info {
struct mbuf *buff;
bus_dmamap_t dmamap;
};
struct tx_desc_info {
struct mbuf *buff;
bus_dmamap_t dmamap;
};
struct macb_chain_data{
struct mbuf *rxhead;
struct mbuf *rxtail;
};
struct macb_softc
{
struct ifnet *ifp; /* ifnet pointer */
struct mtx sc_mtx; /* global mutex */
bus_dma_tag_t sc_parent_tag; /* parent bus DMA tag */
device_t dev; /* Myself */
device_t miibus; /* My child miibus */
void *intrhand; /* Interrupt handle */
void *intrhand_qf; /* queue full */
void *intrhand_tx; /* tx complete */
void *intrhand_status; /* error status */
struct resource *irq_res; /* transmit */
struct resource *irq_res_rec; /* receive */
struct resource *irq_res_qf; /* queue full */
struct resource *irq_res_status; /* status */
struct resource *mem_res; /* Memory resource */
struct callout tick_ch; /* Tick callout */
struct taskqueue *sc_tq;
struct task sc_intr_task;
struct task sc_tx_task;
struct task sc_link_task;
bus_dmamap_t dmamap_ring_tx;
bus_dmamap_t dmamap_ring_rx;
/*dma tag for ring*/
bus_dma_tag_t dmatag_ring_tx;
bus_dma_tag_t dmatag_ring_rx;
/*dma tag for data*/
bus_dma_tag_t dmatag_data_tx;
bus_dma_tag_t dmatag_data_rx;
/*the ring*/
struct eth_tx_desc *desc_tx;
struct eth_rx_desc *desc_rx;
/*ring physical address*/
bus_addr_t ring_paddr_tx;
bus_addr_t ring_paddr_rx;
/*index of last received descriptor*/
int rx_cons;
struct rx_desc_info rx_desc[MACB_MAX_RX_BUFFERS];
/* tx producer index */
uint32_t tx_prod;
/* tx consumer index */
uint32_t tx_cons;
int tx_cnt;
struct tx_desc_info tx_desc[MACB_MAX_TX_BUFFERS];
int macb_watchdog_timer;
#define MACB_FLAG_LINK 0x0001
int flags;
int if_flags;
struct at91_pmc_clock *clk;
struct macb_chain_data macb_cdata;
int clock;
uint32_t use_rmii; /* 0 or USRIO_RMII */
};
#endif

View File

@ -1,11 +0,0 @@
# $FreeBSD$
files "../at91/files.at91"
cpu CPU_ARM9
machine arm
makeoptions CONF_CFLAGS=-mcpu=arm9
options PHYSADDR=0x20000000
options NO_EVENTTIMERS
# For now, just do the AT91RM9200
device at91rm9200

View File

@ -1,11 +0,0 @@
# $FreeBSD$
files "../at91/files.at91"
cpu CPU_ARM9
machine arm
makeoptions CONF_CFLAGS=-mcpu=arm9
options PHYSADDR=0x20000000
options NO_EVENTTIMERS
# bring in the sam specific timers and such
device at91sam9

View File

@ -1,16 +0,0 @@
# $FreeBSD$
#
# Unlike other Atmel SoCs, which have their SDRAM at CS1, the
# at91sam9g45 family has it on CS6, so PHYSADDR must be adjusted
# accordingly. The at91sam9g45, at91sam9g46, at91sam9m10 and at91sam9m11
# SoCs are members of this family.
files "../at91/files.at91"
cpu CPU_ARM9
machine arm
makeoptions CONF_CFLAGS=-mcpu=arm9
options PHYSADDR=0x70000000
options NO_EVENTTIMERS
# bring in the sam specific timers and such
device at91sam9

View File

@ -1,14 +0,0 @@
# $FreeBSD$
include "../at91/std.at91sam9"
# Supported SoCs for the at91 platform
device at91rm9200
device at91sam9260
device at91sam9g20
device at91sam9g45
device at91sam9x5
# bring in the sam specific timers and such
device at91sam9

View File

@ -1,8 +0,0 @@
#$FreeBSD$
include "../at91/std.at91"
makeoptions KERNPHYSADDR=0x20000000
makeoptions KERNVIRTADDR=0xc0000000
options KERNVIRTADDR=0xc0000000
device at91_board_bwct

View File

@ -1,8 +0,0 @@
#$FreeBSD$
include "../at91/std.at91"
makeoptions KERNPHYSADDR=0x20000000
makeoptions KERNVIRTADDR=0xc0000000
options KERNVIRTADDR=0xc0000000
device at91_board_eb9200

View File

@ -1,9 +0,0 @@
# $FreeBSD$
include "../at91/std.at91sam9"
makeoptions KERNPHYSADDR=0x20000000
makeoptions KERNVIRTADDR=0xc0000000
options KERNVIRTADDR=0xc0000000
device at91_board_ethernut5
device at91sam9260

View File

@ -1,8 +0,0 @@
#$FreeBSD$
include "../at91/std.at91"
makeoptions KERNPHYSADDR=0x20100000
makeoptions KERNVIRTADDR=0xc0100000
options KERNVIRTADDR=0xc0100000
device at91_board_hl200

View File

@ -1,9 +0,0 @@
#$FreeBSD$
include "../at91/std.at91sam9"
makeoptions KERNPHYSADDR=0x20000000
makeoptions KERNVIRTADDR=0xc0000000
options KERNVIRTADDR=0xc0000000
device at91_board_hl201
device at91sam9g20

View File

@ -1,8 +0,0 @@
#$FreeBSD$
include "../at91/std.at91"
makeoptions KERNPHYSADDR=0x20000000
makeoptions KERNVIRTADDR=0xc0000000
options KERNVIRTADDR=0xc0000000
device at91_board_kb920x

View File

@ -1,9 +0,0 @@
#$FreeBSD$
include "../at91/std.at91sam9"
makeoptions KERNPHYSADDR=0x20000000
makeoptions KERNVIRTADDR=0xc0000000
options KERNVIRTADDR=0xc0000000
device at91_board_qila9g20
device at91sam9g20

View File

@ -1,9 +0,0 @@
# $FreeBSD$
include "../at91/std.at91sam9"
makeoptions KERNPHYSADDR=0x20000000
makeoptions KERNVIRTADDR=0xc0000000
options KERNVIRTADDR=0xc0000000
device at91_board_sam9260ek
device at91sam9260

View File

@ -1,9 +0,0 @@
#$FreeBSD$
include "../at91/std.at91sam9"
makeoptions KERNPHYSADDR=0x20000000
makeoptions KERNVIRTADDR=0xc0000000
options KERNVIRTADDR=0xc0000000
device at91_board_sam9g20ek
device at91sam9g20

View File

@ -1,9 +0,0 @@
#$FreeBSD$
include "../at91/std.at91sam9"
makeoptions KERNPHYSADDR=0x20000000
makeoptions KERNVIRTADDR=0xc0000000
options KERNVIRTADDR=0xc0000000
device at91_board_sam9x25ek
device at91sam9x5

View File

@ -1,10 +0,0 @@
#$FreeBSD$
include "../at91/std.at91sam9g45"
makeoptions KERNPHYSADDR=0x70008000
makeoptions KERNVIRTADDR=0xc0008000
options KERNVIRTADDR=0xc0008000
device at91sam9g45
device at91_board_sn9g45

View File

@ -1,8 +0,0 @@
#$FreeBSD$
include "../at91/std.at91"
makeoptions KERNPHYSADDR=0x20000000
makeoptions KERNVIRTADDR=0xc0000000
options KERNVIRTADDR=0xc0000000
device at91_board_tsc4370

View File

@ -1,113 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2005 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 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_uart.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <dev/uart/uart.h>
#include <dev/uart/uart_bus.h>
#include <dev/uart/uart_cpu.h>
#include <arm/at91/at91var.h>
#include "uart_if.h"
extern struct uart_class at91_usart_class;
static int usart_at91_probe(device_t dev);
static device_method_t usart_at91_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, usart_at91_probe),
DEVMETHOD(device_attach, uart_bus_attach),
DEVMETHOD(device_detach, uart_bus_detach),
{ 0, 0 }
};
static driver_t usart_at91_driver = {
uart_driver_name,
usart_at91_methods,
sizeof(struct uart_softc),
};
extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
static int
usart_at91_probe(device_t dev)
{
struct uart_softc *sc;
sc = device_get_softc(dev);
switch (device_get_unit(dev))
{
case 0:
device_set_desc(dev, "DBGU");
/*
* Setting sc_sysdev makes this device a 'system device' and
* indirectly makes it the system console.
*/
sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs);
bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
break;
case 1:
device_set_desc(dev, "USART0");
break;
case 2:
device_set_desc(dev, "USART1");
break;
case 3:
device_set_desc(dev, "USART2");
break;
case 4:
device_set_desc(dev, "USART3");
break;
case 5:
device_set_desc(dev, "USART4");
break;
case 6:
device_set_desc(dev, "USART5");
break;
}
sc->sc_class = &at91_usart_class;
if (sc->sc_class->uc_rclk == 0)
sc->sc_class->uc_rclk = at91_master_clock;
return (uart_bus_probe(dev, 0, 0, 0, 0, device_get_unit(dev)));
}
DRIVER_MODULE(uart, atmelarm, usart_at91_driver, uart_devclass, 0, 0);

View File

@ -1,92 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2003 Marcel Moolenaar
* Copyright (c) 2006 M. Warner Losh
* 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 "opt_platform.h"
#include "opt_uart.h"
#ifndef FDT
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/cons.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <machine/bus.h>
#include <dev/uart/uart.h>
#include <dev/uart/uart_bus.h>
#include <dev/uart/uart_cpu.h>
#include <arm/at91/at91var.h>
bus_space_tag_t uart_bus_space_io;
bus_space_tag_t uart_bus_space_mem;
extern struct uart_class at91_usart_class;
int
uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
{
return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0);
}
int
uart_cpu_getdev(int devtype, struct uart_devinfo *di)
{
struct uart_class *class;
class = &at91_usart_class;
if (class->uc_rclk == 0 && at91_master_clock != 0)
class->uc_rclk = at91_master_clock;
di->ops = uart_getops(class);
di->bas.chan = 0;
di->bas.bst = arm_base_bs_tag;
/*
* XXX: Not pretty, but will work because we map the needed addresses
* early. At least we probed this so that the console will work on
* all flavors of Atmel we can detect.
*/
di->bas.bsh = soc_info.dbgu_base;
di->baudrate = 115200;
di->bas.regshft = 0;
di->bas.rclk = 0;
di->databits = 8;
di->stopbits = 1;
di->parity = UART_PARITY_NONE;
uart_bus_space_io = arm_base_bs_tag;
uart_bus_space_mem = NULL;
/* Check the environment for overrides */
uart_getenv(devtype, di, class);
return (0);
}
#endif

View File

@ -1,877 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2005 M. Warner Losh
* Copyright (c) 2005 Olivier Houchard
* Copyright (c) 2012 Ian Lepore
* 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/bus.h>
#include <sys/conf.h>
#include <sys/cons.h>
#include <sys/tty.h>
#include <machine/bus.h>
#include <dev/uart/uart.h>
#include <dev/uart/uart_cpu.h>
#ifdef FDT
#include <dev/uart/uart_cpu_fdt.h>
#endif
#include <dev/uart/uart_bus.h>
#include <arm/at91/at91_usartreg.h>
#include <arm/at91/at91_pdcreg.h>
#include <arm/at91/at91_piovar.h>
#include <arm/at91/at91_pioreg.h>
#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91var.h>
#include "uart_if.h"
#define DEFAULT_RCLK at91_master_clock
#define USART_DEFAULT_FIFO_BYTES 128
#define USART_DCE_CHANGE_BITS (USART_CSR_CTSIC | USART_CSR_DCDIC | \
USART_CSR_DSRIC | USART_CSR_RIIC)
/*
* High-level UART interface.
*/
struct at91_usart_rx {
bus_addr_t pa;
uint8_t *buffer;
bus_dmamap_t map;
};
struct at91_usart_softc {
struct uart_softc base;
bus_dma_tag_t tx_tag;
bus_dmamap_t tx_map;
bus_addr_t tx_paddr;
uint32_t flags;
#define HAS_TIMEOUT 0x1
#define USE_RTS0_WORKAROUND 0x2
bus_dma_tag_t rx_tag;
struct at91_usart_rx ping_pong[2];
struct at91_usart_rx *ping;
struct at91_usart_rx *pong;
};
#define RD4(bas, reg) \
bus_space_read_4((bas)->bst, (bas)->bsh, uart_regofs(bas, reg))
#define WR4(bas, reg, value) \
bus_space_write_4((bas)->bst, (bas)->bsh, uart_regofs(bas, reg), value)
#define SIGCHG(c, i, s, d) \
do { \
if (c) { \
i |= (i & s) ? s : s | d; \
} else { \
i = (i & s) ? (i & ~s) | d : i; \
} \
} while (0);
#define BAUD2DIVISOR(b) \
((((DEFAULT_RCLK * 10) / ((b) * 16)) + 5) / 10)
/*
* Low-level UART interface.
*/
static int at91_usart_probe(struct uart_bas *bas);
static void at91_usart_init(struct uart_bas *bas, int, int, int, int);
static void at91_usart_term(struct uart_bas *bas);
static void at91_usart_putc(struct uart_bas *bas, int);
static int at91_usart_rxready(struct uart_bas *bas);
static int at91_usart_getc(struct uart_bas *bas, struct mtx *hwmtx);
extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
static int
at91_usart_param(struct uart_bas *bas, int baudrate, int databits,
int stopbits, int parity)
{
uint32_t mr;
/*
* Assume 3-wire RS-232 configuration.
* XXX Not sure how uart will present the other modes to us, so
* XXX they are unimplemented. maybe ioctl?
*/
mr = USART_MR_MODE_NORMAL;
mr |= USART_MR_USCLKS_MCK; /* Assume MCK */
/*
* Or in the databits requested
*/
if (databits < 9)
mr &= ~USART_MR_MODE9;
switch (databits) {
case 5:
mr |= USART_MR_CHRL_5BITS;
break;
case 6:
mr |= USART_MR_CHRL_6BITS;
break;
case 7:
mr |= USART_MR_CHRL_7BITS;
break;
case 8:
mr |= USART_MR_CHRL_8BITS;
break;
case 9:
mr |= USART_MR_CHRL_8BITS | USART_MR_MODE9;
break;
default:
return (EINVAL);
}
/*
* Or in the parity
*/
switch (parity) {
case UART_PARITY_NONE:
mr |= USART_MR_PAR_NONE;
break;
case UART_PARITY_ODD:
mr |= USART_MR_PAR_ODD;
break;
case UART_PARITY_EVEN:
mr |= USART_MR_PAR_EVEN;
break;
case UART_PARITY_MARK:
mr |= USART_MR_PAR_MARK;
break;
case UART_PARITY_SPACE:
mr |= USART_MR_PAR_SPACE;
break;
default:
return (EINVAL);
}
/*
* Or in the stop bits. Note: The hardware supports 1.5 stop
* bits in async mode, but there's no way to specify that
* AFAICT. Instead, rely on the convention documented at
* http://www.lammertbies.nl/comm/info/RS-232_specs.html which
* states that 1.5 stop bits are used for 5 bit bytes and
* 2 stop bits only for longer bytes.
*/
if (stopbits == 1)
mr |= USART_MR_NBSTOP_1;
else if (databits > 5)
mr |= USART_MR_NBSTOP_2;
else
mr |= USART_MR_NBSTOP_1_5;
/*
* We want normal plumbing mode too, none of this fancy
* loopback or echo mode.
*/
mr |= USART_MR_CHMODE_NORMAL;
mr &= ~USART_MR_MSBF; /* lsb first */
mr &= ~USART_MR_CKLO_SCK; /* Don't drive SCK */
WR4(bas, USART_MR, mr);
/*
* Set the baud rate (only if we know our master clock rate)
*/
if (DEFAULT_RCLK != 0)
WR4(bas, USART_BRGR, BAUD2DIVISOR(baudrate));
/*
* Set the receive timeout based on the baud rate. The idea is to
* compromise between being responsive on an interactive connection and
* giving a bulk data sender a bit of time to queue up a new buffer
* without mistaking it for a stopping point in the transmission. For
* 19.2kbps and below, use 20 * bit time (2 characters). For faster
* connections use 500 microseconds worth of bits.
*/
if (baudrate <= 19200)
WR4(bas, USART_RTOR, 20);
else
WR4(bas, USART_RTOR, baudrate / 2000);
WR4(bas, USART_CR, USART_CR_STTTO);
/* XXX Need to take possible synchronous mode into account */
return (0);
}
static struct uart_ops at91_usart_ops = {
.probe = at91_usart_probe,
.init = at91_usart_init,
.term = at91_usart_term,
.putc = at91_usart_putc,
.rxready = at91_usart_rxready,
.getc = at91_usart_getc,
};
#ifdef EARLY_PRINTF
/*
* Early printf support. This assumes that we have the SoC "system" devices
* mapped into AT91_BASE. To use this before we adjust the boostrap tables,
* you'll need to define SOCDEV_VA to be 0xdc000000 and SOCDEV_PA to be
* 0xfc000000 in your config file where you define EARLY_PRINTF
*/
volatile uint32_t *at91_dbgu = (volatile uint32_t *)(AT91_BASE + AT91_DBGU0);
static void
eputc(int c)
{
while (!(at91_dbgu[USART_CSR / 4] & USART_CSR_TXRDY))
continue;
at91_dbgu[USART_THR / 4] = c;
}
early_putc_t * early_putc = eputc;
#endif
static int
at91_usart_probe(struct uart_bas *bas)
{
/* We know that this is always here */
return (0);
}
/*
* Initialize this device for use as a console.
*/
static void
at91_usart_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
int parity)
{
#ifdef EARLY_PRINTF
if (early_putc != NULL) {
printf("Early printf yielding control to the real console.\n");
early_putc = NULL;
}
#endif
/*
* This routine is called multiple times, sometimes right after writing
* some output, and the last byte is still shifting out. If that's the
* case delay briefly before resetting, but don't loop on TXRDY because
* we don't want to hang here forever if the hardware is in a bad state.
*/
if (!(RD4(bas, USART_CSR) & USART_CSR_TXRDY))
DELAY(10000);
at91_usart_param(bas, baudrate, databits, stopbits, parity);
/* Reset the rx and tx buffers and turn on rx and tx */
WR4(bas, USART_CR, USART_CR_RSTSTA | USART_CR_RSTRX | USART_CR_RSTTX);
WR4(bas, USART_CR, USART_CR_RXEN | USART_CR_TXEN);
WR4(bas, USART_IDR, 0xffffffff);
}
/*
* Free resources now that we're no longer the console. This appears to
* be never called, and I'm unsure quite what to do if I am called.
*/
static void
at91_usart_term(struct uart_bas *bas)
{
/* XXX */
}
/*
* Put a character of console output (so we do it here polling rather than
* interrupt driven).
*/
static void
at91_usart_putc(struct uart_bas *bas, int c)
{
while (!(RD4(bas, USART_CSR) & USART_CSR_TXRDY))
continue;
WR4(bas, USART_THR, c);
}
/*
* Check for a character available.
*/
static int
at91_usart_rxready(struct uart_bas *bas)
{
return ((RD4(bas, USART_CSR) & USART_CSR_RXRDY) != 0 ? 1 : 0);
}
/*
* Block waiting for a character.
*/
static int
at91_usart_getc(struct uart_bas *bas, struct mtx *hwmtx)
{
int c;
uart_lock(hwmtx);
while (!(RD4(bas, USART_CSR) & USART_CSR_RXRDY)) {
uart_unlock(hwmtx);
DELAY(4);
uart_lock(hwmtx);
}
c = RD4(bas, USART_RHR) & 0xff;
uart_unlock(hwmtx);
return (c);
}
static int at91_usart_bus_probe(struct uart_softc *sc);
static int at91_usart_bus_attach(struct uart_softc *sc);
static int at91_usart_bus_flush(struct uart_softc *, int);
static int at91_usart_bus_getsig(struct uart_softc *);
static int at91_usart_bus_ioctl(struct uart_softc *, int, intptr_t);
static int at91_usart_bus_ipend(struct uart_softc *);
static int at91_usart_bus_param(struct uart_softc *, int, int, int, int);
static int at91_usart_bus_receive(struct uart_softc *);
static int at91_usart_bus_setsig(struct uart_softc *, int);
static int at91_usart_bus_transmit(struct uart_softc *);
static void at91_usart_bus_grab(struct uart_softc *);
static void at91_usart_bus_ungrab(struct uart_softc *);
static kobj_method_t at91_usart_methods[] = {
KOBJMETHOD(uart_probe, at91_usart_bus_probe),
KOBJMETHOD(uart_attach, at91_usart_bus_attach),
KOBJMETHOD(uart_flush, at91_usart_bus_flush),
KOBJMETHOD(uart_getsig, at91_usart_bus_getsig),
KOBJMETHOD(uart_ioctl, at91_usart_bus_ioctl),
KOBJMETHOD(uart_ipend, at91_usart_bus_ipend),
KOBJMETHOD(uart_param, at91_usart_bus_param),
KOBJMETHOD(uart_receive, at91_usart_bus_receive),
KOBJMETHOD(uart_setsig, at91_usart_bus_setsig),
KOBJMETHOD(uart_transmit, at91_usart_bus_transmit),
KOBJMETHOD(uart_grab, at91_usart_bus_grab),
KOBJMETHOD(uart_ungrab, at91_usart_bus_ungrab),
KOBJMETHOD_END
};
int
at91_usart_bus_probe(struct uart_softc *sc)
{
int value;
value = USART_DEFAULT_FIFO_BYTES;
resource_int_value(device_get_name(sc->sc_dev),
device_get_unit(sc->sc_dev), "fifo_bytes", &value);
value = roundup2(value, arm_dcache_align);
sc->sc_txfifosz = value;
sc->sc_rxfifosz = value;
sc->sc_hwiflow = 0;
return (0);
}
static void
at91_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
{
if (error != 0)
return;
*(bus_addr_t *)arg = segs[0].ds_addr;
}
static int
at91_usart_requires_rts0_workaround(struct uart_softc *sc)
{
int value;
int unit;
unit = device_get_unit(sc->sc_dev);
/*
* On the rm9200 chips, the PA21/RTS0 pin is not correctly wired to the
* usart device interally (so-called 'erratum 39', but it's 41.14 in rev
* I of the manual). This prevents use of the hardware flow control
* feature in the usart itself. It also means that if we are to
* implement RTS/CTS flow via the tty layer logic, we must use pin PA21
* as a gpio and manually manipulate it in at91_usart_bus_setsig(). We
* can only safely do so if we've been given permission via a hint,
* otherwise we might manipulate a pin that's attached to who-knows-what
* and Bad Things could happen.
*/
if (at91_is_rm92() && unit == 1) {
value = 0;
resource_int_value(device_get_name(sc->sc_dev), unit,
"use_rts0_workaround", &value);
if (value != 0) {
at91_pio_use_gpio(AT91RM92_PIOA_BASE, AT91C_PIO_PA21);
at91_pio_gpio_output(AT91RM92_PIOA_BASE,
AT91C_PIO_PA21, 1);
at91_pio_use_periph_a(AT91RM92_PIOA_BASE,
AT91C_PIO_PA20, 0);
return (1);
}
}
return (0);
}
static int
at91_usart_bus_attach(struct uart_softc *sc)
{
int err;
int i;
struct at91_usart_softc *atsc;
atsc = (struct at91_usart_softc *)sc;
if (at91_usart_requires_rts0_workaround(sc))
atsc->flags |= USE_RTS0_WORKAROUND;
/*
* See if we have a TIMEOUT bit. We disable all interrupts as
* a side effect. Boot loaders may have enabled them. Since
* a TIMEOUT interrupt can't happen without other setup, the
* apparent race here can't actually happen.
*/
WR4(&sc->sc_bas, USART_IDR, 0xffffffff);
WR4(&sc->sc_bas, USART_IER, USART_CSR_TIMEOUT);
if (RD4(&sc->sc_bas, USART_IMR) & USART_CSR_TIMEOUT)
atsc->flags |= HAS_TIMEOUT;
WR4(&sc->sc_bas, USART_IDR, 0xffffffff);
/*
* Allocate transmit DMA tag and map. We allow a transmit buffer
* to be any size, but it must map to a single contiguous physical
* extent.
*/
err = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
BUS_SPACE_MAXSIZE_32BIT, 1, BUS_SPACE_MAXSIZE_32BIT, 0, NULL,
NULL, &atsc->tx_tag);
if (err != 0)
goto errout;
err = bus_dmamap_create(atsc->tx_tag, 0, &atsc->tx_map);
if (err != 0)
goto errout;
if (bus_dmamap_load(atsc->tx_tag, atsc->tx_map, sc->sc_txbuf,
sc->sc_txfifosz, at91_getaddr, &atsc->tx_paddr, 0) != 0)
goto errout;
if (atsc->flags & HAS_TIMEOUT) {
/*
* Allocate receive DMA tags, maps, and buffers.
* The receive buffers should be aligned to arm_dcache_align,
* otherwise partial cache line flushes on every receive
* interrupt are pretty much guaranteed.
*/
err = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev),
arm_dcache_align, 0, BUS_SPACE_MAXADDR_32BIT,
BUS_SPACE_MAXADDR, NULL, NULL, sc->sc_rxfifosz, 1,
sc->sc_rxfifosz, BUS_DMA_ALLOCNOW, NULL, NULL,
&atsc->rx_tag);
if (err != 0)
goto errout;
for (i = 0; i < 2; i++) {
err = bus_dmamem_alloc(atsc->rx_tag,
(void **)&atsc->ping_pong[i].buffer,
BUS_DMA_NOWAIT, &atsc->ping_pong[i].map);
if (err != 0)
goto errout;
err = bus_dmamap_load(atsc->rx_tag,
atsc->ping_pong[i].map,
atsc->ping_pong[i].buffer, sc->sc_rxfifosz,
at91_getaddr, &atsc->ping_pong[i].pa, 0);
if (err != 0)
goto errout;
bus_dmamap_sync(atsc->rx_tag, atsc->ping_pong[i].map,
BUS_DMASYNC_PREREAD);
}
atsc->ping = &atsc->ping_pong[0];
atsc->pong = &atsc->ping_pong[1];
}
/* Turn on rx and tx */
DELAY(1000); /* Give pending character a chance to drain. */
WR4(&sc->sc_bas, USART_CR, USART_CR_RSTSTA | USART_CR_RSTRX | USART_CR_RSTTX);
WR4(&sc->sc_bas, USART_CR, USART_CR_RXEN | USART_CR_TXEN);
/*
* Setup the PDC to receive data. We use the ping-pong buffers
* so that we can more easily bounce between the two and so that
* we get an interrupt 1/2 way through the software 'fifo' we have
* to avoid overruns.
*/
if (atsc->flags & HAS_TIMEOUT) {
WR4(&sc->sc_bas, PDC_RPR, atsc->ping->pa);
WR4(&sc->sc_bas, PDC_RCR, sc->sc_rxfifosz);
WR4(&sc->sc_bas, PDC_RNPR, atsc->pong->pa);
WR4(&sc->sc_bas, PDC_RNCR, sc->sc_rxfifosz);
WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_RXTEN);
/*
* Set the receive timeout to be 1.5 character times
* assuming 8N1.
*/
WR4(&sc->sc_bas, USART_RTOR, 15);
WR4(&sc->sc_bas, USART_CR, USART_CR_STTTO);
WR4(&sc->sc_bas, USART_IER, USART_CSR_TIMEOUT |
USART_CSR_RXBUFF | USART_CSR_ENDRX);
} else {
WR4(&sc->sc_bas, USART_IER, USART_CSR_RXRDY);
}
WR4(&sc->sc_bas, USART_IER, USART_CSR_RXBRK | USART_DCE_CHANGE_BITS);
/* Prime sc->hwsig with the initial hw line states. */
at91_usart_bus_getsig(sc);
errout:
return (err);
}
static int
at91_usart_bus_transmit(struct uart_softc *sc)
{
struct at91_usart_softc *atsc;
int err;
err = 0;
atsc = (struct at91_usart_softc *)sc;
uart_lock(sc->sc_hwmtx);
bus_dmamap_sync(atsc->tx_tag, atsc->tx_map, BUS_DMASYNC_PREWRITE);
sc->sc_txbusy = 1;
/*
* Setup the PDC to transfer the data and interrupt us when it
* is done. We've already requested the interrupt.
*/
WR4(&sc->sc_bas, PDC_TPR, atsc->tx_paddr);
WR4(&sc->sc_bas, PDC_TCR, sc->sc_txdatasz);
WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_TXTEN);
WR4(&sc->sc_bas, USART_IER, USART_CSR_ENDTX);
uart_unlock(sc->sc_hwmtx);
return (err);
}
static int
at91_usart_bus_setsig(struct uart_softc *sc, int sig)
{
uint32_t new, old, cr;
struct at91_usart_softc *atsc;
atsc = (struct at91_usart_softc *)sc;
do {
old = sc->sc_hwsig;
new = old;
if (sig & SER_DDTR)
SIGCHG(sig & SER_DTR, new, SER_DTR, SER_DDTR);
if (sig & SER_DRTS)
SIGCHG(sig & SER_RTS, new, SER_RTS, SER_DRTS);
} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
cr = 0;
if (new & SER_DTR)
cr |= USART_CR_DTREN;
else
cr |= USART_CR_DTRDIS;
if (new & SER_RTS)
cr |= USART_CR_RTSEN;
else
cr |= USART_CR_RTSDIS;
uart_lock(sc->sc_hwmtx);
WR4(&sc->sc_bas, USART_CR, cr);
if (atsc->flags & USE_RTS0_WORKAROUND) {
/* Signal is active-low. */
if (new & SER_RTS)
at91_pio_gpio_clear(AT91RM92_PIOA_BASE, AT91C_PIO_PA21);
else
at91_pio_gpio_set(AT91RM92_PIOA_BASE,AT91C_PIO_PA21);
}
uart_unlock(sc->sc_hwmtx);
return (0);
}
static int
at91_usart_bus_receive(struct uart_softc *sc)
{
return (0);
}
static int
at91_usart_bus_param(struct uart_softc *sc, int baudrate, int databits,
int stopbits, int parity)
{
return (at91_usart_param(&sc->sc_bas, baudrate, databits, stopbits,
parity));
}
static __inline void
at91_rx_put(struct uart_softc *sc, int key)
{
#if defined(KDB)
if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE)
kdb_alt_break(key, &sc->sc_altbrk);
#endif
uart_rx_put(sc, key);
}
static int
at91_usart_bus_ipend(struct uart_softc *sc)
{
struct at91_usart_softc *atsc;
struct at91_usart_rx *p;
int i, ipend, len;
uint32_t csr;
ipend = 0;
atsc = (struct at91_usart_softc *)sc;
uart_lock(sc->sc_hwmtx);
csr = RD4(&sc->sc_bas, USART_CSR);
if (csr & USART_CSR_OVRE) {
WR4(&sc->sc_bas, USART_CR, USART_CR_RSTSTA);
ipend |= SER_INT_OVERRUN;
}
if (csr & USART_DCE_CHANGE_BITS)
ipend |= SER_INT_SIGCHG;
if (csr & USART_CSR_ENDTX) {
bus_dmamap_sync(atsc->tx_tag, atsc->tx_map,
BUS_DMASYNC_POSTWRITE);
}
if (csr & (USART_CSR_TXRDY | USART_CSR_ENDTX)) {
if (sc->sc_txbusy)
ipend |= SER_INT_TXIDLE;
WR4(&sc->sc_bas, USART_IDR, csr & (USART_CSR_TXRDY |
USART_CSR_ENDTX));
}
/*
* Due to the contraints of the DMA engine present in the
* atmel chip, I can't just say I have a rx interrupt pending
* and do all the work elsewhere. I need to look at the CSR
* bits right now and do things based on them to avoid races.
*/
if (atsc->flags & HAS_TIMEOUT) {
if (csr & USART_CSR_RXBUFF) {
/*
* We have a buffer overflow. Consume data from ping
* and give it back to the hardware before worrying
* about pong, to minimze data loss. Insert an overrun
* marker after the contents of the pong buffer.
*/
WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_RXTDIS);
bus_dmamap_sync(atsc->rx_tag, atsc->ping->map,
BUS_DMASYNC_POSTREAD);
for (i = 0; i < sc->sc_rxfifosz; i++)
at91_rx_put(sc, atsc->ping->buffer[i]);
bus_dmamap_sync(atsc->rx_tag, atsc->ping->map,
BUS_DMASYNC_PREREAD);
WR4(&sc->sc_bas, PDC_RPR, atsc->ping->pa);
WR4(&sc->sc_bas, PDC_RCR, sc->sc_rxfifosz);
WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_RXTEN);
bus_dmamap_sync(atsc->rx_tag, atsc->pong->map,
BUS_DMASYNC_POSTREAD);
for (i = 0; i < sc->sc_rxfifosz; i++)
at91_rx_put(sc, atsc->pong->buffer[i]);
uart_rx_put(sc, UART_STAT_OVERRUN);
bus_dmamap_sync(atsc->rx_tag, atsc->pong->map,
BUS_DMASYNC_PREREAD);
WR4(&sc->sc_bas, PDC_RNPR, atsc->pong->pa);
WR4(&sc->sc_bas, PDC_RNCR, sc->sc_rxfifosz);
ipend |= SER_INT_RXREADY;
} else if (csr & USART_CSR_ENDRX) {
/*
* Consume data from ping of ping pong buffer, but leave
* current pong in place, as it has become the new ping.
* We need to copy data and setup the old ping as the
* new pong when we're done.
*/
bus_dmamap_sync(atsc->rx_tag, atsc->ping->map,
BUS_DMASYNC_POSTREAD);
for (i = 0; i < sc->sc_rxfifosz; i++)
at91_rx_put(sc, atsc->ping->buffer[i]);
p = atsc->ping;
atsc->ping = atsc->pong;
atsc->pong = p;
bus_dmamap_sync(atsc->rx_tag, atsc->pong->map,
BUS_DMASYNC_PREREAD);
WR4(&sc->sc_bas, PDC_RNPR, atsc->pong->pa);
WR4(&sc->sc_bas, PDC_RNCR, sc->sc_rxfifosz);
ipend |= SER_INT_RXREADY;
} else if (csr & USART_CSR_TIMEOUT) {
/*
* On a timeout, one of the following applies:
* 1. Two empty buffers. The last received byte exactly
* filled a buffer, causing an ENDTX that got
* processed earlier; no new bytes have arrived.
* 2. Ping buffer contains some data and pong is empty.
* This should be the most common timeout condition.
* 3. Ping buffer is full and pong is now being filled.
* This is exceedingly rare; it can happen only if
* the ping buffer is almost full when a timeout is
* signaled, and then dataflow resumes and the ping
* buffer filled up between the time we read the
* status register above and the point where the
* RXTDIS takes effect here. Yes, it can happen.
* Because dataflow can resume at any time following a
* timeout (it may have already resumed before we get
* here), it's important to minimize the time the PDC is
* disabled -- just long enough to take the ping buffer
* out of service (so we can consume it) and install the
* pong buffer as the active one. Note that in case 3
* the hardware has already done the ping-pong swap.
*/
WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_RXTDIS);
if (RD4(&sc->sc_bas, PDC_RNCR) == 0) {
len = sc->sc_rxfifosz;
} else {
len = sc->sc_rxfifosz - RD4(&sc->sc_bas, PDC_RCR);
WR4(&sc->sc_bas, PDC_RPR, atsc->pong->pa);
WR4(&sc->sc_bas, PDC_RCR, sc->sc_rxfifosz);
WR4(&sc->sc_bas, PDC_RNCR, 0);
}
WR4(&sc->sc_bas, USART_CR, USART_CR_STTTO);
WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_RXTEN);
bus_dmamap_sync(atsc->rx_tag, atsc->ping->map,
BUS_DMASYNC_POSTREAD);
for (i = 0; i < len; i++)
at91_rx_put(sc, atsc->ping->buffer[i]);
bus_dmamap_sync(atsc->rx_tag, atsc->ping->map,
BUS_DMASYNC_PREREAD);
p = atsc->ping;
atsc->ping = atsc->pong;
atsc->pong = p;
WR4(&sc->sc_bas, PDC_RNPR, atsc->pong->pa);
WR4(&sc->sc_bas, PDC_RNCR, sc->sc_rxfifosz);
ipend |= SER_INT_RXREADY;
}
} else if (csr & USART_CSR_RXRDY) {
/*
* We have another charater in a device that doesn't support
* timeouts, so we do it one character at a time.
*/
at91_rx_put(sc, RD4(&sc->sc_bas, USART_RHR) & 0xff);
ipend |= SER_INT_RXREADY;
}
if (csr & USART_CSR_RXBRK) {
ipend |= SER_INT_BREAK;
WR4(&sc->sc_bas, USART_CR, USART_CR_RSTSTA);
}
uart_unlock(sc->sc_hwmtx);
return (ipend);
}
static int
at91_usart_bus_flush(struct uart_softc *sc, int what)
{
return (0);
}
static int
at91_usart_bus_getsig(struct uart_softc *sc)
{
uint32_t csr, new, old, sig;
/*
* Note that the atmel channel status register DCE status bits reflect
* the electrical state of the lines, not the logical state. Since they
* are logically active-low signals, we invert the tests here.
*/
do {
old = sc->sc_hwsig;
sig = old;
csr = RD4(&sc->sc_bas, USART_CSR);
SIGCHG(!(csr & USART_CSR_DSR), sig, SER_DSR, SER_DDSR);
SIGCHG(!(csr & USART_CSR_CTS), sig, SER_CTS, SER_DCTS);
SIGCHG(!(csr & USART_CSR_DCD), sig, SER_DCD, SER_DDCD);
SIGCHG(!(csr & USART_CSR_RI), sig, SER_RI, SER_DRI);
new = sig & ~SER_MASK_DELTA;
} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
return (sig);
}
static int
at91_usart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
{
switch (request) {
case UART_IOCTL_BREAK:
case UART_IOCTL_IFLOW:
case UART_IOCTL_OFLOW:
break;
case UART_IOCTL_BAUD:
/* only if we know our master clock rate */
if (DEFAULT_RCLK != 0)
WR4(&sc->sc_bas, USART_BRGR,
BAUD2DIVISOR(*(int *)data));
return (0);
}
return (EINVAL);
}
static void
at91_usart_bus_grab(struct uart_softc *sc)
{
uart_lock(sc->sc_hwmtx);
WR4(&sc->sc_bas, USART_IDR, USART_CSR_RXRDY);
uart_unlock(sc->sc_hwmtx);
}
static void
at91_usart_bus_ungrab(struct uart_softc *sc)
{
uart_lock(sc->sc_hwmtx);
WR4(&sc->sc_bas, USART_IER, USART_CSR_RXRDY);
uart_unlock(sc->sc_hwmtx);
}
struct uart_class at91_usart_class = {
"at91_usart",
at91_usart_methods,
sizeof(struct at91_usart_softc),
.uc_ops = &at91_usart_ops,
.uc_range = 8
};
#ifdef FDT
static struct ofw_compat_data compat_data[] = {
{"atmel,at91rm9200-usart",(uintptr_t)&at91_usart_class},
{"atmel,at91sam9260-usart",(uintptr_t)&at91_usart_class},
{NULL, (uintptr_t)NULL},
};
UART_FDT_CLASS_AND_DEVICE(compat_data);
#endif

View File

@ -1,159 +0,0 @@
# Kernel configuration to test compile all the atmel bits with one
# configuration. This kernel will not (presently) boot. Do not copy
# it to create your own custom config file.
#
# $FreeBSD$
ident ATMEL
include "std.arm"
include "../at91/std.atmel"
# Typical values for most SoCs and board configurations. Will not work for
# at91sam9g45 or on some boards with non u-boot boot loaders.
makeoptions KERNPHYSADDR=0x20000000
makeoptions KERNVIRTADDR=0xc0000000
options KERNVIRTADDR=0xc0000000
makeoptions MODULES_OVERRIDE="dtb/atmel"
# list all boards here, but not just yet (no multiboard in mainline).
options ARM_MANY_BOARD
device at91_board_bwct
device at91_board_ethernut5
device at91_board_hl200
device at91_board_hl201
device at91_board_kb920x
device at91_board_qila9g20
device at91_board_sam9260ek
device at91_board_sam9g20ek
device at91_board_sam9x25ek
device at91_board_sn9g45
device at91_board_tsc4370
options SCHED_4BSD # 4BSD scheduler
#options PREEMPTION # Enable kernel thread preemption
options INET # InterNETworking
options INET6 # IPv6 communications protocols
options TCP_HHOOK # hhook(9) framework for TCP
options SCTP # Stream Control Transmission Protocol
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 UFS_GJOURNAL # Enable gjournal-based UFS journaling
options MD_ROOT # MD is a potential root device
options NFSCL # Network Filesystem Client
options NFSD # Network Filesystem Server
options NFSLOCKD # Network Lock Manager
options NFS_ROOT # NFS usable as /, requires NFSCL
options TMPFS # Efficient memory filesystem
options MSDOSFS # MSDOS Filesystem
options CD9660 # ISO 9660 Filesystem
options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
options GEOM_PART_BSD # BSD partition scheme
options GEOM_PART_MBR # MBR partition scheme
options GEOM_PART_GPT # GUID Partition Tables.
options GEOM_LABEL # Provides labelization
options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
options KTRACE # ktrace(1) support
options STACK # stack(9) 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 PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed.
#options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4)
#options AUDIT # Security event auditing
#options CAPABILITY_MODE # Capsicum capability mode
#options CAPABILITIES # Capsicum capabilities
#options MAC # TrustedBSD MAC Framework
#options INCLUDE_CONFIG_FILE # Include this file in kernel
# NFS root from boopt/dhcp
options BOOTP
options BOOTP_NFSROOT
options BOOTP_COMPAT
options BOOTP_NFSV3
options BOOTP_WIRED_TO=ate0
# alternatively, boot from a MMC/SD memory card
#options ROOTDEVNAME=\"ufs:/dev/mmcsd0a\"
# kernel/memory size reduction
options MUTEX_NOINLINE
options NO_FFS_SNAPSHOT
options NO_SWAPPING
options NO_SYSCTL_DESCR
options RWLOCK_NOINLINE
# The `bpf' device enables the Berkeley Packet Filter.
# Be aware of the administrative consequences of enabling this!
# Note that 'bpf' is required for DHCP.
device bpf # Berkeley packet filter
# Ethernet
device mii # Minimal MII support
device ate # Atmel AT91 Ethernet driver
# I2C
device at91_twi # Atmel AT91 Two-wire Interface
device iic # I2C generic I/O device driver
device iicbus # I2C bus system
device pcf8563 # NXP PCF8563 clock/calendar
# MMC/SD
device at91_mci # Atmel AT91 Multimedia Card Interface
options AT91_MCI_HAS_4WIRE
device mmc # MMC/SD bus
device mmcsd # MMC/SD memory card
# DataFlash
device at91_spi # Atmel AT91 Serial Peripheral Interface
device spibus # SPI bus
device at45d # Atmel AT45D
device geom_map # GEOM partition mapping
# Pseudo devices.
device loop # Network loopback
device random # Entropy device
device ether # Ethernet support
device vlan # 802.1Q VLAN support
device tun # Packet tunnel.
device md # Memory "disks"
device gif # IPv6 and IPv4 tunneling
#device firmware # firmware assist module
# SCSI peripherals
device scbus # SCSI bus (required for ATA/SCSI)
device ch # SCSI media changers
device da # Direct Access (disks)
device sa # Sequential Access (tape etc)
device cd # CD
device pass # Passthrough device (direct ATA/SCSI access)
device ses # Enclosure Services (SES and SAF-TE)
#device ctl # CAM Target Layer
# Serial (COM) ports
device uart # Multi-uart driver
# USB support
device ohci # OHCI USB interface
device usb # USB Bus (required)
device umass # Disks/Mass storage - Requires scbus and da
# USB device (gadget) support
device at91_dci # Atmel's usb device
device cdce # emulate an ethernet
device usb_template # Control of the gadget
# watchdog
device at91_wdt # Atmel AT91 Watchdog Timer
device at91_rtc
device at91_ssc
#device at91_tc # missing?
# NAND Flash - Reference design has Samsung 256MB but others possible
device nand # NAND interface on CS3

Some files were not shown because too many files have changed in this diff Show More