summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorcognet <cognet@FreeBSD.org>2010-10-06 22:25:21 +0000
committercognet <cognet@FreeBSD.org>2010-10-06 22:25:21 +0000
commit2edabad8a47c024ddbf097f91202a71b88cff6fc (patch)
treec231f180320438f262879021e2e02bbace0911b3 /sys
parent87987160d6251c2bc94a904a9995d519ac8df5fd (diff)
downloadFreeBSD-src-2edabad8a47c024ddbf097f91202a71b88cff6fc.zip
FreeBSD-src-2edabad8a47c024ddbf097f91202a71b88cff6fc.tar.gz
if_ate.c:
* Support for sam9 "EMAC" controller. * Support for rmii interface to phy. at91.c & at91sam9.c: * Eliminate separate at91sam9.c file. * Add new devices to at91sam9_devs table. at91_machdep.c & at at91sam9_machdep.c: * Automatic chip type determination. * Remove compile time chip dependencies. * Eliminate separate at91sam9_machdep.c file. at91_pmc.c: * Corrected support for all of the sam926? and sam9g20 chips. * Remove compile time chip dependencies. My apologies to Greg for taking so long to take care of it.
Diffstat (limited to 'sys')
-rw-r--r--sys/arm/at91/at91.c369
-rw-r--r--sys/arm/at91/at91_machdep.c85
-rw-r--r--sys/arm/at91/at91_mci.c97
-rw-r--r--sys/arm/at91/at91_pio.c26
-rw-r--r--sys/arm/at91/at91_pio_rm9200.h128
-rw-r--r--sys/arm/at91/at91_pio_sam9.h291
-rw-r--r--sys/arm/at91/at91_pio_sam9g20.h180
-rw-r--r--sys/arm/at91/at91_pioreg.h97
-rw-r--r--sys/arm/at91/at91_pit.c219
-rw-r--r--sys/arm/at91/at91_pmc.c273
-rw-r--r--sys/arm/at91/at91_pmcreg.h31
-rw-r--r--sys/arm/at91/at91_pmcvar.h17
-rw-r--r--sys/arm/at91/at91_reset.S57
-rw-r--r--sys/arm/at91/at91_rst.c215
-rw-r--r--sys/arm/at91/at91_rstreg.h59
-rw-r--r--sys/arm/at91/at91_twi.c1
-rw-r--r--sys/arm/at91/at91_twireg.h5
-rw-r--r--sys/arm/at91/at91_wdt.c222
-rw-r--r--sys/arm/at91/at91_wdtreg.h60
-rw-r--r--sys/arm/at91/at91reg.h70
-rw-r--r--sys/arm/at91/at91rm9200.c330
-rw-r--r--sys/arm/at91/at91rm92reg.h96
-rw-r--r--sys/arm/at91/at91sam9.c717
-rw-r--r--sys/arm/at91/at91sam9_machdep.c420
-rw-r--r--sys/arm/at91/at91sam9g20.c317
-rw-r--r--sys/arm/at91/at91sam9g20reg.h131
-rw-r--r--sys/arm/at91/at91var.h43
-rw-r--r--sys/arm/at91/board_hl201.c27
-rw-r--r--sys/arm/at91/board_kb920x.c9
-rw-r--r--sys/arm/at91/board_sam9g20ek.c176
-rw-r--r--sys/arm/at91/files.at919
-rw-r--r--sys/arm/at91/files.at91sam921
-rw-r--r--sys/arm/at91/if_ate.c714
-rw-r--r--sys/arm/at91/if_atereg.h40
-rw-r--r--sys/arm/at91/if_macb.c28
-rw-r--r--sys/arm/at91/std.at91sam94
-rw-r--r--sys/arm/at91/std.kb920x1
-rw-r--r--sys/arm/at91/std.sam9g20ek11
-rw-r--r--sys/arm/at91/uart_cpu_at91rm9200usart.c4
-rw-r--r--sys/arm/at91/uart_dev_at91usart.c10
40 files changed, 3091 insertions, 2519 deletions
diff --git a/sys/arm/at91/at91.c b/sys/arm/at91/at91.c
index efc731b..e979dcb 100644
--- a/sys/arm/at91/at91.c
+++ b/sys/arm/at91/at91.c
@@ -1,5 +1,6 @@
/*-
* 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
@@ -43,14 +44,23 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/intr.h>
-#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91var.h>
+#include <arm/at91/at91_pmcvar.h>
+#include <arm/at91/at91_aicreg.h>
static struct at91_softc *at91_softc;
static void at91_eoi(void *);
+extern const struct pmap_devmap at91_devmap[];
+
+uint32_t at91_chip_id;
+
+#ifdef AT91C_MASTER_CLOCK
uint32_t at91_master_clock = AT91C_MASTER_CLOCK;
+#else
+uint32_t at91_master_clock;
+#endif
static int
at91_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flags,
@@ -99,6 +109,19 @@ at91_barrier(void *t, bus_space_handle_t bsh, bus_size_t size, bus_size_t b,
{
}
+struct arm32_dma_range *
+bus_dma_get_range(void)
+{
+
+ return (NULL);
+}
+
+int
+bus_dma_get_range_nb(void)
+{
+ return (0);
+}
+
bs_protos(generic);
bs_protos(generic_armv4);
@@ -212,6 +235,7 @@ struct bus_space at91_bs_tag = {
static int
at91_probe(device_t dev)
{
+
device_set_desc(dev, "AT91 device bus");
arm_post_filter = at91_eoi;
return (0);
@@ -224,324 +248,38 @@ at91_identify(driver_t *drv, device_t parent)
BUS_ADD_CHILD(parent, 0, "atmelarm", 0);
}
-struct arm32_dma_range *
-bus_dma_get_range(void)
-{
-
- return (NULL);
-}
-
-int
-bus_dma_get_range_nb(void)
-{
- return (0);
-}
-
-extern void irq_entry(void);
-
-static 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 (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);
- if (addr != 0)
- bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
-}
-
-struct cpu_devs
-{
- const char *name;
- int unit;
- bus_addr_t mem_base;
- bus_size_t mem_len;
- int irq0;
- int irq1;
- int irq2;
-};
-
-struct cpu_devs at91rm9200_devs[] =
-{
- // All the "system" devices
- {
- "at91_st", 0,
- AT91RM92_BASE + AT91RM92_ST_BASE, AT91RM92_ST_SIZE,
- AT91RM92_IRQ_SYSTEM
- },
- {
- "at91_pio", 0,
- AT91RM92_BASE + AT91RM92_PIOA_BASE, AT91RM92_PIO_SIZE,
- AT91RM92_IRQ_SYSTEM
- },
- {
- "at91_pio", 1,
- AT91RM92_BASE + AT91RM92_PIOB_BASE, AT91RM92_PIO_SIZE,
- AT91RM92_IRQ_SYSTEM
- },
- {
- "at91_pio", 2,
- AT91RM92_BASE + AT91RM92_PIOC_BASE, AT91RM92_PIO_SIZE,
- AT91RM92_IRQ_SYSTEM
- },
- {
- "at91_pio", 3,
- AT91RM92_BASE + AT91RM92_PIOD_BASE, AT91RM92_PIO_SIZE,
- AT91RM92_IRQ_SYSTEM
- },
- {
- "at91_pmc", 0,
- AT91RM92_BASE + AT91RM92_PMC_BASE, AT91RM92_PMC_SIZE,
- AT91RM92_IRQ_SYSTEM
- },
- {
- "at91_aic", 0,
- AT91RM92_BASE + AT91RM92_AIC_BASE, AT91RM92_AIC_SIZE,
- 0 // Interrupt controller has no interrupts!
- },
- {
- "at91_rtc", 0,
- AT91RM92_BASE + AT91RM92_RTC_BASE, AT91RM92_RTC_SIZE,
- AT91RM92_IRQ_SYSTEM
- },
- {
- "at91_mc", 0,
- AT91RM92_BASE + AT91RM92_MC_BASE, AT91RM92_MC_SIZE,
- AT91RM92_IRQ_SYSTEM
- },
-
- // All other devices
- {
- "at91_tc", 0,
- AT91RM92_BASE + AT91RM92_TC0_BASE, AT91RM92_TC_SIZE,
- AT91RM92_IRQ_TC0, AT91RM92_IRQ_TC1, AT91RM92_IRQ_TC2
- },
- {
- "at91_tc", 1,
- AT91RM92_BASE + AT91RM92_TC1_BASE, AT91RM92_TC_SIZE,
- AT91RM92_IRQ_TC3, AT91RM92_IRQ_TC4, AT91RM92_IRQ_TC5
- },
- {
- "at91_udp", 0,
- AT91RM92_BASE + AT91RM92_UDP_BASE, AT91RM92_UDP_SIZE,
- AT91RM92_IRQ_UDP, AT91RM92_IRQ_PIOB
- },
- {
- "at91_mci", 0,
- AT91RM92_BASE + AT91RM92_MCI_BASE, AT91RM92_MCI_SIZE,
- AT91RM92_IRQ_MCI
- },
- {
- "at91_twi", 0,
- AT91RM92_BASE + AT91RM92_TWI_BASE, AT91RM92_TWI_SIZE,
- AT91RM92_IRQ_TWI
- },
- {
- "ate", 0,
- AT91RM92_BASE + AT91RM92_EMAC_BASE, AT91RM92_EMAC_SIZE,
- AT91RM92_IRQ_EMAC
- },
-#ifndef SKYEYE_WORKAROUNDS
- {
- "uart", 0,
- AT91RM92_BASE + AT91RM92_DBGU_BASE, AT91RM92_DBGU_SIZE,
- AT91RM92_IRQ_SYSTEM
- },
- {
- "uart", 1,
- AT91RM92_BASE + AT91RM92_USART0_BASE, AT91RM92_USART_SIZE,
- AT91RM92_IRQ_USART0
- },
- {
- "uart", 2,
- AT91RM92_BASE + AT91RM92_USART1_BASE, AT91RM92_USART_SIZE,
- AT91RM92_IRQ_USART1
- },
- {
- "uart", 3,
- AT91RM92_BASE + AT91RM92_USART2_BASE, AT91RM92_USART_SIZE,
- AT91RM92_IRQ_USART2
- },
- {
- "uart", 4,
- AT91RM92_BASE + AT91RM92_USART3_BASE, AT91RM92_USART_SIZE,
- AT91RM92_IRQ_USART3
- },
-#else
- {
- "uart", 0,
- AT91RM92_BASE + AT91RM92_USART0_BASE, AT91RM92_USART_SIZE,
- AT91RM92_IRQ_USART0
- },
-#endif
- {
- "at91_ssc", 0,
- AT91RM92_BASE + AT91RM92_SSC0_BASE, AT91RM92_SSC_SIZE,
- AT91RM92_IRQ_SSC0
- },
- {
- "at91_ssc", 1,
- AT91RM92_BASE + AT91RM92_SSC1_BASE, AT91RM92_SSC_SIZE,
- AT91RM92_IRQ_SSC1
- },
- {
- "at91_ssc", 2,
- AT91RM92_BASE + AT91RM92_SSC2_BASE, AT91RM92_SSC_SIZE,
- AT91RM92_IRQ_SSC2
- },
- {
- "spi", 0,
- AT91RM92_BASE + AT91RM92_SPI_BASE, AT91RM92_SPI_SIZE,
- AT91RM92_IRQ_SPI
- },
- {
- "ohci", 0,
- AT91RM92_OHCI_BASE, AT91RM92_OHCI_SIZE,
- AT91RM92_IRQ_UHP
- },
- {
- "at91_cfata", 0,
- AT91RM92_CF_BASE, AT91RM92_CF_SIZE,
- -1
- },
- { 0, 0, 0, 0, 0 }
-};
-
-static void
-at91_cpu_add_builtin_children(device_t dev, struct at91_softc *sc)
-{
- int i;
- struct cpu_devs *walker;
-
- // XXX should look at the device id in the DBGU register and
- // XXX based on the CPU load in these devices
- for (i = 0, walker = at91rm9200_devs; 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);
- }
-}
-
-#define NORMDEV 50
-
-/*
- * 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 int 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 int
at91_attach(device_t dev)
{
struct at91_softc *sc = device_get_softc(dev);
- int i;
+ const struct pmap_devmap *pdevmap;
at91_softc = sc;
sc->sc_st = &at91_bs_tag;
- sc->sc_sh = AT91RM92_BASE;
+ sc->sc_sh = AT91_BASE;
sc->dev = dev;
- if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91RM92_SYS_BASE,
- AT91RM92_SYS_SIZE, &sc->sc_sys_sh) != 0)
- panic("Enable to map IRQ registers");
+
sc->sc_irq_rman.rm_type = RMAN_ARRAY;
sc->sc_irq_rman.rm_descr = "AT91 IRQs";
- sc->sc_mem_rman.rm_type = RMAN_ARRAY;
- sc->sc_mem_rman.rm_descr = "AT91 Memory";
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");
- if (rman_init(&sc->sc_mem_rman) != 0 ||
- rman_manage_region(&sc->sc_mem_rman, 0xdff00000ul,
- 0xdffffffful) != 0)
+
+ 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");
- if (rman_manage_region(&sc->sc_mem_rman, AT91RM92_OHCI_BASE,
- AT91RM92_OHCI_BASE + AT91RM92_OHCI_SIZE - 1) != 0)
- panic("at91_attach: failed to set up ohci memory");
- if (rman_manage_region(&sc->sc_mem_rman, AT91RM92_CF_BASE,
- AT91RM92_CF_BASE + AT91RM92_CF_SIZE - 1) != 0)
- panic("at91_attach: failed to set up CompactFlash ATA memory");
-
- for (i = 0; i < 32; i++) {
- bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_SVR +
- i * 4, i);
- /* Priority. */
- bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_SMR + i * 4,
- irq_prio[i]);
- if (i < 8)
- bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_EOICR,
- 1);
+ for ( pdevmap = at91_devmap; pdevmap->pd_va != 0; pdevmap++) {
+ if (rman_manage_region(&sc->sc_mem_rman, pdevmap->pd_va,
+ pdevmap->pd_va + pdevmap->pd_size - 1) != 0)
+ panic("at91_attach: failed to set up memory rman");
}
- bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_SPU, 32);
- /* No debug. */
- bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_DCR, 0);
- /* Disable and clear all interrupts. */
- bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_IDCR, 0xffffffff);
- bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_ICCR, 0xffffffff);
-
- /* XXX */
- /* 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 DBGU */
- bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x20c, 0xffffffff);
- /* Disable all interrupts for the SDRAM controller */
- bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xfa8, 0xffffffff);
-
- at91_cpu_add_builtin_children(dev, sc);
+
+
+ /* Our device list will be added automatically by the cpu device
+ * e.g. at91rm9200.c when it is identified. To ensure that the
+ * CPU and PMC are attached first any other "identified" devices
+ * call BUS_ADD_CHILD(9) with an "order" of at least 2. */
bus_generic_probe(dev);
bus_generic_attach(dev);
@@ -630,11 +368,11 @@ at91_setup_intr(device_t dev, device_t child,
{
struct at91_softc *sc = device_get_softc(dev);
- if (rman_get_start(ires) == AT91RM92_IRQ_SYSTEM && filt == NULL)
+ if (rman_get_start(ires) == sc->sc_irq_system && filt == NULL)
panic("All system interrupt ISRs must be FILTER");
BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, filt,
intr, arg, cookiep);
- bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_IECR,
+ bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_IECR,
1 << rman_get_start(ires));
return (0);
}
@@ -645,7 +383,7 @@ at91_teardown_intr(device_t dev, device_t child, struct resource *res,
{
struct at91_softc *sc = device_get_softc(dev);
- bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_IDCR,
+ 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));
}
@@ -697,8 +435,7 @@ arm_mask_irq(uintptr_t nb)
{
bus_space_write_4(at91_softc->sc_st,
- at91_softc->sc_sys_sh, IC_IDCR, 1 << nb);
-
+ at91_softc->sc_aic_sh, IC_IDCR, 1 << nb);
}
int
@@ -708,12 +445,12 @@ arm_get_next_irq(int last __unused)
int irq;
irq = bus_space_read_4(at91_softc->sc_st,
- at91_softc->sc_sys_sh, IC_IVR);
+ at91_softc->sc_aic_sh, IC_IVR);
status = bus_space_read_4(at91_softc->sc_st,
- at91_softc->sc_sys_sh, IC_ISR);
+ at91_softc->sc_aic_sh, IC_ISR);
if (status == 0) {
bus_space_write_4(at91_softc->sc_st,
- at91_softc->sc_sys_sh, IC_EOICR, 1);
+ at91_softc->sc_aic_sh, IC_EOICR, 1);
return (-1);
}
return (irq);
@@ -724,16 +461,15 @@ arm_unmask_irq(uintptr_t nb)
{
bus_space_write_4(at91_softc->sc_st,
- at91_softc->sc_sys_sh, IC_IECR, 1 << nb);
- bus_space_write_4(at91_softc->sc_st, at91_softc->sc_sys_sh,
+ at91_softc->sc_aic_sh, IC_IECR, 1 << nb);
+ bus_space_write_4(at91_softc->sc_st, at91_softc->sc_aic_sh,
IC_EOICR, 0);
-
}
static void
at91_eoi(void *unused)
{
- bus_space_write_4(at91_softc->sc_st, at91_softc->sc_sys_sh,
+ bus_space_write_4(at91_softc->sc_st, at91_softc->sc_aic_sh,
IC_EOICR, 0);
}
@@ -761,6 +497,7 @@ static driver_t at91_driver = {
at91_methods,
sizeof(struct at91_softc),
};
+
static devclass_t at91_devclass;
DRIVER_MODULE(atmelarm, nexus, at91_driver, at91_devclass, 0, 0);
diff --git a/sys/arm/at91/at91_machdep.c b/sys/arm/at91/at91_machdep.c
index 1e63ee6..64536d5 100644
--- a/sys/arm/at91/at91_machdep.c
+++ b/sys/arm/at91/at91_machdep.c
@@ -90,9 +90,10 @@ __FBSDID("$FreeBSD$");
#include <sys/reboot.h>
#include <arm/at91/at91board.h>
+#include <arm/at91/at91var.h>
#include <arm/at91/at91rm92reg.h>
-#include <arm/at91/at91_piovar.h>
-#include <arm/at91/at91_pio_rm9200.h>
+#include <arm/at91/at91sam9g20reg.h>
+#include <arm/at91/at91board.h>
#define KERNEL_PT_SYS 0 /* Page table for mapping proc0 zero page */
#define KERNEL_PT_KERN 1
@@ -140,7 +141,7 @@ static void *boot_arg2;
static struct trapframe proc0_tf;
/* Static device mappings. */
-static const struct pmap_devmap at91rm9200_devmap[] = {
+const struct pmap_devmap at91_devmap[] = {
/*
* Map the on-board devices VA == PA so that we can access them
* with the MMU on or off.
@@ -153,60 +154,88 @@ static const struct pmap_devmap at91rm9200_devmap[] = {
*/
0xdff00000,
0xfff00000,
- 0x100000,
+ 0x00100000,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
- /*
- * We can't just map the OHCI registers VA == PA, because
- * AT91RM92_OHCI_BASE belongs to the userland address space.
+ /* 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_BASE,
AT91RM92_OHCI_PA_BASE,
- AT91RM92_OHCI_SIZE,
+ 0x00100000,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
{
- /* CompactFlash controller. */
+ /* CompactFlash controller. Portion of EBI CS4 1MB */
AT91RM92_CF_BASE,
AT91RM92_CF_PA_BASE,
- AT91RM92_CF_SIZE,
+ 0x00100000,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
+ /* The next two should be good for the 9260, 9261 and 9G20 since
+ * addresses mapping is the same. */
{
- 0,
- 0,
- 0,
- 0,
- 0,
- }
+ /* Internal Memory 1MB */
+ AT91SAM9G20_OHCI_BASE,
+ AT91SAM9G20_OHCI_PA_BASE,
+ 0x00100000,
+ VM_PROT_READ|VM_PROT_WRITE,
+ PTE_NOCACHE,
+ },
+ {
+ /* EBI CS3 256MB */
+ AT91SAM9G20_NAND_BASE,
+ AT91SAM9G20_NAND_PA_BASE,
+ AT91SAM9G20_NAND_SIZE,
+ VM_PROT_READ|VM_PROT_WRITE,
+ PTE_NOCACHE,
+ },
+ { 0, 0, 0, 0, 0, }
};
long
at91_ramsize(void)
{
- uint32_t *SDRAMC = (uint32_t *)(AT91RM92_BASE + AT91RM92_SDRAMC_BASE);
+ uint32_t *SDRAMC = (uint32_t *)(AT91_BASE + AT91RM92_SDRAMC_BASE);
uint32_t cr, mr;
int banks, rows, cols, bw;
- cr = SDRAMC[AT91RM92_SDRAMC_CR / 4];
- mr = SDRAMC[AT91RM92_SDRAMC_MR / 4];
- bw = (mr & AT91RM92_SDRAMC_MR_DBW_16) ? 1 : 2;
- 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;
+ 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 {
+ /* This should be good for the 9260, 9261 and 9G20 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));
}
@@ -326,13 +355,21 @@ initarm(void *arg, void *arg2)
VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
}
- pmap_devmap_bootstrap(l1pagetable, at91rm9200_devmap);
+ pmap_devmap_bootstrap(l1pagetable, at91_devmap);
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
setttb(kernel_l1pt.pv_pa);
cpu_tlb_flushID();
cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
+
cninit();
+
+ /* Get chip id so device drivers know about differences */
+ at91_chip_id = *(volatile uint32_t *)
+ (AT91_BASE + AT91_DBGU_BASE + DBGU_C1R);
+
memsize = board_init();
+
+ printf("memsize = %d\n", memsize);
physmem = memsize / PAGE_SIZE;
/*
diff --git a/sys/arm/at91/at91_mci.c b/sys/arm/at91/at91_mci.c
index 5ca60b9..17cf9c2 100644
--- a/sys/arm/at91/at91_mci.c
+++ b/sys/arm/at91/at91_mci.c
@@ -1,6 +1,7 @@
/*-
* Copyright (c) 2006 Bernd Walter. All rights reserved.
* Copyright (c) 2006 M. Warner Losh. 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
@@ -42,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/queue.h>
#include <sys/resource.h>
#include <sys/rman.h>
+#include <sys/sysctl.h>
#include <sys/time.h>
#include <sys/timetc.h>
#include <sys/watchdog.h>
@@ -52,16 +54,19 @@ __FBSDID("$FreeBSD$");
#include <machine/resource.h>
#include <machine/frame.h>
#include <machine/intr.h>
-#include <arm/at91/at91rm92reg.h>
+
#include <arm/at91/at91var.h>
#include <arm/at91/at91_mcireg.h>
#include <arm/at91/at91_pdcreg.h>
+
#include <dev/mmc/bridge.h>
#include <dev/mmc/mmcreg.h>
#include <dev/mmc/mmcbrvar.h>
#include "mmcbr_if.h"
+#include "opt_at91.h"
+
#define BBSZ 512
struct at91_mci_softc {
@@ -69,8 +74,9 @@ struct at91_mci_softc {
device_t dev;
int sc_cap;
#define CAP_HAS_4WIRE 1 /* Has 4 wire bus */
-#define CAP_NEEDS_BOUNCE 2 /* broken hardware needing bounce */
+#define CAP_NEEDS_BYTESWAP 2 /* broken hardware needing bounce */
int flags;
+ int has_4wire;
#define CMD_STARTED 1
#define STOP_STARTED 2
struct resource *irq_res; /* IRQ resource */
@@ -89,7 +95,7 @@ struct at91_mci_softc {
static inline uint32_t
RD4(struct at91_mci_softc *sc, bus_size_t off)
{
- return bus_read_4(sc->mem_res, off);
+ return (bus_read_4(sc->mem_res, off));
}
static inline void
@@ -140,7 +146,13 @@ at91_mci_init(device_t dev)
WR4(sc, MCI_IDR, 0xffffffff); /* Turn off interrupts */
WR4(sc, MCI_DTOR, MCI_DTOR_DTOMUL_1M | 1);
WR4(sc, MCI_MR, 0x834a); // XXX GROSS HACK FROM LINUX
+#ifndef AT91_MCI_SLOT_B
WR4(sc, MCI_SDCR, 0); /* SLOT A, 1 bit bus */
+#else
+ /* XXX Really should add second "unit" but nobody using using
+ * a two slot card that we know of. XXX */
+ WR4(sc, MCI_SDCR, 1); /* SLOT B, 1 bit bus */
+#endif
}
static void
@@ -165,11 +177,16 @@ static int
at91_mci_attach(device_t dev)
{
struct at91_mci_softc *sc = device_get_softc(dev);
- int err;
+ struct sysctl_ctx_list *sctx;
+ struct sysctl_oid *soid;
device_t child;
+ int err;
sc->dev = dev;
- sc->sc_cap = CAP_NEEDS_BOUNCE;
+
+ sc->sc_cap = 0;
+ if (at91_is_rm92())
+ sc->sc_cap |= CAP_NEEDS_BYTESWAP;
err = at91_mci_activate(dev);
if (err)
goto out;
@@ -201,13 +218,28 @@ at91_mci_attach(device_t dev)
AT91_MCI_LOCK_DESTROY(sc);
goto out;
}
+
+ sctx = device_get_sysctl_ctx(dev);
+ soid = device_get_sysctl_tree(dev);
+ SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "4wire",
+ CTLFLAG_RW, &sc->has_4wire, 0, "has 4 wire SD Card bus");
+
+#ifdef AT91_MCI_HAS_4WIRE
+ sc->has_4wire = 1;
+#endif
+ if (sc->has_4wire)
+ sc->sc_cap |= CAP_HAS_4WIRE;
+
+ sc->host.f_min = at91_master_clock / 512;
sc->host.f_min = 375000;
- sc->host.f_max = at91_master_clock / 2; /* Typically 30MHz */
+ sc->host.f_max = at91_master_clock / 2;
+ if (sc->host.f_max > 50000000)
+ sc->host.f_max = 50000000; /* Limit to 50MHz */
+
sc->host.host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340;
+ sc->host.caps = 0;
if (sc->sc_cap & CAP_HAS_4WIRE)
- sc->host.caps = MMC_CAP_4_BIT_DATA;
- else
- sc->host.caps = 0;
+ sc->host.caps |= MMC_CAP_4_BIT_DATA;
child = device_add_child(dev, "mmc", 0);
device_set_ivars(dev, &sc->host);
err = bus_generic_attach(dev);
@@ -237,11 +269,13 @@ at91_mci_activate(device_t dev)
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_mci_deactivate(dev);
@@ -316,14 +350,16 @@ at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd)
uint32_t *src, *dst;
int i;
struct mmc_data *data;
- struct mmc_request *req;
void *vaddr;
bus_addr_t paddr;
sc->curcmd = cmd;
data = cmd->data;
cmdr = cmd->opcode;
- req = cmd->mrq;
+
+ /* XXX Upper layers don't always set this */
+ cmd->mrq = sc->req;
+
if (MMC_RSP(cmd->flags) == MMC_RSP_NONE)
cmdr |= MCI_CMDR_RSPTYP_NO;
else {
@@ -364,26 +400,30 @@ at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd)
if (cmdr & MCI_CMDR_TRDIR)
vaddr = cmd->data->data;
else {
- if (sc->sc_cap & CAP_NEEDS_BOUNCE) {
- vaddr = sc->bounce_buffer;
- src = (uint32_t *)cmd->data->data;
- dst = (uint32_t *)vaddr;
+ /* Use bounce buffer even if we don't need
+ * byteswap, since buffer may straddle a page
+ * boundry, and we don't handle multi-segment
+ * transfers in hardware.
+ * (page issues seen from 'bsdlabel -w' which
+ * uses raw geom access to the volume).
+ * Greg Ansley (gja (at) ansley.com)
+ */
+ vaddr = sc->bounce_buffer;
+ src = (uint32_t *)cmd->data->data;
+ dst = (uint32_t *)vaddr;
+ if (sc->sc_cap & CAP_NEEDS_BYTESWAP) {
for (i = 0; i < data->len / 4; i++)
dst[i] = bswap32(src[i]);
- }
- else
- vaddr = cmd->data->data;
+ } else
+ memcpy(dst, src, data->len);
}
data->xfer_len = 0;
if (bus_dmamap_load(sc->dmatag, sc->map, vaddr, data->len,
at91_mci_getaddr, &paddr, 0) != 0) {
- if (req->cmd->flags & STOP_STARTED)
- req->stop->error = MMC_ERR_NO_MEMORY;
- else
- req->cmd->error = MMC_ERR_NO_MEMORY;
+ cmd->error = MMC_ERR_NO_MEMORY;
sc->req = NULL;
sc->curcmd = NULL;
- req->done(req);
+ cmd->mrq->done(cmd->mrq);
return;
}
sc->mapped++;
@@ -451,7 +491,7 @@ at91_mci_request(device_t brdev, device_t reqdev, struct mmc_request *req)
// XXX maybe the idea is naive...
if (sc->req != NULL) {
AT91_MCI_UNLOCK(sc);
- return EBUSY;
+ return (EBUSY);
}
sc->req = req;
sc->flags = 0;
@@ -503,7 +543,7 @@ at91_mci_read_done(struct at91_mci_softc *sc)
bus_dmamap_sync(sc->dmatag, sc->map, BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(sc->dmatag, sc->map);
sc->mapped--;
- if (sc->sc_cap & CAP_NEEDS_BOUNCE) {
+ if (sc->sc_cap & CAP_NEEDS_BYTESWAP) {
walker = (uint32_t *)cmd->data->data;
len = cmd->data->len / 4;
for (i = 0; i < len; i++)
@@ -653,6 +693,13 @@ at91_mci_read_ivar(device_t bus, device_t child, int which, uintptr_t *result)
*(int *)result = sc->host.ios.vdd;
break;
case MMCBR_IVAR_CAPS:
+ if (sc->has_4wire) {
+ sc->sc_cap |= CAP_HAS_4WIRE;
+ sc->host.caps |= MMC_CAP_4_BIT_DATA;
+ } else {
+ sc->sc_cap &= ~CAP_HAS_4WIRE;
+ sc->host.caps &= ~MMC_CAP_4_BIT_DATA;
+ }
*(int *)result = sc->host.caps;
break;
case MMCBR_IVAR_MAX_DATA:
diff --git a/sys/arm/at91/at91_pio.c b/sys/arm/at91/at91_pio.c
index e141212..853e588 100644
--- a/sys/arm/at91/at91_pio.c
+++ b/sys/arm/at91/at91_pio.c
@@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <machine/bus.h>
-#include <arm/at91/at91rm92reg.h>
+#include <arm/at91/at91reg.h>
#include <arm/at91/at91_pioreg.h>
#include <arm/at91/at91_piovar.h>
@@ -58,7 +58,7 @@ struct at91_pio_softc
static inline uint32_t
RD4(struct at91_pio_softc *sc, bus_size_t off)
{
- return bus_read_4(sc->mem_res, off);
+ return (bus_read_4(sc->mem_res, off));
}
static inline void
@@ -283,7 +283,7 @@ at91_pio_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
void
at91_pio_use_periph_a(uint32_t pio, uint32_t periph_a_mask, int use_pullup)
{
- uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
+ uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
PIO[PIO_ASR / 4] = periph_a_mask;
PIO[PIO_PDR / 4] = periph_a_mask;
@@ -296,7 +296,7 @@ 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)
{
- uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
+ uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
PIO[PIO_BSR / 4] = periph_b_mask;
PIO[PIO_PDR / 4] = periph_b_mask;
@@ -309,7 +309,7 @@ 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)
{
- uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
+ uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
PIO[PIO_PER / 4] = gpio_mask;
}
@@ -317,7 +317,7 @@ at91_pio_use_gpio(uint32_t pio, uint32_t gpio_mask)
void
at91_pio_gpio_input(uint32_t pio, uint32_t input_enable_mask)
{
- uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
+ uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
PIO[PIO_ODR / 4] = input_enable_mask;
}
@@ -325,7 +325,7 @@ 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)
{
- uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
+ uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
PIO[PIO_OER / 4] = output_enable_mask;
if (use_pullup)
@@ -337,7 +337,7 @@ at91_pio_gpio_output(uint32_t pio, uint32_t output_enable_mask, int use_pullup)
void
at91_pio_gpio_set(uint32_t pio, uint32_t data_mask)
{
- uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
+ uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
PIO[PIO_SODR / 4] = data_mask;
}
@@ -345,7 +345,7 @@ 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 *PIO = (uint32_t *)(AT91RM92_BASE + pio);
+ uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
PIO[PIO_CODR / 4] = data_mask;
}
@@ -353,7 +353,7 @@ at91_pio_gpio_clear(uint32_t pio, uint32_t data_mask)
uint8_t
at91_pio_gpio_get(uint32_t pio, uint32_t data_mask)
{
- uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
+ uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
data_mask &= PIO[PIO_PDSR / 4];
@@ -363,7 +363,7 @@ 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)
{
- uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
+ uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
if (use_deglitch)
PIO[PIO_IFER / 4] = data_mask;
@@ -376,7 +376,7 @@ void
at91_pio_gpio_set_interrupt(uint32_t pio, uint32_t data_mask,
int enable_interrupt)
{
- uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
+ uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
if (enable_interrupt)
PIO[PIO_IER / 4] = data_mask;
@@ -388,7 +388,7 @@ at91_pio_gpio_set_interrupt(uint32_t pio, uint32_t data_mask,
uint32_t
at91_pio_gpio_clear_interrupt(uint32_t pio)
{
- uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
+ uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
/* reading this register will clear the interrupts */
return (PIO[PIO_ISR / 4]);
}
diff --git a/sys/arm/at91/at91_pio_rm9200.h b/sys/arm/at91/at91_pio_rm9200.h
index 16d1ccb..fa4fae3 100644
--- a/sys/arm/at91/at91_pio_rm9200.h
+++ b/sys/arm/at91/at91_pio_rm9200.h
@@ -1,5 +1,9 @@
/* $FreeBSD$ */
+#ifndef ARM_AT91_AT91_PIO_RM9200_H
+#define ARM_AT91_AT91_PIO_RM9200_H
+
+#include <arm/at91/at91_pioreg.h>
/*
* These defines come from an atmel file that says specifically that it
* has no copyright.
@@ -8,317 +12,197 @@
//*****************************************************************************
// PIO DEFINITIONS FOR AT91RM9200
//*****************************************************************************
-#define AT91C_PIO_PA0 (1u << 0) // Pin Controlled by PA0
#define AT91C_PA0_MISO (AT91C_PIO_PA0) // SPI Master In Slave
#define AT91C_PA0_PCK3 (AT91C_PIO_PA0) // PMC Programmable Clock Output 3
-#define AT91C_PIO_PA1 (1u << 1) // Pin Controlled by PA1
#define AT91C_PA1_MOSI (AT91C_PIO_PA1) // SPI Master Out Slave
#define AT91C_PA1_PCK0 (AT91C_PIO_PA1) // PMC Programmable Clock Output 0
-#define AT91C_PIO_PA10 (1u << 10) // Pin Controlled by PA10
#define AT91C_PA10_ETX1 (AT91C_PIO_PA10) // Ethernet MAC Transmit Data 1
#define AT91C_PA10_MCDB1 (AT91C_PIO_PA10) // Multimedia Card B Data 1
-#define AT91C_PIO_PA11 (1u << 11) // Pin Controlled by PA11
#define AT91C_PA11_ECRS_ECRSDV (AT91C_PIO_PA11) // Ethernet MAC Carrier Sense/Carrier Sense and Data Valid
#define AT91C_PA11_MCDB2 (AT91C_PIO_PA11) // Multimedia Card B Data 2
-#define AT91C_PIO_PA12 (1u << 12) // Pin Controlled by PA12
#define AT91C_PA12_ERX0 (AT91C_PIO_PA12) // Ethernet MAC Receive Data 0
#define AT91C_PA12_MCDB3 (AT91C_PIO_PA12) // Multimedia Card B Data 3
-#define AT91C_PIO_PA13 (1u << 13) // Pin Controlled by PA13
#define AT91C_PA13_ERX1 (AT91C_PIO_PA13) // Ethernet MAC Receive Data 1
#define AT91C_PA13_TCLK0 (AT91C_PIO_PA13) // Timer Counter 0 external clock input
-#define AT91C_PIO_PA14 (1u << 14) // Pin Controlled by PA14
#define AT91C_PA14_ERXER (AT91C_PIO_PA14) // Ethernet MAC Receive Error
#define AT91C_PA14_TCLK1 (AT91C_PIO_PA14) // Timer Counter 1 external clock input
-#define AT91C_PIO_PA15 (1u << 15) // Pin Controlled by PA15
#define AT91C_PA15_EMDC (AT91C_PIO_PA15) // Ethernet MAC Management Data Clock
#define AT91C_PA15_TCLK2 (AT91C_PIO_PA15) // Timer Counter 2 external clock input
-#define AT91C_PIO_PA16 (1u << 16) // Pin Controlled by PA16
#define AT91C_PA16_EMDIO (AT91C_PIO_PA16) // Ethernet MAC Management Data Input/Output
#define AT91C_PA16_IRQ6 (AT91C_PIO_PA16) // AIC Interrupt input 6
-#define AT91C_PIO_PA17 (1u << 17) // Pin Controlled by PA17
#define AT91C_PA17_TXD0 (AT91C_PIO_PA17) // USART 0 Transmit Data
#define AT91C_PA17_TIOA0 (AT91C_PIO_PA17) // Timer Counter 0 Multipurpose Timer I/O Pin A
-#define AT91C_PIO_PA18 (1u << 18) // Pin Controlled by PA18
#define AT91C_PA18_RXD0 (AT91C_PIO_PA18) // USART 0 Receive Data
#define AT91C_PA18_TIOB0 (AT91C_PIO_PA18) // Timer Counter 0 Multipurpose Timer I/O Pin B
-#define AT91C_PIO_PA19 (1u << 19) // Pin Controlled by PA19
#define AT91C_PA19_SCK0 (AT91C_PIO_PA19) // USART 0 Serial Clock
#define AT91C_PA19_TIOA1 (AT91C_PIO_PA19) // Timer Counter 1 Multipurpose Timer I/O Pin A
-#define AT91C_PIO_PA2 (1u << 2) // Pin Controlled by PA2
#define AT91C_PA2_SPCK (AT91C_PIO_PA2) // SPI Serial Clock
#define AT91C_PA2_IRQ4 (AT91C_PIO_PA2) // AIC Interrupt Input 4
-#define AT91C_PIO_PA20 (1u << 20) // Pin Controlled by PA20
#define AT91C_PA20_CTS0 (AT91C_PIO_PA20) // USART 0 Clear To Send
#define AT91C_PA20_TIOB1 (AT91C_PIO_PA20) // Timer Counter 1 Multipurpose Timer I/O Pin B
-#define AT91C_PIO_PA21 (1u << 21) // Pin Controlled by PA21
#define AT91C_PA21_RTS0 (AT91C_PIO_PA21) // Usart 0 Ready To Send
#define AT91C_PA21_TIOA2 (AT91C_PIO_PA21) // Timer Counter 2 Multipurpose Timer I/O Pin A
-#define AT91C_PIO_PA22 (1u << 22) // Pin Controlled by PA22
#define AT91C_PA22_RXD2 (AT91C_PIO_PA22) // USART 2 Receive Data
#define AT91C_PA22_TIOB2 (AT91C_PIO_PA22) // Timer Counter 2 Multipurpose Timer I/O Pin B
-#define AT91C_PIO_PA23 (1u << 23) // Pin Controlled by PA23
#define AT91C_PA23_TXD2 (AT91C_PIO_PA23) // USART 2 Transmit Data
#define AT91C_PA23_IRQ3 (AT91C_PIO_PA23) // Interrupt input 3
-#define AT91C_PIO_PA24 (1u << 24) // Pin Controlled by PA24
#define AT91C_PA24_SCK2 (AT91C_PIO_PA24) // USART2 Serial Clock
#define AT91C_PA24_PCK1 (AT91C_PIO_PA24) // PMC Programmable Clock Output 1
-#define AT91C_PIO_PA25 (1u << 25) // Pin Controlled by PA25
#define AT91C_PA25_TWD (AT91C_PIO_PA25) // TWI Two-wire Serial Data
#define AT91C_PA25_IRQ2 (AT91C_PIO_PA25) // Interrupt input 2
-#define AT91C_PIO_PA26 (1u << 26) // Pin Controlled by PA26
#define AT91C_PA26_TWCK (AT91C_PIO_PA26) // TWI Two-wire Serial Clock
#define AT91C_PA26_IRQ1 (AT91C_PIO_PA26) // Interrupt input 1
-#define AT91C_PIO_PA27 (1u << 27) // Pin Controlled by PA27
#define AT91C_PA27_MCCK (AT91C_PIO_PA27) // Multimedia Card Clock
#define AT91C_PA27_TCLK3 (AT91C_PIO_PA27) // Timer Counter 3 External Clock Input
-#define AT91C_PIO_PA28 (1u << 28) // Pin Controlled by PA28
#define AT91C_PA28_MCCDA (AT91C_PIO_PA28) // Multimedia Card A Command
#define AT91C_PA28_TCLK4 (AT91C_PIO_PA28) // Timer Counter 4 external Clock Input
-#define AT91C_PIO_PA29 (1u << 29) // Pin Controlled by PA29
#define AT91C_PA29_MCDA0 (AT91C_PIO_PA29) // Multimedia Card A Data 0
#define AT91C_PA29_TCLK5 (AT91C_PIO_PA29) // Timer Counter 5 external clock input
-#define AT91C_PIO_PA3 (1u << 3) // Pin Controlled by PA3
#define AT91C_PA3_NPCS0 (AT91C_PIO_PA3) // SPI Peripheral Chip Select 0
#define AT91C_PA3_IRQ5 (AT91C_PIO_PA3) // AIC Interrupt Input 5
-#define AT91C_PIO_PA30 (1u << 30) // Pin Controlled by PA30
#define AT91C_PA30_DRXD (AT91C_PIO_PA30) // DBGU Debug Receive Data
#define AT91C_PA30_CTS2 (AT91C_PIO_PA30) // Usart 2 Clear To Send
-#define AT91C_PIO_PA31 (1u << 31) // Pin Controlled by PA31
#define AT91C_PA31_DTXD (AT91C_PIO_PA31) // DBGU Debug Transmit Data
#define AT91C_PA31_RTS2 (AT91C_PIO_PA31) // USART 2 Ready To Send
-#define AT91C_PIO_PA4 (1u << 4) // Pin Controlled by PA4
#define AT91C_PA4_NPCS1 (AT91C_PIO_PA4) // SPI Peripheral Chip Select 1
#define AT91C_PA4_PCK1 (AT91C_PIO_PA4) // PMC Programmable Clock Output 1
-#define AT91C_PIO_PA5 (1u << 5) // Pin Controlled by PA5
#define AT91C_PA5_NPCS2 (AT91C_PIO_PA5) // SPI Peripheral Chip Select 2
#define AT91C_PA5_TXD3 (AT91C_PIO_PA5) // USART 3 Transmit Data
-#define AT91C_PIO_PA6 (1u << 6) // Pin Controlled by PA6
#define AT91C_PA6_NPCS3 (AT91C_PIO_PA6) // SPI Peripheral Chip Select 3
#define AT91C_PA6_RXD3 (AT91C_PIO_PA6) // USART 3 Receive Data
-#define AT91C_PIO_PA7 (1u << 7) // Pin Controlled by PA7
#define AT91C_PA7_ETXCK_EREFCK (AT91C_PIO_PA7) // Ethernet MAC Transmit Clock/Reference Clock
#define AT91C_PA7_PCK2 (AT91C_PIO_PA7) // PMC Programmable Clock 2
-#define AT91C_PIO_PA8 (1u << 8) // Pin Controlled by PA8
#define AT91C_PA8_ETXEN (AT91C_PIO_PA8) // Ethernet MAC Transmit Enable
#define AT91C_PA8_MCCDB (AT91C_PIO_PA8) // Multimedia Card B Command
-#define AT91C_PIO_PA9 (1u << 9) // Pin Controlled by PA9
#define AT91C_PA9_ETX0 (AT91C_PIO_PA9) // Ethernet MAC Transmit Data 0
#define AT91C_PA9_MCDB0 (AT91C_PIO_PA9) // Multimedia Card B Data 0
-#define AT91C_PIO_PB0 (1u << 0) // Pin Controlled by PB0
#define AT91C_PB0_TF0 (AT91C_PIO_PB0) // SSC Transmit Frame Sync 0
#define AT91C_PB0_TIOB3 (AT91C_PIO_PB0) // Timer Counter 3 Multipurpose Timer I/O Pin B
-#define AT91C_PIO_PB1 (1u << 1) // Pin Controlled by PB1
#define AT91C_PB1_TK0 (AT91C_PIO_PB1) // SSC Transmit Clock 0
#define AT91C_PB1_CTS3 (AT91C_PIO_PB1) // USART 3 Clear To Send
-#define AT91C_PIO_PB10 (1u << 10) // Pin Controlled by PB10
#define AT91C_PB10_RK1 (AT91C_PIO_PB10) // SSC Receive Clock 1
#define AT91C_PB10_TIOA5 (AT91C_PIO_PB10) // Timer Counter 5 Multipurpose Timer I/O Pin A
-#define AT91C_PIO_PB11 (1u << 11) // Pin Controlled by PB11
#define AT91C_PB11_RF1 (AT91C_PIO_PB11) // SSC Receive Frame Sync 1
#define AT91C_PB11_TIOB5 (AT91C_PIO_PB11) // Timer Counter 5 Multipurpose Timer I/O Pin B
-#define AT91C_PIO_PB12 (1u << 12) // Pin Controlled by PB12
#define AT91C_PB12_TF2 (AT91C_PIO_PB12) // SSC Transmit Frame Sync 2
#define AT91C_PB12_ETX2 (AT91C_PIO_PB12) // Ethernet MAC Transmit Data 2
-#define AT91C_PIO_PB13 (1u << 13) // Pin Controlled by PB13
#define AT91C_PB13_TK2 (AT91C_PIO_PB13) // SSC Transmit Clock 2
#define AT91C_PB13_ETX3 (AT91C_PIO_PB13) // Ethernet MAC Transmit Data 3
-#define AT91C_PIO_PB14 (1u << 14) // Pin Controlled by PB14
#define AT91C_PB14_TD2 (AT91C_PIO_PB14) // SSC Transmit Data 2
#define AT91C_PB14_ETXER (AT91C_PIO_PB14) // Ethernet MAC Transmikt Coding Error
-#define AT91C_PIO_PB15 (1u << 15) // Pin Controlled by PB15
#define AT91C_PB15_RD2 (AT91C_PIO_PB15) // SSC Receive Data 2
#define AT91C_PB15_ERX2 (AT91C_PIO_PB15) // Ethernet MAC Receive Data 2
-#define AT91C_PIO_PB16 (1u << 16) // Pin Controlled by PB16
#define AT91C_PB16_RK2 (AT91C_PIO_PB16) // SSC Receive Clock 2
#define AT91C_PB16_ERX3 (AT91C_PIO_PB16) // Ethernet MAC Receive Data 3
-#define AT91C_PIO_PB17 (1u << 17) // Pin Controlled by PB17
#define AT91C_PB17_RF2 (AT91C_PIO_PB17) // SSC Receive Frame Sync 2
#define AT91C_PB17_ERXDV (AT91C_PIO_PB17) // Ethernet MAC Receive Data Valid
-#define AT91C_PIO_PB18 (1u << 18) // Pin Controlled by PB18
#define AT91C_PB18_RI1 (AT91C_PIO_PB18) // USART 1 Ring Indicator
#define AT91C_PB18_ECOL (AT91C_PIO_PB18) // Ethernet MAC Collision Detected
-#define AT91C_PIO_PB19 (1u << 19) // Pin Controlled by PB19
#define AT91C_PB19_DTR1 (AT91C_PIO_PB19) // USART 1 Data Terminal ready
#define AT91C_PB19_ERXCK (AT91C_PIO_PB19) // Ethernet MAC Receive Clock
-#define AT91C_PIO_PB2 (1u << 2) // Pin Controlled by PB2
#define AT91C_PB2_TD0 (AT91C_PIO_PB2) // SSC Transmit data
#define AT91C_PB2_SCK3 (AT91C_PIO_PB2) // USART 3 Serial Clock
-#define AT91C_PIO_PB20 (1u << 20) // Pin Controlled by PB20
#define AT91C_PB20_TXD1 (AT91C_PIO_PB20) // USART 1 Transmit Data
-#define AT91C_PIO_PB21 (1u << 21) // Pin Controlled by PB21
#define AT91C_PB21_RXD1 (AT91C_PIO_PB21) // USART 1 Receive Data
-#define AT91C_PIO_PB22 (1u << 22) // Pin Controlled by PB22
#define AT91C_PB22_SCK1 (AT91C_PIO_PB22) // USART1 Serial Clock
-#define AT91C_PIO_PB23 (1u << 23) // Pin Controlled by PB23
#define AT91C_PB23_DCD1 (AT91C_PIO_PB23) // USART 1 Data Carrier Detect
-#define AT91C_PIO_PB24 (1u << 24) // Pin Controlled by PB24
#define AT91C_PB24_CTS1 (AT91C_PIO_PB24) // USART 1 Clear To Send
-#define AT91C_PIO_PB25 (1u << 25) // Pin Controlled by PB25
#define AT91C_PB25_DSR1 (AT91C_PIO_PB25) // USART 1 Data Set ready
#define AT91C_PB25_EF100 (AT91C_PIO_PB25) // Ethernet MAC Force 100 Mbits/sec
-#define AT91C_PIO_PB26 (1u << 26) // Pin Controlled by PB26
#define AT91C_PB26_RTS1 (AT91C_PIO_PB26) // Usart 0 Ready To Send
-#define AT91C_PIO_PB27 (1u << 27) // Pin Controlled by PB27
#define AT91C_PB27_PCK0 (AT91C_PIO_PB27) // PMC Programmable Clock Output 0
-#define AT91C_PIO_PB28 (1u << 28) // Pin Controlled by PB28
#define AT91C_PB28_FIQ (AT91C_PIO_PB28) // AIC Fast Interrupt Input
-#define AT91C_PIO_PB29 (1u << 29) // Pin Controlled by PB29
#define AT91C_PB29_IRQ0 (AT91C_PIO_PB29) // Interrupt input 0
-#define AT91C_PIO_PB3 (1u << 3) // Pin Controlled by PB3
#define AT91C_PB3_RD0 (AT91C_PIO_PB3) // SSC Receive Data
#define AT91C_PB3_MCDA1 (AT91C_PIO_PB3) // Multimedia Card A Data 1
-#define AT91C_PIO_PB4 (1u << 4) // Pin Controlled by PB4
#define AT91C_PB4_RK0 (AT91C_PIO_PB4) // SSC Receive Clock
#define AT91C_PB4_MCDA2 (AT91C_PIO_PB4) // Multimedia Card A Data 2
-#define AT91C_PIO_PB5 (1u << 5) // Pin Controlled by PB5
#define AT91C_PB5_RF0 (AT91C_PIO_PB5) // SSC Receive Frame Sync 0
#define AT91C_PB5_MCDA3 (AT91C_PIO_PB5) // Multimedia Card A Data 3
-#define AT91C_PIO_PB6 (1u << 6) // Pin Controlled by PB6
#define AT91C_PB6_TF1 (AT91C_PIO_PB6) // SSC Transmit Frame Sync 1
#define AT91C_PB6_TIOA3 (AT91C_PIO_PB6) // Timer Counter 4 Multipurpose Timer I/O Pin A
-#define AT91C_PIO_PB7 (1u << 7) // Pin Controlled by PB7
#define AT91C_PB7_TK1 (AT91C_PIO_PB7) // SSC Transmit Clock 1
#define AT91C_PB7_TIOB3 (AT91C_PIO_PB7) // Timer Counter 3 Multipurpose Timer I/O Pin B
-#define AT91C_PIO_PB8 (1u << 8) // Pin Controlled by PB8
#define AT91C_PB8_TD1 (AT91C_PIO_PB8) // SSC Transmit Data 1
#define AT91C_PB8_TIOA4 (AT91C_PIO_PB8) // Timer Counter 4 Multipurpose Timer I/O Pin A
-#define AT91C_PIO_PB9 (1u << 9) // Pin Controlled by PB9
#define AT91C_PB9_RD1 (AT91C_PIO_PB9) // SSC Receive Data 1
#define AT91C_PB9_TIOB4 (AT91C_PIO_PB9) // Timer Counter 4 Multipurpose Timer I/O Pin B
-#define AT91C_PIO_PC0 (1u << 0) // Pin Controlled by PC0
#define AT91C_PC0_BFCK (AT91C_PIO_PC0) // Burst Flash Clock
-#define AT91C_PIO_PC1 (1u << 1) // Pin Controlled by PC1
#define AT91C_PC1_BFRDY_SMOE (AT91C_PIO_PC1) // Burst Flash Ready
-#define AT91C_PIO_PC10 (1u << 10) // Pin Controlled by PC10
#define AT91C_PC10_NCS4_CFCS (AT91C_PIO_PC10) // Compact Flash Chip Select
-#define AT91C_PIO_PC11 (1u << 11) // Pin Controlled by PC11
#define AT91C_PC11_NCS5_CFCE1 (AT91C_PIO_PC11) // Chip Select 5 / Compact Flash Chip Enable 1
-#define AT91C_PIO_PC12 (1u << 12) // Pin Controlled by PC12
#define AT91C_PC12_NCS6_CFCE2 (AT91C_PIO_PC12) // Chip Select 6 / Compact Flash Chip Enable 2
-#define AT91C_PIO_PC13 (1u << 13) // Pin Controlled by PC13
#define AT91C_PC13_NCS7 (AT91C_PIO_PC13) // Chip Select 7
-#define AT91C_PIO_PC14 (1u << 14) // Pin Controlled by PC14
-#define AT91C_PIO_PC15 (1u << 15) // Pin Controlled by PC15
-#define AT91C_PIO_PC16 (1u << 16) // Pin Controlled by PC16
#define AT91C_PC16_D16 (AT91C_PIO_PC16) // Data Bus [16]
-#define AT91C_PIO_PC17 (1u << 17) // Pin Controlled by PC17
#define AT91C_PC17_D17 (AT91C_PIO_PC17) // Data Bus [17]
-#define AT91C_PIO_PC18 (1u << 18) // Pin Controlled by PC18
#define AT91C_PC18_D18 (AT91C_PIO_PC18) // Data Bus [18]
-#define AT91C_PIO_PC19 (1u << 19) // Pin Controlled by PC19
#define AT91C_PC19_D19 (AT91C_PIO_PC19) // Data Bus [19]
-#define AT91C_PIO_PC2 (1u << 2) // Pin Controlled by PC2
#define AT91C_PC2_BFAVD (AT91C_PIO_PC2)u // Burst Flash Address Valid
-#define AT91C_PIO_PC20 (1u << 20) // Pin Controlled by PC20
#define AT91C_PC20_D20 (AT91C_PIO_PC20) // Data Bus [20]
-#define AT91C_PIO_PC21 (1u << 21) // Pin Controlled by PC21
#define AT91C_PC21_D21 (AT91C_PIO_PC21) // Data Bus [21]
-#define AT91C_PIO_PC22 (1u << 22) // Pin Controlled by PC22
#define AT91C_PC22_D22 (AT91C_PIO_PC22) // Data Bus [22]
-#define AT91C_PIO_PC23 (1u << 23) // Pin Controlled by PC23
#define AT91C_PC23_D23 (AT91C_PIO_PC23) // Data Bus [23]
-#define AT91C_PIO_PC24 (1u << 24) // Pin Controlled by PC24
#define AT91C_PC24_D24 (AT91C_PIO_PC24) // Data Bus [24]
-#define AT91C_PIO_PC25 (1u << 25) // Pin Controlled by PC25
#define AT91C_PC25_D25 (AT91C_PIO_PC25) // Data Bus [25]
-#define AT91C_PIO_PC26 (1u << 26) // Pin Controlled by PC26
#define AT91C_PC26_D26 (AT91C_PIO_PC26) // Data Bus [26]
-#define AT91C_PIO_PC27 (1u << 27) // Pin Controlled by PC27
#define AT91C_PC27_D27 (AT91C_PIO_PC27) // Data Bus [27]
-#define AT91C_PIO_PC28 (1u << 28) // Pin Controlled by PC28
#define AT91C_PC28_D28 (AT91C_PIO_PC28) // Data Bus [28]
-#define AT91C_PIO_PC29 (1u << 29) // Pin Controlled by PC29
#define AT91C_PC29_D29 (AT91C_PIO_PC29) // Data Bus [29]
-#define AT91C_PIO_PC3 (1u << 3) // Pin Controlled by PC3
#define AT91C_PC3_BFBAA_SMWE (AT91C_PIO_PC3) // Burst Flash Address Advance / SmartMedia Write Enable
-#define AT91C_PIO_PC30 (1u << 30) // Pin Controlled by PC30
#define AT91C_PC30_D30 (AT91C_PIO_PC30) // Data Bus [30]
-#define AT91C_PIO_PC31 (1u << 31) // Pin Controlled by PC31
#define AT91C_PC31_D31 (AT91C_PIO_PC31) // Data Bus [31]
-#define AT91C_PIO_PC4 (1u << 4) // Pin Controlled by PC4
#define AT91C_PC4_BFOE (AT91C_PIO_PC4) // Burst Flash Output Enable
-#define AT91C_PIO_PC5 (1u << 5) // Pin Controlled by PC5
#define AT91C_PC5_BFWE (AT91C_PIO_PC5) // Burst Flash Write Enable
-#define AT91C_PIO_PC6 (1u << 6) // Pin Controlled by PC6
#define AT91C_PC6_NWAIT (AT91C_PIO_PC6) // NWAIT
-#define AT91C_PIO_PC7 (1u << 7) // Pin Controlled by PC7
#define AT91C_PC7_A23 (AT91C_PIO_PC7) // Address Bus[23]
-#define AT91C_PIO_PC8 (1u << 8) // Pin Controlled by PC8
#define AT91C_PC8_A24 (AT91C_PIO_PC8) // Address Bus[24]
-#define AT91C_PIO_PC9 (1u << 9) // Pin Controlled by PC9
#define AT91C_PC9_A25_CFRNW (AT91C_PIO_PC9) // Address Bus[25] / Compact Flash Read Not Write
-#define AT91C_PIO_PD0 (1u << 0) // Pin Controlled by PD0
#define AT91C_PD0_ETX0 (AT91C_PIO_PD0) // Ethernet MAC Transmit Data 0
-#define AT91C_PIO_PD1 (1u << 1) // Pin Controlled by PD1
#define AT91C_PD1_ETX1 (AT91C_PIO_PD1) // Ethernet MAC Transmit Data 1
-#define AT91C_PIO_PD10 (1u << 10) // Pin Controlled by PD10
#define AT91C_PD10_PCK3 (AT91C_PIO_PD10) // PMC Programmable Clock Output 3
#define AT91C_PD10_TPS1 (AT91C_PIO_PD10) // ETM ARM9 pipeline status 1
-#define AT91C_PIO_PD11 (1u << 11) // Pin Controlled by PD11
#define AT91C_PD11_ (AT91C_PIO_PD11) //
#define AT91C_PD11_TPS2 (AT91C_PIO_PD11) // ETM ARM9 pipeline status 2
-#define AT91C_PIO_PD12 (1u << 12) // Pin Controlled by PD12
#define AT91C_PD12_ (AT91C_PIO_PD12) //
#define AT91C_PD12_TPK0 (AT91C_PIO_PD12) // ETM Trace Packet 0
-#define AT91C_PIO_PD13 (1u << 13) // Pin Controlled by PD13
#define AT91C_PD13_ (AT91C_PIO_PD13) //
#define AT91C_PD13_TPK1 (AT91C_PIO_PD13) // ETM Trace Packet 1
-#define AT91C_PIO_PD14 (1u << 14) // Pin Controlled by PD14
#define AT91C_PD14_ (AT91C_PIO_PD14) //
#define AT91C_PD14_TPK2 (AT91C_PIO_PD14) // ETM Trace Packet 2
-#define AT91C_PIO_PD15 (1u << 15) // Pin Controlled by PD15
#define AT91C_PD15_TD0 (AT91C_PIO_PD15) // SSC Transmit data
#define AT91C_PD15_TPK3 (AT91C_PIO_PD15) // ETM Trace Packet 3
-#define AT91C_PIO_PD16 (1u << 16) // Pin Controlled by PD16
#define AT91C_PD16_TD1 (AT91C_PIO_PD16) // SSC Transmit Data 1
#define AT91C_PD16_TPK4 (AT91C_PIO_PD16) // ETM Trace Packet 4
-#define AT91C_PIO_PD17 (1u << 17) // Pin Controlled by PD17
#define AT91C_PD17_TD2 (AT91C_PIO_PD17) // SSC Transmit Data 2
#define AT91C_PD17_TPK5 (AT91C_PIO_PD17) // ETM Trace Packet 5
-#define AT91C_PIO_PD18 (1u << 18) // Pin Controlled by PD18
#define AT91C_PD18_NPCS1 (AT91C_PIO_PD18) // SPI Peripheral Chip Select 1
#define AT91C_PD18_TPK6 (AT91C_PIO_PD18) // ETM Trace Packet 6
-#define AT91C_PIO_PD19 (1u << 19) // Pin Controlled by PD19
#define AT91C_PD19_NPCS2 (AT91C_PIO_PD19) // SPI Peripheral Chip Select 2
#define AT91C_PD19_TPK7 (AT91C_PIO_PD19) // ETM Trace Packet 7
-#define AT91C_PIO_PD2 (1u << 2) // Pin Controlled by PD2
#define AT91C_PD2_ETX2 (AT91C_PIO_PD2) // Ethernet MAC Transmit Data 2
-#define AT91C_PIO_PD20 (1u << 20) // Pin Controlled by PD20
#define AT91C_PD20_NPCS3 (AT91C_PIO_PD20) // SPI Peripheral Chip Select 3
#define AT91C_PD20_TPK8 (AT91C_PIO_PD20) // ETM Trace Packet 8
-#define AT91C_PIO_PD21 (1u << 21) // Pin Controlled by PD21
#define AT91C_PD21_RTS0 (AT91C_PIO_PD21) // Usart 0 Ready To Send
#define AT91C_PD21_TPK9 (AT91C_PIO_PD21) // ETM Trace Packet 9
-#define AT91C_PIO_PD22 (1u << 22) // Pin Controlled by PD22
#define AT91C_PD22_RTS1 (AT91C_PIO_PD22) // Usart 0 Ready To Send
#define AT91C_PD22_TPK10 (AT91C_PIO_PD22) // ETM Trace Packet 10
-#define AT91C_PIO_PD23 (1u << 23) // Pin Controlled by PD23
#define AT91C_PD23_RTS2 (AT91C_PIO_PD23) // USART 2 Ready To Send
#define AT91C_PD23_TPK11 (AT91C_PIO_PD23) // ETM Trace Packet 11
-#define AT91C_PIO_PD24 (1u << 24) // Pin Controlled by PD24
#define AT91C_PD24_RTS3 (AT91C_PIO_PD24) // USART 3 Ready To Send
#define AT91C_PD24_TPK12 (AT91C_PIO_PD24) // ETM Trace Packet 12
-#define AT91C_PIO_PD25 (1u << 25) // Pin Controlled by PD25
#define AT91C_PD25_DTR1 (AT91C_PIO_PD25) // USART 1 Data Terminal ready
#define AT91C_PD25_TPK13 (AT91C_PIO_PD25) // ETM Trace Packet 13
-#define AT91C_PIO_PD26 (1u << 26) // Pin Controlled by PD26
#define AT91C_PD26_TPK14 (AT91C_PIO_PD26) // ETM Trace Packet 14
-#define AT91C_PIO_PD27 (1u << 27) // Pin Controlled by PD27
#define AT91C_PD27_TPK15 (AT91C_PIO_PD27) // ETM Trace Packet 15
-#define AT91C_PIO_PD3 (1u << 3) // Pin Controlled by PD3
#define AT91C_PD3_ETX3 (AT91C_PIO_PD3) // Ethernet MAC Transmit Data 3
-#define AT91C_PIO_PD4 (1u << 4) // Pin Controlled by PD4
#define AT91C_PD4_ETXEN (AT91C_PIO_PD4) // Ethernet MAC Transmit Enable
-#define AT91C_PIO_PD5 (1u << 5) // Pin Controlled by PD5
#define AT91C_PD5_ETXER (AT91C_PIO_PD5) // Ethernet MAC Transmikt Coding Error
-#define AT91C_PIO_PD6 (1u << 6) // Pin Controlled by PD6
#define AT91C_PD6_DTXD (AT91C_PIO_PD6) // DBGU Debug Transmit Data
-#define AT91C_PIO_PD7 (1u << 7) // Pin Controlled by PD7
#define AT91C_PD7_PCK0 (AT91C_PIO_PD7) // PMC Programmable Clock Output 0
#define AT91C_PD7_TSYNC (AT91C_PIO_PD7) // ETM Synchronization signal
-#define AT91C_PIO_PD8 (1u << 8) // Pin Controlled by PD8
#define AT91C_PD8_PCK1 (AT91C_PIO_PD8) // PMC Programmable Clock Output 1
#define AT91C_PD8_TCLK (AT91C_PIO_PD8) // ETM Trace Clock signal
-#define AT91C_PIO_PD9 (1u << 9) // Pin Controlled by PD9
#define AT91C_PD9_PCK2 (AT91C_PIO_PD9) // PMC Programmable Clock 2
#define AT91C_PD9_TPS0 (AT91C_PIO_PD9) // ETM ARM9 pipeline status 0
+
+#endif /* ARM_AT91_AT91_PIO_RM9200_H */
diff --git a/sys/arm/at91/at91_pio_sam9.h b/sys/arm/at91/at91_pio_sam9.h
deleted file mode 100644
index d3c8f06..0000000
--- a/sys/arm/at91/at91_pio_sam9.h
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Theses defines come from an atmel file that says specifically that it
- * has no copyright.
- */
-
-/* $FreeBSD$ */
-
-// *****************************************************************************
-// PIO DEFINITIONS FOR AT91SAM9261
-// *****************************************************************************
-#define AT91C_PIO_PA0 ((unsigned int) 1 << 0) // Pin Controlled by PA0
-#define AT91C_PA0_MISO0 ((unsigned int) AT91C_PIO_PA0) // SPI0 Master In Slave
-#define AT91C_PA0_MCDA0 ((unsigned int) AT91C_PIO_PA0) // Multimedia Card A Data 0
-#define AT91C_PIO_PA1 ((unsigned int) 1 << 1) // Pin Controlled by PA1
-#define AT91C_PA1_MOSI0 ((unsigned int) AT91C_PIO_PA1) // SPI0 Master Out Slave
-#define AT91C_PA1_MCCDA ((unsigned int) AT91C_PIO_PA1) // Multimedia Card A Command
-#define AT91C_PIO_PA10 ((unsigned int) 1 << 10) // Pin Controlled by PA10
-#define AT91C_PA10_DTXD ((unsigned int) AT91C_PIO_PA10) // DBGU Debug Transmit Data
-#define AT91C_PA10_PCK3 ((unsigned int) AT91C_PIO_PA10) // PMC Programmable clock Output 3
-#define AT91C_PIO_PA11 ((unsigned int) 1 << 11) // Pin Controlled by PA11
-#define AT91C_PA11_TSYNC ((unsigned int) AT91C_PIO_PA11) // Trace Synchronization Signal
-#define AT91C_PA11_SCK1 ((unsigned int) AT91C_PIO_PA11) // USART1 Serial Clock
-#define AT91C_PIO_PA12 ((unsigned int) 1 << 12) // Pin Controlled by PA12
-#define AT91C_PA12_TCLK ((unsigned int) AT91C_PIO_PA12) // Trace Clock
-#define AT91C_PA12_RTS1 ((unsigned int) AT91C_PIO_PA12) // USART1 Ready To Send
-#define AT91C_PIO_PA13 ((unsigned int) 1 << 13) // Pin Controlled by PA13
-#define AT91C_PA13_TPS0 ((unsigned int) AT91C_PIO_PA13) // Trace ARM Pipeline Status 0
-#define AT91C_PA13_CTS1 ((unsigned int) AT91C_PIO_PA13) // USART1 Clear To Send
-#define AT91C_PIO_PA14 ((unsigned int) 1 << 14) // Pin Controlled by PA14
-#define AT91C_PA14_TPS1 ((unsigned int) AT91C_PIO_PA14) // Trace ARM Pipeline Status 1
-#define AT91C_PA14_SCK2 ((unsigned int) AT91C_PIO_PA14) // USART2 Serial Clock
-#define AT91C_PIO_PA15 ((unsigned int) 1 << 15) // Pin Controlled by PA15
-#define AT91C_PA15_TPS2 ((unsigned int) AT91C_PIO_PA15) // Trace ARM Pipeline Status 2
-#define AT91C_PA15_RTS2 ((unsigned int) AT91C_PIO_PA15) // USART2 Ready To Send
-#define AT91C_PIO_PA16 ((unsigned int) 1 << 16) // Pin Controlled by PA16
-#define AT91C_PA16_TPK0 ((unsigned int) AT91C_PIO_PA16) // Trace Packet Port 0
-#define AT91C_PA16_CTS2 ((unsigned int) AT91C_PIO_PA16) // USART2 Clear To Send
-#define AT91C_PIO_PA17 ((unsigned int) 1 << 17) // Pin Controlled by PA17
-#define AT91C_PA17_TPK1 ((unsigned int) AT91C_PIO_PA17) // Trace Packet Port 1
-#define AT91C_PA17_TF1 ((unsigned int) AT91C_PIO_PA17) // SSC1 Transmit Frame Sync
-#define AT91C_PIO_PA18 ((unsigned int) 1 << 18) // Pin Controlled by PA18
-#define AT91C_PA18_TPK2 ((unsigned int) AT91C_PIO_PA18) // Trace Packet Port 2
-#define AT91C_PA18_TK1 ((unsigned int) AT91C_PIO_PA18) // SSC1 Transmit Clock
-#define AT91C_PIO_PA19 ((unsigned int) 1 << 19) // Pin Controlled by PA19
-#define AT91C_PA19_TPK3 ((unsigned int) AT91C_PIO_PA19) // Trace Packet Port 3
-#define AT91C_PA19_TD1 ((unsigned int) AT91C_PIO_PA19) // SSC1 Transmit Data
-#define AT91C_PIO_PA2 ((unsigned int) 1 << 2) // Pin Controlled by PA2
-#define AT91C_PA2_SPCK0 ((unsigned int) AT91C_PIO_PA2) // SPI0 Serial Clock
-#define AT91C_PA2_MCCK ((unsigned int) AT91C_PIO_PA2) // Multimedia Card Clock
-#define AT91C_PIO_PA20 ((unsigned int) 1 << 20) // Pin Controlled by PA20
-#define AT91C_PA20_TPK4 ((unsigned int) AT91C_PIO_PA20) // Trace Packet Port 4
-#define AT91C_PA20_RD1 ((unsigned int) AT91C_PIO_PA20) // SSC1 Receive Data
-#define AT91C_PIO_PA21 ((unsigned int) 1 << 21) // Pin Controlled by PA21
-#define AT91C_PA21_TPK5 ((unsigned int) AT91C_PIO_PA21) // Trace Packet Port 5
-#define AT91C_PA21_RK1 ((unsigned int) AT91C_PIO_PA21) // SSC1 Receive Clock
-#define AT91C_PIO_PA22 ((unsigned int) 1 << 22) // Pin Controlled by PA22
-#define AT91C_PA22_TPK6 ((unsigned int) AT91C_PIO_PA22) // Trace Packet Port 6
-#define AT91C_PA22_RF1 ((unsigned int) AT91C_PIO_PA22) // SSC1 Receive Frame Sync
-#define AT91C_PIO_PA23 ((unsigned int) 1 << 23) // Pin Controlled by PA23
-#define AT91C_PA23_TPK7 ((unsigned int) AT91C_PIO_PA23) // Trace Packet Port 7
-#define AT91C_PA23_RTS0 ((unsigned int) AT91C_PIO_PA23) // USART0 Ready To Send
-#define AT91C_PIO_PA24 ((unsigned int) 1 << 24) // Pin Controlled by PA24
-#define AT91C_PA24_TPK8 ((unsigned int) AT91C_PIO_PA24) // Trace Packet Port 8
-#define AT91C_PA24_NPCS11 ((unsigned int) AT91C_PIO_PA24) // SPI1 Peripheral Chip Select 1
-#define AT91C_PIO_PA25 ((unsigned int) 1 << 25) // Pin Controlled by PA25
-#define AT91C_PA25_TPK9 ((unsigned int) AT91C_PIO_PA25) // Trace Packet Port 9
-#define AT91C_PA25_NPCS12 ((unsigned int) AT91C_PIO_PA25) // SPI1 Peripheral Chip Select 2
-#define AT91C_PIO_PA26 ((unsigned int) 1 << 26) // Pin Controlled by PA26
-#define AT91C_PA26_TPK10 ((unsigned int) AT91C_PIO_PA26) // Trace Packet Port 10
-#define AT91C_PA26_NPCS13 ((unsigned int) AT91C_PIO_PA26) // SPI1 Peripheral Chip Select 3
-#define AT91C_PIO_PA27 ((unsigned int) 1 << 27) // Pin Controlled by PA27
-#define AT91C_PA27_TPK11 ((unsigned int) AT91C_PIO_PA27) // Trace Packet Port 11
-#define AT91C_PA27_NPCS01 ((unsigned int) AT91C_PIO_PA27) // SPI0 Peripheral Chip Select 1
-#define AT91C_PIO_PA28 ((unsigned int) 1 << 28) // Pin Controlled by PA28
-#define AT91C_PA28_TPK12 ((unsigned int) AT91C_PIO_PA28) // Trace Packet Port 12
-#define AT91C_PA28_NPCS02 ((unsigned int) AT91C_PIO_PA28) // SPI0 Peripheral Chip Select 2
-#define AT91C_PIO_PA29 ((unsigned int) 1 << 29) // Pin Controlled by PA29
-#define AT91C_PA29_TPK13 ((unsigned int) AT91C_PIO_PA29) // Trace Packet Port 13
-#define AT91C_PA29_NPCS03 ((unsigned int) AT91C_PIO_PA29) // SPI0 Peripheral Chip Select 3
-#define AT91C_PIO_PA3 ((unsigned int) 1 << 3) // Pin Controlled by PA3
-#define AT91C_PA3_NPCS00 ((unsigned int) AT91C_PIO_PA3) // SPI0 Peripheral Chip Select 0
-#define AT91C_PIO_PA30 ((unsigned int) 1 << 30) // Pin Controlled by PA30
-#define AT91C_PA30_TPK14 ((unsigned int) AT91C_PIO_PA30) // Trace Packet Port 14
-#define AT91C_PA30_A23 ((unsigned int) AT91C_PIO_PA30) // Address Bus bit 23
-#define AT91C_PIO_PA31 ((unsigned int) 1 << 31) // Pin Controlled by PA31
-#define AT91C_PA31_TPK15 ((unsigned int) AT91C_PIO_PA31) // Trace Packet Port 15
-#define AT91C_PA31_A24 ((unsigned int) AT91C_PIO_PA31) // Address Bus bit 24
-#define AT91C_PIO_PA4 ((unsigned int) 1 << 4) // Pin Controlled by PA4
-#define AT91C_PA4_NPCS01 ((unsigned int) AT91C_PIO_PA4) // SPI0 Peripheral Chip Select 1
-#define AT91C_PA4_MCDA1 ((unsigned int) AT91C_PIO_PA4) // Multimedia Card A Data 1
-#define AT91C_PIO_PA5 ((unsigned int) 1 << 5) // Pin Controlled by PA5
-#define AT91C_PA5_NPCS02 ((unsigned int) AT91C_PIO_PA5) // SPI0 Peripheral Chip Select 2
-#define AT91C_PA5_MCDA2 ((unsigned int) AT91C_PIO_PA5) // Multimedia Card A Data 2
-#define AT91C_PIO_PA6 ((unsigned int) 1 << 6) // Pin Controlled by PA6
-#define AT91C_PA6_NPCS03 ((unsigned int) AT91C_PIO_PA6) // SPI0 Peripheral Chip Select 3
-#define AT91C_PA6_MCDA3 ((unsigned int) AT91C_PIO_PA6) // Multimedia Card A Data 3
-#define AT91C_PIO_PA7 ((unsigned int) 1 << 7) // Pin Controlled by PA7
-#define AT91C_PA7_TWD ((unsigned int) AT91C_PIO_PA7) // TWI Two-wire Serial Data
-#define AT91C_PA7_PCK0 ((unsigned int) AT91C_PIO_PA7) // PMC Programmable clock Output 0
-#define AT91C_PIO_PA8 ((unsigned int) 1 << 8) // Pin Controlled by PA8
-#define AT91C_PA8_TWCK ((unsigned int) AT91C_PIO_PA8) // TWI Two-wire Serial Clock
-#define AT91C_PA8_PCK1 ((unsigned int) AT91C_PIO_PA8) // PMC Programmable clock Output 1
-#define AT91C_PIO_PA9 ((unsigned int) 1 << 9) // Pin Controlled by PA9
-#define AT91C_PA9_DRXD ((unsigned int) AT91C_PIO_PA9) // DBGU Debug Receive Data
-#define AT91C_PA9_PCK2 ((unsigned int) AT91C_PIO_PA9) // PMC Programmable clock Output 2
-#define AT91C_PIO_PB0 ((unsigned int) 1 << 0) // Pin Controlled by PB0
-#define AT91C_PB0_LCDVSYNC ((unsigned int) AT91C_PIO_PB0) // LCD Vertical Synchronization
-#define AT91C_PIO_PB1 ((unsigned int) 1 << 1) // Pin Controlled by PB1
-#define AT91C_PB1_LCDHSYNC ((unsigned int) AT91C_PIO_PB1) // LCD Horizontal Synchronization
-#define AT91C_PIO_PB10 ((unsigned int) 1 << 10) // Pin Controlled by PB10
-#define AT91C_PB10_LCDD5 ((unsigned int) AT91C_PIO_PB10) // LCD Data Bus Bit 5
-#define AT91C_PB10_LCDD10 ((unsigned int) AT91C_PIO_PB10) // LCD Data Bus Bit 10
-#define AT91C_PIO_PB11 ((unsigned int) 1 << 11) // Pin Controlled by PB11
-#define AT91C_PB11_LCDD6 ((unsigned int) AT91C_PIO_PB11) // LCD Data Bus Bit 6
-#define AT91C_PB11_LCDD11 ((unsigned int) AT91C_PIO_PB11) // LCD Data Bus Bit 11
-#define AT91C_PIO_PB12 ((unsigned int) 1 << 12) // Pin Controlled by PB12
-#define AT91C_PB12_LCDD7 ((unsigned int) AT91C_PIO_PB12) // LCD Data Bus Bit 7
-#define AT91C_PB12_LCDD12 ((unsigned int) AT91C_PIO_PB12) // LCD Data Bus Bit 12
-#define AT91C_PIO_PB13 ((unsigned int) 1 << 13) // Pin Controlled by PB13
-#define AT91C_PB13_LCDD8 ((unsigned int) AT91C_PIO_PB13) // LCD Data Bus Bit 8
-#define AT91C_PB13_LCDD13 ((unsigned int) AT91C_PIO_PB13) // LCD Data Bus Bit 13
-#define AT91C_PIO_PB14 ((unsigned int) 1 << 14) // Pin Controlled by PB14
-#define AT91C_PB14_LCDD9 ((unsigned int) AT91C_PIO_PB14) // LCD Data Bus Bit 9
-#define AT91C_PB14_LCDD14 ((unsigned int) AT91C_PIO_PB14) // LCD Data Bus Bit 14
-#define AT91C_PIO_PB15 ((unsigned int) 1 << 15) // Pin Controlled by PB15
-#define AT91C_PB15_LCDD10 ((unsigned int) AT91C_PIO_PB15) // LCD Data Bus Bit 10
-#define AT91C_PB15_LCDD15 ((unsigned int) AT91C_PIO_PB15) // LCD Data Bus Bit 15
-#define AT91C_PIO_PB16 ((unsigned int) 1 << 16) // Pin Controlled by PB16
-#define AT91C_PB16_LCDD11 ((unsigned int) AT91C_PIO_PB16) // LCD Data Bus Bit 11
-#define AT91C_PB16_LCDD19 ((unsigned int) AT91C_PIO_PB16) // LCD Data Bus Bit 19
-#define AT91C_PIO_PB17 ((unsigned int) 1 << 17) // Pin Controlled by PB17
-#define AT91C_PB17_LCDD12 ((unsigned int) AT91C_PIO_PB17) // LCD Data Bus Bit 12
-#define AT91C_PB17_LCDD20 ((unsigned int) AT91C_PIO_PB17) // LCD Data Bus Bit 20
-#define AT91C_PIO_PB18 ((unsigned int) 1 << 18) // Pin Controlled by PB18
-#define AT91C_PB18_LCDD13 ((unsigned int) AT91C_PIO_PB18) // LCD Data Bus Bit 13
-#define AT91C_PB18_LCDD21 ((unsigned int) AT91C_PIO_PB18) // LCD Data Bus Bit 21
-#define AT91C_PIO_PB19 ((unsigned int) 1 << 19) // Pin Controlled by PB19
-#define AT91C_PB19_LCDD14 ((unsigned int) AT91C_PIO_PB19) // LCD Data Bus Bit 14
-#define AT91C_PB19_LCDD22 ((unsigned int) AT91C_PIO_PB19) // LCD Data Bus Bit 22
-#define AT91C_PIO_PB2 ((unsigned int) 1 << 2) // Pin Controlled by PB2
-#define AT91C_PB2_LCDDOTCK ((unsigned int) AT91C_PIO_PB2) // LCD Dot Clock
-#define AT91C_PB2_PCK0 ((unsigned int) AT91C_PIO_PB2) // PMC Programmable clock Output 0
-#define AT91C_PIO_PB20 ((unsigned int) 1 << 20) // Pin Controlled by PB20
-#define AT91C_PB20_LCDD15 ((unsigned int) AT91C_PIO_PB20) // LCD Data Bus Bit 15
-#define AT91C_PB20_LCDD23 ((unsigned int) AT91C_PIO_PB20) // LCD Data Bus Bit 23
-#define AT91C_PIO_PB21 ((unsigned int) 1 << 21) // Pin Controlled by PB21
-#define AT91C_PB21_TF0 ((unsigned int) AT91C_PIO_PB21) // SSC0 Transmit Frame Sync
-#define AT91C_PB21_LCDD16 ((unsigned int) AT91C_PIO_PB21) // LCD Data Bus Bit 16
-#define AT91C_PIO_PB22 ((unsigned int) 1 << 22) // Pin Controlled by PB22
-#define AT91C_PB22_TK0 ((unsigned int) AT91C_PIO_PB22) // SSC0 Transmit Clock
-#define AT91C_PB22_LCDD17 ((unsigned int) AT91C_PIO_PB22) // LCD Data Bus Bit 17
-#define AT91C_PIO_PB23 ((unsigned int) 1 << 23) // Pin Controlled by PB23
-#define AT91C_PB23_TD0 ((unsigned int) AT91C_PIO_PB23) // SSC0 Transmit Data
-#define AT91C_PB23_LCDD18 ((unsigned int) AT91C_PIO_PB23) // LCD Data Bus Bit 18
-#define AT91C_PIO_PB24 ((unsigned int) 1 << 24) // Pin Controlled by PB24
-#define AT91C_PB24_RD0 ((unsigned int) AT91C_PIO_PB24) // SSC0 Receive Data
-#define AT91C_PB24_LCDD19 ((unsigned int) AT91C_PIO_PB24) // LCD Data Bus Bit 19
-#define AT91C_PIO_PB25 ((unsigned int) 1 << 25) // Pin Controlled by PB25
-#define AT91C_PB25_RK0 ((unsigned int) AT91C_PIO_PB25) // SSC0 Receive Clock
-#define AT91C_PB25_LCDD20 ((unsigned int) AT91C_PIO_PB25) // LCD Data Bus Bit 20
-#define AT91C_PIO_PB26 ((unsigned int) 1 << 26) // Pin Controlled by PB26
-#define AT91C_PB26_RF0 ((unsigned int) AT91C_PIO_PB26) // SSC0 Receive Frame Sync
-#define AT91C_PB26_LCDD21 ((unsigned int) AT91C_PIO_PB26) // LCD Data Bus Bit 21
-#define AT91C_PIO_PB27 ((unsigned int) 1 << 27) // Pin Controlled by PB27
-#define AT91C_PB27_NPCS11 ((unsigned int) AT91C_PIO_PB27) // SPI1 Peripheral Chip Select 1
-#define AT91C_PB27_LCDD22 ((unsigned int) AT91C_PIO_PB27) // LCD Data Bus Bit 22
-#define AT91C_PIO_PB28 ((unsigned int) 1 << 28) // Pin Controlled by PB28
-#define AT91C_PB28_NPCS10 ((unsigned int) AT91C_PIO_PB28) // SPI1 Peripheral Chip Select 0
-#define AT91C_PB28_LCDD23 ((unsigned int) AT91C_PIO_PB28) // LCD Data Bus Bit 23
-#define AT91C_PIO_PB29 ((unsigned int) 1 << 29) // Pin Controlled by PB29
-#define AT91C_PB29_SPCK1 ((unsigned int) AT91C_PIO_PB29) // SPI1 Serial Clock
-#define AT91C_PB29_IRQ2 ((unsigned int) AT91C_PIO_PB29) // Interrupt input 2
-#define AT91C_PIO_PB3 ((unsigned int) 1 << 3) // Pin Controlled by PB3
-#define AT91C_PB3_LCDDEN ((unsigned int) AT91C_PIO_PB3) // LCD Data Enable
-#define AT91C_PIO_PB30 ((unsigned int) 1 << 30) // Pin Controlled by PB30
-#define AT91C_PB30_MISO1 ((unsigned int) AT91C_PIO_PB30) // SPI1 Master In Slave
-#define AT91C_PB30_IRQ1 ((unsigned int) AT91C_PIO_PB30) // Interrupt input 1
-#define AT91C_PIO_PB31 ((unsigned int) 1 << 31) // Pin Controlled by PB31
-#define AT91C_PB31_MOSI1 ((unsigned int) AT91C_PIO_PB31) // SPI1 Master Out Slave
-#define AT91C_PB31_PCK2 ((unsigned int) AT91C_PIO_PB31) // PMC Programmable clock Output 2
-#define AT91C_PIO_PB4 ((unsigned int) 1 << 4) // Pin Controlled by PB4
-#define AT91C_PB4_LCDCC ((unsigned int) AT91C_PIO_PB4) // LCD Contrast Control
-#define AT91C_PB4_LCDD2 ((unsigned int) AT91C_PIO_PB4) // LCD Data Bus Bit 2
-#define AT91C_PIO_PB5 ((unsigned int) 1 << 5) // Pin Controlled by PB5
-#define AT91C_PB5_LCDD0 ((unsigned int) AT91C_PIO_PB5) // LCD Data Bus Bit 0
-#define AT91C_PB5_LCDD3 ((unsigned int) AT91C_PIO_PB5) // LCD Data Bus Bit 3
-#define AT91C_PIO_PB6 ((unsigned int) 1 << 6) // Pin Controlled by PB6
-#define AT91C_PB6_LCDD1 ((unsigned int) AT91C_PIO_PB6) // LCD Data Bus Bit 1
-#define AT91C_PB6_LCDD4 ((unsigned int) AT91C_PIO_PB6) // LCD Data Bus Bit 4
-#define AT91C_PIO_PB7 ((unsigned int) 1 << 7) // Pin Controlled by PB7
-#define AT91C_PB7_LCDD2 ((unsigned int) AT91C_PIO_PB7) // LCD Data Bus Bit 2
-#define AT91C_PB7_LCDD5 ((unsigned int) AT91C_PIO_PB7) // LCD Data Bus Bit 5
-#define AT91C_PIO_PB8 ((unsigned int) 1 << 8) // Pin Controlled by PB8
-#define AT91C_PB8_LCDD3 ((unsigned int) AT91C_PIO_PB8) // LCD Data Bus Bit 3
-#define AT91C_PB8_LCDD6 ((unsigned int) AT91C_PIO_PB8) // LCD Data Bus Bit 6
-#define AT91C_PIO_PB9 ((unsigned int) 1 << 9) // Pin Controlled by PB9
-#define AT91C_PB9_LCDD4 ((unsigned int) AT91C_PIO_PB9) // LCD Data Bus Bit 4
-#define AT91C_PB9_LCDD7 ((unsigned int) AT91C_PIO_PB9) // LCD Data Bus Bit 7
-#define AT91C_PIO_PC0 ((unsigned int) 1 << 0) // Pin Controlled by PC0
-#define AT91C_PC0_SMOE ((unsigned int) AT91C_PIO_PC0) // SmartMedia Output Enable
-#define AT91C_PC0_NCS6 ((unsigned int) AT91C_PIO_PC0) // Chip Select 6
-#define AT91C_PIO_PC1 ((unsigned int) 1 << 1) // Pin Controlled by PC1
-#define AT91C_PC1_SMWE ((unsigned int) AT91C_PIO_PC1) // SmartMedia Write Enable
-#define AT91C_PC1_NCS7 ((unsigned int) AT91C_PIO_PC1) // Chip Select 7
-#define AT91C_PIO_PC10 ((unsigned int) 1 << 10) // Pin Controlled by PC10
-#define AT91C_PC10_RTS0 ((unsigned int) AT91C_PIO_PC10) // USART0 Ready To Send
-#define AT91C_PC10_SCK0 ((unsigned int) AT91C_PIO_PC10) // USART0 Serial Clock
-#define AT91C_PIO_PC11 ((unsigned int) 1 << 11) // Pin Controlled by PC11
-#define AT91C_PC11_CTS0 ((unsigned int) AT91C_PIO_PC11) // USART0 Clear To Send
-#define AT91C_PC11_FIQ ((unsigned int) AT91C_PIO_PC11) // AIC Fast Interrupt Input
-#define AT91C_PIO_PC12 ((unsigned int) 1 << 12) // Pin Controlled by PC12
-#define AT91C_PC12_TXD1 ((unsigned int) AT91C_PIO_PC12) // USART1 Transmit Data
-#define AT91C_PC12_NCS6 ((unsigned int) AT91C_PIO_PC12) // Chip Select 6
-#define AT91C_PIO_PC13 ((unsigned int) 1 << 13) // Pin Controlled by PC13
-#define AT91C_PC13_RXD1 ((unsigned int) AT91C_PIO_PC13) // USART1 Receive Data
-#define AT91C_PC13_NCS7 ((unsigned int) AT91C_PIO_PC13) // Chip Select 7
-#define AT91C_PIO_PC14 ((unsigned int) 1 << 14) // Pin Controlled by PC14
-#define AT91C_PC14_TXD2 ((unsigned int) AT91C_PIO_PC14) // USART2 Transmit Data
-#define AT91C_PC14_NPCS12 ((unsigned int) AT91C_PIO_PC14) // SPI1 Peripheral Chip Select 2
-#define AT91C_PIO_PC15 ((unsigned int) 1 << 15) // Pin Controlled by PC15
-#define AT91C_PC15_RXD2 ((unsigned int) AT91C_PIO_PC15) // USART2 Receive Data
-#define AT91C_PC15_NPCS13 ((unsigned int) AT91C_PIO_PC15) // SPI1 Peripheral Chip Select 3
-#define AT91C_PIO_PC16 ((unsigned int) 1 << 16) // Pin Controlled by PC16
-#define AT91C_PC16_D16 ((unsigned int) AT91C_PIO_PC16) // Data Bus [16]
-#define AT91C_PC16_TCLK0 ((unsigned int) AT91C_PIO_PC16) // Timer Counter 0 external clock input
-#define AT91C_PIO_PC17 ((unsigned int) 1 << 17) // Pin Controlled by PC17
-#define AT91C_PC17_D17 ((unsigned int) AT91C_PIO_PC17) // Data Bus [17]
-#define AT91C_PC17_TCLK1 ((unsigned int) AT91C_PIO_PC17) // Timer Counter 1 external clock input
-#define AT91C_PIO_PC18 ((unsigned int) 1 << 18) // Pin Controlled by PC18
-#define AT91C_PC18_D18 ((unsigned int) AT91C_PIO_PC18) // Data Bus [18]
-#define AT91C_PC18_TCLK2 ((unsigned int) AT91C_PIO_PC18) // Timer Counter 2 external clock input
-#define AT91C_PIO_PC19 ((unsigned int) 1 << 19) // Pin Controlled by PC19
-#define AT91C_PC19_D19 ((unsigned int) AT91C_PIO_PC19) // Data Bus [19]
-#define AT91C_PC19_TIOA0 ((unsigned int) AT91C_PIO_PC19) // Timer Counter 0 Multipurpose Timer I/O Pin A
-#define AT91C_PIO_PC2 ((unsigned int) 1 << 2) // Pin Controlled by PC2
-#define AT91C_PC2_NWAIT ((unsigned int) AT91C_PIO_PC2) // NWAIT
-#define AT91C_PC2_IRQ0 ((unsigned int) AT91C_PIO_PC2) // Interrupt input 0
-#define AT91C_PIO_PC20 ((unsigned int) 1 << 20) // Pin Controlled by PC20
-#define AT91C_PC20_D20 ((unsigned int) AT91C_PIO_PC20) // Data Bus [20]
-#define AT91C_PC20_TIOB0 ((unsigned int) AT91C_PIO_PC20) // Timer Counter 0 Multipurpose Timer I/O Pin B
-#define AT91C_PIO_PC21 ((unsigned int) 1 << 21) // Pin Controlled by PC21
-#define AT91C_PC21_D21 ((unsigned int) AT91C_PIO_PC21) // Data Bus [21]
-#define AT91C_PC21_TIOA1 ((unsigned int) AT91C_PIO_PC21) // Timer Counter 1 Multipurpose Timer I/O Pin A
-#define AT91C_PIO_PC22 ((unsigned int) 1 << 22) // Pin Controlled by PC22
-#define AT91C_PC22_D22 ((unsigned int) AT91C_PIO_PC22) // Data Bus [22]
-#define AT91C_PC22_TIOB1 ((unsigned int) AT91C_PIO_PC22) // Timer Counter 1 Multipurpose Timer I/O Pin B
-#define AT91C_PIO_PC23 ((unsigned int) 1 << 23) // Pin Controlled by PC23
-#define AT91C_PC23_D23 ((unsigned int) AT91C_PIO_PC23) // Data Bus [23]
-#define AT91C_PC23_TIOA2 ((unsigned int) AT91C_PIO_PC23) // Timer Counter 2 Multipurpose Timer I/O Pin A
-#define AT91C_PIO_PC24 ((unsigned int) 1 << 24) // Pin Controlled by PC24
-#define AT91C_PC24_D24 ((unsigned int) AT91C_PIO_PC24) // Data Bus [24]
-#define AT91C_PC24_TIOB2 ((unsigned int) AT91C_PIO_PC24) // Timer Counter 2 Multipurpose Timer I/O Pin B
-#define AT91C_PIO_PC25 ((unsigned int) 1 << 25) // Pin Controlled by PC25
-#define AT91C_PC25_D25 ((unsigned int) AT91C_PIO_PC25) // Data Bus [25]
-#define AT91C_PC25_TF2 ((unsigned int) AT91C_PIO_PC25) // SSC2 Transmit Frame Sync
-#define AT91C_PIO_PC26 ((unsigned int) 1 << 26) // Pin Controlled by PC26
-#define AT91C_PC26_D26 ((unsigned int) AT91C_PIO_PC26) // Data Bus [26]
-#define AT91C_PC26_TK2 ((unsigned int) AT91C_PIO_PC26) // SSC2 Transmit Clock
-#define AT91C_PIO_PC27 ((unsigned int) 1 << 27) // Pin Controlled by PC27
-#define AT91C_PC27_D27 ((unsigned int) AT91C_PIO_PC27) // Data Bus [27]
-#define AT91C_PC27_TD2 ((unsigned int) AT91C_PIO_PC27) // SSC2 Transmit Data
-#define AT91C_PIO_PC28 ((unsigned int) 1 << 28) // Pin Controlled by PC28
-#define AT91C_PC28_D28 ((unsigned int) AT91C_PIO_PC28) // Data Bus [28]
-#define AT91C_PC28_RD2 ((unsigned int) AT91C_PIO_PC28) // SSC2 Receive Data
-#define AT91C_PIO_PC29 ((unsigned int) 1 << 29) // Pin Controlled by PC29
-#define AT91C_PC29_D29 ((unsigned int) AT91C_PIO_PC29) // Data Bus [29]
-#define AT91C_PC29_RK2 ((unsigned int) AT91C_PIO_PC29) // SSC2 Receive Clock
-#define AT91C_PIO_PC3 ((unsigned int) 1 << 3) // Pin Controlled by PC3
-#define AT91C_PC3_A25_CFRNW ((unsigned int) AT91C_PIO_PC3) // Address Bus[25] / Compact Flash Read Not Write
-#define AT91C_PIO_PC30 ((unsigned int) 1 << 30) // Pin Controlled by PC30
-#define AT91C_PC30_D30 ((unsigned int) AT91C_PIO_PC30) // Data Bus [30]
-#define AT91C_PC30_RF2 ((unsigned int) AT91C_PIO_PC30) // SSC2 Receive Frame Sync
-#define AT91C_PIO_PC31 ((unsigned int) 1 << 31) // Pin Controlled by PC31
-#define AT91C_PC31_D31 ((unsigned int) AT91C_PIO_PC31) // Data Bus [31]
-#define AT91C_PC31_PCK1 ((unsigned int) AT91C_PIO_PC31) // PMC Programmable clock Output 1
-#define AT91C_PIO_PC4 ((unsigned int) 1 << 4) // Pin Controlled by PC4
-#define AT91C_PC4_NCS4_CFCS0 ((unsigned int) AT91C_PIO_PC4) // Chip Select 4 / CompactFlash Chip Select 0
-#define AT91C_PIO_PC5 ((unsigned int) 1 << 5) // Pin Controlled by PC5
-#define AT91C_PC5_NCS5_CFCS1 ((unsigned int) AT91C_PIO_PC5) // Chip Select 5 / CompactFlash Chip Select 1
-#define AT91C_PIO_PC6 ((unsigned int) 1 << 6) // Pin Controlled by PC6
-#define AT91C_PC6_CFCE1 ((unsigned int) AT91C_PIO_PC6) // CompactFlash Chip Enable 1
-#define AT91C_PIO_PC7 ((unsigned int) 1 << 7) // Pin Controlled by PC7
-#define AT91C_PC7_CFCE2 ((unsigned int) AT91C_PIO_PC7) // CompactFlash Chip Enable 2
-#define AT91C_PIO_PC8 ((unsigned int) 1 << 8) // Pin Controlled by PC8
-#define AT91C_PC8_TXD0 ((unsigned int) AT91C_PIO_PC8) // USART0 Transmit Data
-#define AT91C_PC8_PCK2 ((unsigned int) AT91C_PIO_PC8) // PMC Programmable clock Output 2
-#define AT91C_PIO_PC9 ((unsigned int) 1 << 9) // Pin Controlled by PC9
-#define AT91C_PC9_RXD0 ((unsigned int) AT91C_PIO_PC9) // USART0 Receive Data
-#define AT91C_PC9_PCK3 ((unsigned int) AT91C_PIO_PC9) // PMC Programmable clock Output 3
-
-
diff --git a/sys/arm/at91/at91_pio_sam9g20.h b/sys/arm/at91/at91_pio_sam9g20.h
new file mode 100644
index 0000000..9469434
--- /dev/null
+++ b/sys/arm/at91/at91_pio_sam9g20.h
@@ -0,0 +1,180 @@
+/*
+ * Theses defines come from an atmel file that says specifically that it
+ * has no copyright.
+ */
+
+/* $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 */
diff --git a/sys/arm/at91/at91_pioreg.h b/sys/arm/at91/at91_pioreg.h
index ccb6d42..e3f2ea3 100644
--- a/sys/arm/at91/at91_pioreg.h
+++ b/sys/arm/at91/at91_pioreg.h
@@ -66,4 +66,101 @@
#define PIO_OWSR 0xa8 /* PIO Output Write Status Register */
/* 0xac reserved */
+#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
+
#endif /* ARM_AT91_AT91_PIOREG_H */
diff --git a/sys/arm/at91/at91_pit.c b/sys/arm/at91/at91_pit.c
index 516b4d4..6a6680f 100644
--- a/sys/arm/at91/at91_pit.c
+++ b/sys/arm/at91/at91_pit.c
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2010 Yohanes Nugroho. All rights reserved.
+ * 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
@@ -24,110 +25,117 @@
*/
#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
#include <sys/param.h>
-#include <sys/systm.h>
+#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
-#include <sys/time.h>
-#include <sys/bus.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/cpufunc.h>
-#include <machine/resource.h>
#include <machine/frame.h>
#include <machine/intr.h>
+#include <machine/resource.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91_pitreg.h>
-#include <arm/at91/at91_pmcvar.h>
-#include <arm/at91/at91sam9g20reg.h>
-__FBSDID("$FreeBSD$");
+static struct pit_softc {
+ struct resource *mem_res; /* Memory resource */
+ void *intrhand; /* Interrupt handle */
+ device_t sc_dev;
+} *sc;
-static struct at91pit_softc {
- bus_space_tag_t sc_st;
- bus_space_handle_t sc_sh;
- device_t sc_dev;
-} *pit_softc;
+static uint32_t timecount = 0;
-#define RD4(off) \
- bus_space_read_4(pit_softc->sc_st, pit_softc->sc_sh, (off))
-#define WR4(off, val) \
- bus_space_write_4(pit_softc->sc_st, pit_softc->sc_sh, (off), (val))
+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);
+}
static unsigned at91pit_get_timecount(struct timecounter *tc);
-static int clock_intr(void *arg);
+static int pit_intr(void *arg);
+
+#ifndef PIT_PRESCALE
+#define PIT_PRESCALE (16)
+#endif
static struct timecounter at91pit_timecounter = {
at91pit_get_timecount, /* get_timecount */
NULL, /* no poll_pps */
- 0xffffffffu, /* counter mask */
- 0, /* frequency */
- "AT91SAM9261 timer", /* name */
+ 0xffffffff, /* counter mask */
+ 0 / PIT_PRESCALE, /* frequency */
+ "AT91SAM9 timer", /* name */
1000 /* quality */
};
-
-uint32_t
-at91_pit_base(void);
-
-uint32_t
-at91_pit_size(void);
-
static int
at91pit_probe(device_t dev)
{
- device_set_desc(dev, "PIT");
- return (0);
-}
-
-uint32_t
-at91_pit_base(void)
-{
- return (AT91SAM9G20_PIT_BASE);
-}
-uint32_t
-at91_pit_size(void)
-{
- return (AT91SAM9G20_PIT_SIZE);
+ if (at91_is_sam9()) {
+ device_set_desc(dev, "AT91SAM9 PIT");
+ return (0);
+ }
+ return (ENXIO);
}
-static int pit_rate;
-static int pit_cycle;
-static int pit_counter;
-
static int
at91pit_attach(device_t dev)
{
- struct at91_softc *sc = device_get_softc(device_get_parent(dev));
- struct resource *irq;
- int rid = 0;
void *ih;
+ int rid, err = 0;
+ struct at91_softc *at91_sc;
+ struct resource *irq;
+
+ at91_sc = device_get_softc(device_get_parent(dev));
+ sc = device_get_softc(dev);
+ sc->sc_dev = dev;
- pit_softc = device_get_softc(dev);
- pit_softc->sc_st = sc->sc_st;
- pit_softc->sc_dev = dev;
- if (bus_space_subregion(sc->sc_st, sc->sc_sh, at91_pit_base(),
- at91_pit_size(), &pit_softc->sc_sh) != 0)
- panic("couldn't subregion pit registers");
+ 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)
- panic("Unable to allocate IRQ for the system timer");
- else
- bus_setup_intr(dev, irq, INTR_TYPE_CLK,
- clock_intr, NULL, NULL, &ih);
-
-
- device_printf(dev, "AT91SAM9x pit registered\n");
- return (0);
+ 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);
+
+ at91pit_timecounter.tc_frequency = at91_master_clock / PIT_PRESCALE;
+ tc_init(&at91pit_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 device_method_t at91pit_methods[] = {
@@ -139,7 +147,7 @@ static device_method_t at91pit_methods[] = {
static driver_t at91pit_driver = {
"at91_pit",
at91pit_methods,
- sizeof(struct at91pit_softc),
+ sizeof(struct pit_softc),
};
static devclass_t at91pit_devclass;
@@ -147,52 +155,58 @@ static devclass_t at91pit_devclass;
DRIVER_MODULE(at91_pit, atmelarm, at91pit_driver, at91pit_devclass, 0, 0);
static int
-clock_intr(void *arg)
+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;
- if (RD4(PIT_SR) & PIT_PITS_DONE) {
- uint32_t pivr = RD4(PIT_PIVR);
- if (PIT_CNT(pivr)>1) {
- printf("cnt = %d\n", PIT_CNT(pivr));
- }
- pit_counter += pit_cycle;
hardclock(TRAPF_USERMODE(fp), TRAPF_PC(fp));
return (FILTER_HANDLED);
}
return (FILTER_STRAY);
}
-static unsigned
+static unsigned
at91pit_get_timecount(struct timecounter *tc)
{
- return pit_counter;
+ 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);
}
-/*todo: review this*/
void
-DELAY(int n)
+DELAY(int us)
{
- u_int32_t start, end, cur;
-
- start = RD4(PIT_PIIR);
- n = (n * 1000) / (at91_master_clock / 12);
- if (n <= 0)
- n = 1;
- end = (start + n);
- cur = start;
- if (start > end) {
- while (cur >= start || cur < end)
- cur = RD4(PIT_PIIR);
- } else {
- while (cur < end)
- cur = RD4(PIT_PIIR);
+ int32_t cnt, last, piv;
+ uint64_t pit_freq;
+ const uint64_t mhz = 1E6;
+
+ last = PIT_PIV(RD4(sc, PIT_PIIR));
+
+ /* Max delay ~= 260s. @ 133Mhz */
+ pit_freq = at91_master_clock / PIT_PRESCALE;
+ cnt = ((pit_freq * us) + (mhz -1)) / 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;
}
}
/*
- * The 3 next functions must be implement with the futur PLL code.
+ * The 3 next functions must be implement with the future PLL code.
*/
void
cpu_startprofclock(void)
@@ -204,30 +218,7 @@ cpu_stopprofclock(void)
{
}
-#define HZ 100
-
void
cpu_initclocks(void)
{
- struct at91_pmc_clock *master;
-
- master = at91_pmc_clock_ref("mck");
- pit_rate = master->hz / 16;
- pit_cycle = (pit_rate + HZ/2) / HZ;
- at91pit_timecounter.tc_frequency = pit_rate;
- WR4(PIT_MR, 0);
-
- while (PIT_PIV(RD4(PIT_PIVR)) != 0);
-
- WR4(PIT_MR, (pit_cycle - 1) | PIT_IEN | PIT_EN);
- tc_init(&at91pit_timecounter);
-}
-
-void
-cpu_reset(void)
-{
- *(volatile int *)(AT91SAM9G20_BASE + AT91SAM9G20_RSTC_BASE +
- RSTC_CR) = RSTC_PROCRST | RSTC_PERRST | RSTC_KEY;
- while (1)
- continue;
}
diff --git a/sys/arm/at91/at91_pmc.c b/sys/arm/at91/at91_pmc.c
index 78d33a0..1f314c3 100644
--- a/sys/arm/at91/at91_pmc.c
+++ b/sys/arm/at91/at91_pmc.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2006 M. Warner Losh. 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
@@ -23,14 +24,13 @@
* SUCH DAMAGE.
*/
-#include "opt_at91.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>
@@ -44,8 +44,8 @@ __FBSDID("$FreeBSD$");
#include <machine/resource.h>
#include <machine/frame.h>
#include <machine/intr.h>
-#include <arm/at91/at91rm92reg.h>
-#include <arm/at91/at91sam9g20reg.h>
+#include <arm/at91/at91reg.h>
+#include <arm/at91/at91var.h>
#include <arm/at91/at91_pmcreg.h>
#include <arm/at91/at91_pmcvar.h>
@@ -59,9 +59,13 @@ static struct at91_pmc_softc {
uint32_t pllb_init;
} *pmc_softc;
+MALLOC_DECLARE(M_PMC);
+MALLOC_DEFINE(M_PMC, "at91_pmc_clocks", "AT91 PMC Clock descriptors");
+
static void at91_pmc_set_pllb_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
@@ -71,6 +75,10 @@ static struct at91_pmc_clock slck = {
.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,
@@ -115,60 +123,20 @@ static struct at91_pmc_clock uhpck = {
};
static struct at91_pmc_clock mck = {
- .name = "mck",
+ .name = "mck", // Master (Peripheral) Clock
.pmc_mask = PMC_IER_MCKRDY,
.refcnt = 0,
};
-#ifdef AT91SAM9G20
-#define IRQ_UDP AT91SAM9G20_IRQ_UDP
-#define IRQ_UHP AT91SAM9G20_IRQ_UHP
-#else
-#define IRQ_UDP AT91RM92_IRQ_UDP
-#define IRQ_UHP AT91RM92_IRQ_UHP
-#endif /* AT91SAM9G20 */
-
-static struct at91_pmc_clock udc_clk = {
- .name = "udc_clk",
- .parent = &mck,
- .pmc_mask = 1 << IRQ_UDP,
- .set_mode = &at91_pmc_set_periph_mode
-};
-
-static struct at91_pmc_clock ohci_clk = {
- .name = "ohci_clk",
- .parent = &mck,
- .pmc_mask = 1 << IRQ_UHP,
- .set_mode = &at91_pmc_set_periph_mode
-};
-
-#ifdef AT91SAM9G20
-static struct at91_pmc_clock macb_clk = {
- .name = "macb_clk",
- .parent = &mck,
-
- .pmc_mask = 1 << 21,
- .set_mode = &at91_pmc_set_periph_mode
-};
-
-static struct at91_pmc_clock spi0_clk = {
- .name = "spi0_clk",
- .parent = &mck,
-
- .pmc_mask = 1 << 12,
- .set_mode = &at91_pmc_set_periph_mode
-};
-
-static struct at91_pmc_clock spi1_clk = {
- .name = "spi1_clk",
- .parent = &mck,
- .pmc_mask = 1 << 13,
- .set_mode = &at91_pmc_set_periph_mode
+static struct at91_pmc_clock cpu = {
+ .name = "cpu", // CPU Clock
+ .parent = &plla,
+ .pmc_mask = PMC_SCER_PCK,
+ .refcnt = 0,
};
-#endif /* AT91SAM9G20 */
-
-static struct at91_pmc_clock *const clock_list[] = {
+/* "+32" or the automatic peripheral clocks */
+static struct at91_pmc_clock *clock_list[16+32] = {
&slck,
&main_ck,
&plla,
@@ -176,13 +144,7 @@ static struct at91_pmc_clock *const clock_list[] = {
&udpck,
&uhpck,
&mck,
- &udc_clk,
-#ifdef AT91SAM9G20
- &macb_clk,
- &spi0_clk,
- &spi1_clk,
-#endif /* AT91SAM9G20 */
- &ohci_clk
+ &cpu
};
#if !defined(AT91C_MAIN_CLOCK)
@@ -200,7 +162,7 @@ static const unsigned int at91_mainf_tbl[] = {
static inline uint32_t
RD4(struct at91_pmc_softc *sc, bus_size_t off)
{
- return bus_read_4(sc->mem_res, off);
+ return (bus_read_4(sc->mem_res, off));
}
static inline void
@@ -209,7 +171,7 @@ WR4(struct at91_pmc_softc *sc, bus_size_t off, uint32_t val)
bus_write_4(sc->mem_res, off, val);
}
-static void
+void
at91_pmc_set_pllb_mode(struct at91_pmc_clock *clk, int on)
{
struct at91_pmc_softc *sc = pmc_softc;
@@ -221,6 +183,15 @@ at91_pmc_set_pllb_mode(struct at91_pmc_clock *clk, int on)
} else {
value = 0;
}
+
+ /* Workaround RM9200 Errata #26 */
+ if (at91_is_rm92() &&
+ ((value ^ RD4(sc, CKGR_PLLBR)) & 0x03f0ff) != 0) {
+ WR4(sc, CKGR_PLLBR, value ^ 1);
+ while ((RD4(sc, PMC_SR) & PMC_IER_LOCKB) != on)
+ continue;
+ }
+
WR4(sc, CKGR_PLLBR, value);
while ((RD4(sc, PMC_SR) & PMC_IER_LOCKB) != on)
continue;
@@ -255,14 +226,74 @@ at91_pmc_set_periph_mode(struct at91_pmc_clock *clk, int on)
}
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, M_NOWAIT | M_ZERO);
+ if (clk == NULL)
+ goto err;
+
+ buflen = strlen(name) + 1;
+ clk->name = malloc(buflen, M_PMC, 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 < sizeof(clock_list) / sizeof(clock_list[0]); 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);
+ free(clk, M_PMC);
+ }
+
+ 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 < sizeof(clock_list) / sizeof(clock_list[0]); i++)
+ for (i = 0; i < sizeof(clock_list) / sizeof(clock_list[0]); i++) {
+ if (clock_list[i] == NULL)
+ break;
if (strcmp(name, clock_list[i]->name) == 0)
return (clock_list[i]);
+ }
+ //printf("at91_pmc: Warning - did not find clock '%s'", name);
return (NULL);
}
@@ -292,55 +323,48 @@ at91_pmc_clock_disable(struct at91_pmc_clock *clk)
}
static int
-at91_pmc_pll_rate(int freq, uint32_t reg, int is_pllb)
+at91_pmc_pll_rate(struct at91_pmc_clock *clk, uint32_t reg)
{
- uint32_t mul, div;
+ 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;
- div = reg & 0xff;
-#ifdef AT91SAM9G20
- if (is_pllb)
- mul = (reg >> 16) & 0x3f;
- else
- mul = (reg >> 16) & 0xff;
-#else
- mul = (reg >> 16) & 0x7ff;
-#endif
if (div != 0 && mul != 0) {
freq /= div;
freq *= mul + 1;
} else {
freq = 0;
}
-#ifndef AT91SAM9G20
- if (is_pllb && (reg & (1 << 28)))
- freq >>= 1;
-#endif
+ clk->hz = freq;
return (freq);
}
static uint32_t
-at91_pmc_pll_calc(uint32_t main_freq, uint32_t out_freq)
+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 = (out_freq > PMC_PLL_FAST_THRESH) ? 0xbe00 : 0x3e00;
- if (out_freq > PMC_PLL_MAX_OUT_FREQ)
+ 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 = main_freq / i;
- if (input < PMC_PLL_MIN_IN_FREQ)
+ input = clk->parent->hz / i;
+ if (input < clk->pll_min_in)
break;
- if (input > PMC_PLL_MAX_IN_FREQ)
+ if (input > clk->pll_max_in)
continue;
mul1 = out_freq / input;
- if (mul1 > PMC_PLL_MULT_MAX)
+ if (mul1 > (clk->pll_mul_mask + 1))
continue;
- if (mul1 < PMC_PLL_MULT_MIN)
+ if (mul1 == 0)
break;
diff1 = out_freq - input * mul1;
@@ -356,53 +380,93 @@ at91_pmc_pll_calc(uint32_t main_freq, uint32_t out_freq)
}
if (diff > (out_freq >> PMC_PLL_SHIFT_TOL))
goto fail;
- return ret | ((mul - 1) << 16) | div;
+
+ 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;
+ return (0);
}
static void
at91_pmc_init_clock(struct at91_pmc_softc *sc, unsigned int main_clock)
{
uint32_t mckr;
- int freq;
+ uint32_t mdiv;
+ if (at91_is_sam9()) {
+ uhpck.pmc_mask = PMC_SCER_UHP_SAM9;
+ udpck.pmc_mask = PMC_SCER_UDP_SAM9;
+ }
+ mckr = RD4(sc, PMC_MCKR);
sc->main_clock_hz = main_clock;
main_ck.hz = main_clock;
- plla.hz = at91_pmc_pll_rate(main_clock, RD4(sc, CKGR_PLLAR), 0);
+
+ at91_pmc_pll_rate(&plla, RD4(sc, CKGR_PLLAR));
+
+ if (at91_cpu_is(AT91_CPU_SAM9G45) && (mckr & PMC_MCKR_PLLADIV2))
+ plla.hz /= 2;
/*
* Initialize the usb clock. This sets up pllb, but disables the
* actual clock.
*/
- sc->pllb_init = at91_pmc_pll_calc(main_clock, 48000000 * 2) |0x10000000;
- pllb.hz = at91_pmc_pll_rate(main_clock, sc->pllb_init, 1);
- WR4(sc, PMC_PCDR, (1 << IRQ_UHP) | (1 << IRQ_UDP));
- WR4(sc, PMC_SCDR, PMC_SCER_UHP | PMC_SCER_UDP);
- WR4(sc, CKGR_PLLBR, 0);
-#ifndef AT91SAM9G20
- WR4(sc, PMC_SCER, PMC_SCER_MCKUDP);
+ sc->pllb_init = at91_pmc_pll_calc(&pllb, 48000000 * 2) | 0x10000000;
+ at91_pmc_pll_rate(&pllb, sc->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);
+ }
+ WR4(sc, CKGR_PLLBR, 0);
+
/*
* MCK and PCU derive from one of the primary clocks. Initialize
* this relationship.
*/
- mckr = RD4(sc, PMC_MCKR);
mck.parent = clock_list[mckr & 0x3];
mck.parent->refcnt++;
- freq = mck.parent->hz / (1 << ((mckr >> 2) & 3));
- mck.hz = freq / (1 + ((mckr >> 8) & 3));
+
+ 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()) {
+ mck.hz /= (mdiv) ? (mdiv * 2) : 1;
+ } else
+ mck.hz /= (1 + mdiv);
+
+ /* Only found on SAM9G20 */
+ if (at91_cpu_is(AT91_CPU_SAM9G20))
+ cpu.hz /= (mckr & PMC_MCKR_PDIV) ? 2 : 1;
+
+ at91_master_clock = mck.hz;
device_printf(sc->dev,
"Primary: %d Hz PLLA: %d MHz CPU: %d MHz MCK: %d MHz\n",
sc->main_clock_hz,
- at91_pmc_pll_rate(main_clock, RD4(sc, CKGR_PLLAR), 0) / 1000000,
- freq / 1000000, mck.hz / 1000000);
+ plla.hz / 1000000,
+ cpu.hz / 1000000, mck.hz / 1000000);
+
+ /* 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);
}
@@ -482,7 +546,7 @@ at91_pmc_attach(device_t dev)
pmc_softc = device_get_softc(dev);
pmc_softc->dev = dev;
if ((err = at91_pmc_activate(dev)) != 0)
- return err;
+ return (err);
/*
* Configure main clock frequency.
@@ -493,6 +557,11 @@ at91_pmc_attach(device_t dev)
mainf = AT91C_MAIN_CLOCK;
#endif
at91_pmc_init_clock(pmc_softc, mainf);
+
+ /* These clocks refrenced by "special" names */
+ at91_pmc_clock_alias("ohci0", "ohci_clk");
+ at91_pmc_clock_alias("udp0", "udp_clk");
+
return (0);
}
diff --git a/sys/arm/at91/at91_pmcreg.h b/sys/arm/at91/at91_pmcreg.h
index 54de9f4..a39a0fe 100644
--- a/sys/arm/at91/at91_pmcreg.h
+++ b/sys/arm/at91/at91_pmcreg.h
@@ -58,21 +58,6 @@
#define PMC_SR 0x68 /* Status Register */
#define PMC_IMR 0x6c /* Interrupt Mask Register */
-#ifdef AT91SAM9G20
-/* PMC Specific AT91SAM9G20 */
-
-/* PMC System Clock Enable Register */
-/* PMC System Clock Disable Register */
-/* PMC System Clock StatusRegister */
-#define PMC_SCER_UHP (1UL << 6) /* UHP: USB Host Port Clock Enable */
-#define PMC_SCER_UDP (1UL << 7) /* UDP: USB Device 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 */
-
-#else
-
/* PMC System Clock Enable Register */
/* PMC System Clock Disable Register */
/* PMC System Clock StatusRegister */
@@ -81,11 +66,12 @@
#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 << 10) /* PCK1: Programmable Clock out en */
-#define PMC_SCER_PCK2 (1UL << 11) /* PCK2: Programmable Clock out en */
-#define PMC_SCER_PCK3 (1UL << 12) /* PCK3: 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 */
-#endif /* AT91SAM9G20 */
/* PMC Peripheral Clock Enable Register */
/* PMC Peripheral Clock Disable Register */
/* PMC Peripheral Clock Status Register */
@@ -100,6 +86,13 @@
#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 << 8)
+#define PMC_MCKR_MDIV_MASK (3 << 8)
+#define PMC_MCKR_PRES_MASK (7 << 2)
+
/* PMC Interrupt Enable Register */
/* PMC Interrupt Disable Register */
/* PMC Status Register */
diff --git a/sys/arm/at91/at91_pmcvar.h b/sys/arm/at91/at91_pmcvar.h
index a4ebba7..22255d6 100644
--- a/sys/arm/at91/at91_pmcvar.h
+++ b/sys/arm/at91/at91_pmcvar.h
@@ -30,7 +30,7 @@
struct at91_pmc_clock
{
- const char *name;
+ char *name;
uint32_t hz;
struct at91_pmc_clock *parent;
uint32_t pmc_mask;
@@ -40,8 +40,23 @@ struct at91_pmc_clock
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 *);
diff --git a/sys/arm/at91/at91_reset.S b/sys/arm/at91/at91_reset.S
new file mode 100644
index 0000000..e3b1d00
--- /dev/null
+++ b/sys/arm/at91/at91_reset.S
@@ -0,0 +1,57 @@
+#include <machine/asm.h>
+#include <arm/at91/at91_rstreg.h>
+#include <arm/at91/at91sam9g20reg.h>
+__FBSDID("$FreeBSD$");
+
+#define SDRAM_TR (AT91SAM9G20_BASE + \
+ AT91SAM9G20_SDRAMC_BASE + AT91SAM9G20_SDRAMC_TR)
+#define SDRAM_LPR (AT91SAM9G20_BASE + \
+ AT91SAM9G20_SDRAMC_BASE + AT91SAM9G20_SDRAMC_LPR)
+#define RSTC_RCR (AT91SAM9G20_BASE + \
+ AT91SAM9G20_RSTC_BASE + RST_CR)
+
+/*
+ * From AT91SAM9G20 Datasheet errata 44:3.5:
+ *
+ * When User Reset occurs durring SDRAM read acces, eh 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
+ * 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]
diff --git a/sys/arm/at91/at91_rst.c b/sys/arm/at91/at91_rst.c
new file mode 100644
index 0000000..0e50b39
--- /dev/null
+++ b/sys/arm/at91/at91_rst.c
@@ -0,0 +1,215 @@
+/*-
+ * 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/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>
+
+#define RST_TIMEOUT (5) /* Seconds to hold NRST for hard reset */
+#define RST_TICK (20) /* sample NRST at hz/RST_TICK intervals */
+
+static int rst_intr(void *arg);
+
+static struct 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 */
+} *rst_sc;
+
+static inline uint32_t
+RD4(struct rst_softc *sc, bus_size_t off)
+{
+
+ return (bus_read_4(sc->mem_res, off));
+}
+
+static inline void
+WR4(struct rst_softc *sc, bus_size_t off, uint32_t val)
+{
+
+ bus_write_4(sc->mem_res, off, val);
+}
+
+static int
+at91_rst_probe(device_t dev)
+{
+
+ if (at91_is_sam9()) {
+ device_set_desc(dev, "AT91SAM9 Reset Controller");
+ return (0);
+ }
+ return (ENXIO);
+}
+
+static int
+at91_rst_attach(device_t dev)
+{
+ struct rst_softc *sc;
+ const char *cause;
+ int rid, err;
+
+ rst_sc = sc = device_get_softc(dev);
+ sc->sc_dev = dev;
+
+ callout_init(&sc->tick_ch, 0);
+
+ 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;
+ }
+ 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,
+ rst_intr, NULL, sc, &sc->intrhand);
+ if (err)
+ device_printf(dev, "could not establish interrupt handler.\n");
+
+ WR4(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);
+ /* cpu_reset_addr = cpu_reset; */
+
+out:
+ return (err);
+}
+
+static void
+rst_tick(void *argp)
+{
+ struct 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, rst_tick, sc);
+ }
+}
+
+static int
+rst_intr(void *argp)
+{
+ struct rst_softc *sc = argp;
+
+ if (RD4(sc, RST_SR) & RST_SR_URSTS) {
+ if (sc->shutdown == 0)
+ callout_reset(&sc->tick_ch, hz/RST_TICK, rst_tick, sc);
+ return (FILTER_HANDLED);
+ }
+ return (FILTER_STRAY);
+}
+
+static device_method_t at91_rst_methods[] = {
+ DEVMETHOD(device_probe, at91_rst_probe),
+ DEVMETHOD(device_attach, at91_rst_attach),
+ {0,0},
+};
+
+static driver_t at91_rst_driver = {
+ "at91_rst",
+ at91_rst_methods,
+ sizeof(struct rst_softc),
+};
+
+static devclass_t at91_rst_devclass;
+
+DRIVER_MODULE(at91_rst, atmelarm, at91_rst_driver, at91_rst_devclass, 0, 0);
+
+void cpu_reset_sam9g20(void) __attribute__((weak));
+void cpu_reset_sam9g20(void) {}
+
+void
+cpu_reset(void)
+{
+
+ if (rst_sc) {
+ if (at91_cpu_is(AT91_CPU_SAM9G20))
+ cpu_reset_sam9g20();
+
+ WR4(rst_sc, RST_MR,
+ RST_MR_ERSTL(0xd) | RST_MR_URSTEN | RST_MR_KEY);
+
+ WR4(rst_sc, RST_CR,
+ RST_CR_PROCRST |
+ RST_CR_PERRST |
+ RST_CR_EXTRST |
+ RST_CR_KEY);
+ }
+
+ for(;;) ;
+}
diff --git a/sys/arm/at91/at91_rstreg.h b/sys/arm/at91/at91_rstreg.h
new file mode 100644
index 0000000..f075b2c
--- /dev/null
+++ b/sys/arm/at91/at91_rstreg.h
@@ -0,0 +1,59 @@
+/*-
+ * 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_AT91RSTREG_H
+#define ARM_AT91_AT91RSTREG_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)
+
+#endif /* ARM_AT91_AT91RSTREG_H */
diff --git a/sys/arm/at91/at91_twi.c b/sys/arm/at91/at91_twi.c
index b101772..fdd377a 100644
--- a/sys/arm/at91/at91_twi.c
+++ b/sys/arm/at91/at91_twi.c
@@ -39,7 +39,6 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <machine/bus.h>
-#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91_twireg.h>
#include <arm/at91/at91var.h>
diff --git a/sys/arm/at91/at91_twireg.h b/sys/arm/at91/at91_twireg.h
index 6cca101..7d61a4a 100644
--- a/sys/arm/at91/at91_twireg.h
+++ b/sys/arm/at91/at91_twireg.h
@@ -63,7 +63,10 @@
#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_master_clock /(4*(rate))) - 2)
+#define TWI_CWGR_DIV(rate) \
+ (at91_is_sam9() ? \
+ ((at91_master_clock /(4*(rate))) - 3) : \
+ ((at91_master_clock /(4*(rate))) - 2))
/* TWI_SR */
/* TWI_IER */
diff --git a/sys/arm/at91/at91_wdt.c b/sys/arm/at91/at91_wdt.c
new file mode 100644
index 0000000..6ae01ef
--- /dev/null
+++ b/sys/arm/at91/at91_wdt.c
@@ -0,0 +1,222 @@
+/*-
+ * 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 16s in wdt_attach and only reset it in the wdt_tick
+ * handler. The watchdog is halted in processor debug mode.
+ */
+
+#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>
+
+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 of 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)
+{
+
+ if (at91_is_sam9()) {
+ device_set_desc(dev, "WDT");
+ return (0);
+ }
+ return (ENXIO);
+}
+
+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),
+ {0,0},
+};
+
+static driver_t wdt_driver = {
+ "at91_wdt",
+ wdt_methods,
+ sizeof(struct wdt_softc),
+};
+
+static devclass_t wdt_devclass;
+
+DRIVER_MODULE(at91_wdt, atmelarm, wdt_driver, wdt_devclass, 0, 0);
diff --git a/sys/arm/at91/at91_wdtreg.h b/sys/arm/at91/at91_wdtreg.h
new file mode 100644
index 0000000..56e8f1b
--- /dev/null
+++ b/sys/arm/at91/at91_wdtreg.h
@@ -0,0 +1,60 @@
+/*-
+ * 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 */
diff --git a/sys/arm/at91/at91reg.h b/sys/arm/at91/at91reg.h
new file mode 100644
index 0000000..03e31cb
--- /dev/null
+++ b/sys/arm/at91/at91reg.h
@@ -0,0 +1,70 @@
+/*-
+ * 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
+
+/* A few things that we count on being the same
+ * throught the whole family of SOCs */
+
+/* SYSC System Controler */
+/* System Registers */
+#define AT91_SYS_BASE 0xffff000
+#define AT91_SYS_SIZE 0x1000
+
+#if defined(AT91SAM9G45) || defined(AT91SAM9263)
+#define AT91_DBGU_BASE 0xfffee00
+#else
+#define AT91_DBGU_BASE 0xffff200
+#endif
+#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_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_ARCH(chipid) ((chipid >> 20) & 0xff)
+#define AT91_CPU(chipid) (chipid & ~AT91_CPU_VERSION_MASK)
+#define AT91_ARCH_SAM9 (0x19)
+#define AT91_ARCH_RM92 (0x92)
+
+#endif /* _AT91REG_H_ */
diff --git a/sys/arm/at91/at91rm9200.c b/sys/arm/at91/at91rm9200.c
new file mode 100644
index 0000000..27faaff
--- /dev/null
+++ b/sys/arm/at91/at91rm9200.c
@@ -0,0 +1,330 @@
+/*-
+ * 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/at91rm92reg.h>
+#include <arm/at91/at91_aicreg.h>
+#include <arm/at91/at91_pmcreg.h>
+#include <arm/at91/at91_pmcvar.h>
+
+struct at91rm92_softc {
+ device_t dev;
+ bus_space_tag_t sc_st;
+ bus_space_handle_t sc_sh;
+ bus_space_handle_t sc_sys_sh;
+ bus_space_handle_t sc_aic_sh;
+ bus_space_handle_t sc_dbg_sh;
+ bus_space_handle_t sc_matrix_sh;
+};
+/*
+ * 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) */
+};
+
+#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_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),
+
+#ifndef SKYEYE_WORKAROUNDS
+ DEVICE("uart", DBGU, 0),
+ DEVICE("uart", USART0, 1),
+ DEVICE("uart", USART1, 2),
+ DEVICE("uart", USART2, 3),
+ DEVICE("uart", USART3, 4),
+#else
+ DEVICE("uart", USART0, 0),
+#endif
+ DEVICE("at91_aic", AIC, 0),
+ DEVICE("at91_mc", MC, 0),
+ DEVICE("at91_tc", TC0, 0),
+ DEVICE("at91_tc", TC1, 1),
+ DEVICE("ohci", OHCI, 0),
+ DEVICE("af91_cfata", CF, 0),
+ { 0, 0, 0, 0, 0 }
+};
+
+static 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 != AT91RM92_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);
+ if (addr != 0 && addr < AT91RM92_BASE)
+ addr += AT91RM92_BASE;
+ if (addr != 0)
+ bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
+}
+
+static void
+at91_cpu_add_builtin_children(device_t dev)
+{
+ int i;
+ const struct cpu_devs *walker;
+
+ for (i = 1, walker = at91_devs; 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 uint32_t
+at91_pll_outb(int freq)
+{
+
+ if (freq > 155000000)
+ return (0x0000);
+ else
+ return (0x8000);
+}
+
+static void
+at91_identify(driver_t *drv, device_t parent)
+{
+
+ if (at91_cpu_is(AT91_CPU_RM9200)) {
+ at91_add_child(parent, 0, "at91rm920", 0, 0, 0, -1, 0, 0);
+ at91_cpu_add_builtin_children(parent);
+ }
+}
+
+static int
+at91_probe(device_t dev)
+{
+
+ if (at91_cpu_is(AT91_CPU_RM9200)) {
+ device_set_desc(dev, "AT91RM9200");
+ return (0);
+ }
+ return (ENXIO);
+}
+
+static int
+at91_attach(device_t dev)
+{
+ struct at91_pmc_clock *clk;
+ struct at91rm92_softc *sc = device_get_softc(dev);
+ int i;
+
+ struct at91_softc *at91sc = device_get_softc(device_get_parent(dev));
+
+ sc->sc_st = at91sc->sc_st;
+ sc->sc_sh = at91sc->sc_sh;
+ sc->dev = dev;
+
+ if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91RM92_SYS_BASE,
+ AT91RM92_SYS_SIZE, &sc->sc_sys_sh) != 0)
+ panic("Enable to map system registers");
+
+ if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91RM92_DBGU_BASE,
+ AT91RM92_DBGU_SIZE, &sc->sc_dbg_sh) != 0)
+ panic("Enable to map DBGU registers");
+
+ if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91RM92_AIC_BASE,
+ AT91RM92_AIC_SIZE, &sc->sc_aic_sh) != 0)
+ panic("Enable to map system registers");
+
+ /* XXX Hack to tell atmelarm about the AIC */
+ at91sc->sc_aic_sh = sc->sc_aic_sh;
+ at91sc->sc_irq_system = AT91RM92_IRQ_SYSTEM;
+
+ for (i = 0; i < 32; i++) {
+ bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SVR +
+ i * 4, i);
+ /* Priority. */
+ bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SMR + i * 4,
+ at91_irq_prio[i]);
+ if (i < 8)
+ bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_EOICR,
+ 1);
+ }
+
+ bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SPU, 32);
+ /* No debug. */
+ bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_DCR, 0);
+ /* Disable and clear all interrupts. */
+ bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_IDCR, 0xffffffff);
+ bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_ICCR, 0xffffffff);
+
+ /* 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);
+
+ /* Disable all interrupts for DBGU */
+ bus_space_write_4(sc->sc_st, sc->sc_dbg_sh, 0x0c, 0xffffffff);
+
+ /* 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);
+
+ return (0);
+}
+
+static device_method_t at91_methods[] = {
+ DEVMETHOD(device_probe, at91_probe),
+ DEVMETHOD(device_attach, at91_attach),
+ DEVMETHOD(device_identify, at91_identify),
+ {0, 0},
+};
+
+static driver_t at91rm92_driver = {
+ "at91rm920",
+ at91_methods,
+ sizeof(struct at91rm92_softc),
+};
+
+static devclass_t at91rm92_devclass;
+
+DRIVER_MODULE(at91rm920, atmelarm, at91rm92_driver, at91rm92_devclass, 0, 0);
diff --git a/sys/arm/at91/at91rm92reg.h b/sys/arm/at91/at91rm92reg.h
index b7ca805..8241646a 100644
--- a/sys/arm/at91/at91rm92reg.h
+++ b/sys/arm/at91/at91rm92reg.h
@@ -27,6 +27,33 @@
#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
@@ -45,20 +72,26 @@
#define AT91RM92_BASE 0xd0000000
/* 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_USART_SIZE 0x4000
+#define AT91RM92_USART3_SIZE AT91RM92_USART_SIZE
/* System Registers */
#define AT91RM92_SYS_BASE 0xffff000
#define AT91RM92_SYS_SIZE 0x1000
+
+#if 0
/* Interrupt Controller */
#define IC_SMR (0) /* Source mode register */
#define IC_SVR (128) /* Source vector register */
@@ -79,13 +112,6 @@
#define IC_FFDR (324) /* Fast forcing disable register */
#define IC_FFSR (328) /* Fast forcing status register */
-/* DBGU */
-
-#define DBGU 0x200
-#define DBGU_SIZE 0x200
-#define DBGU_C1R (0x200 + 64) /* Chip ID1 Register */
-#define DBGU_C2R (0x200 + 68) /* Chip ID2 Register */
-#define DBGU_FNTR (0x200 + 72) /* Force NTRST Register */
#define PIOA_PER (0x400) /* PIO Enable Register */
#define PIOA_PDR (0x400 + 4) /* PIO Disable Register */
@@ -204,14 +230,19 @@
#define PIOD_OWDR (0xa00 + 164) /* Output write disable register */
#define PIOD_OWSR (0xa00 + 168) /* Output write status register */
+#endif
/*
* PIO
*/
-#define AT91RM92_PIOA_BASE 0xffff400
#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
@@ -271,21 +302,40 @@
#define AT91RM92_IRQ_SSC0 14
#define AT91RM92_IRQ_SSC1 15
#define AT91RM92_IRQ_SSC2 16
-#define AT91RM92_IRQ_TC0 17
-#define AT91RM92_IRQ_TC1 18
-#define AT91RM92_IRQ_TC2 19
-#define AT91RM92_IRQ_TC3 20
-#define AT91RM92_IRQ_TC4 21
-#define AT91RM92_IRQ_TC5 22
+#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_BASE 25
+#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
@@ -302,16 +352,18 @@
#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_SSC_SIZE 0x4000
+#define AT91RM92_SSC2_SIZE AT91RM92_SSC_SIZE
#define AT91RM92_EMAC_BASE 0xffbc000
#define AT91RM92_EMAC_SIZE 0x4000
@@ -326,17 +378,23 @@
#define AT91RM92_UDP_BASE 0xffb0000
#define AT91RM92_UDP_SIZE 0x4000
-#define AT91RM92_TC0_BASE 0xffa0000
#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_BASE 0xdfe00000
#define AT91RM92_OHCI_PA_BASE 0x00300000
#define AT91RM92_OHCI_SIZE 0x00100000
diff --git a/sys/arm/at91/at91sam9.c b/sys/arm/at91/at91sam9.c
deleted file mode 100644
index a6510ea..0000000
--- a/sys/arm/at91/at91sam9.c
+++ /dev/null
@@ -1,717 +0,0 @@
-/*-
- * 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/bus.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-
-#include <vm/vm.h>
-#include <vm/vm_kern.h>
-#include <vm/pmap.h>
-#include <vm/vm_page.h>
-#include <vm/vm_extern.h>
-
-#define _ARM32_BUS_DMA_PRIVATE
-#include <machine/bus.h>
-#include <machine/intr.h>
-#include <arm/at91/at91_aicreg.h>
-#include <arm/at91/at91sam9g20reg.h>
-#include <arm/at91/at91var.h>
-
-static struct at91_softc *at91_softc;
-
-static void at91_eoi(void *);
-
-uint32_t at91_master_clock = AT91C_MASTER_CLOCK;
-
-static int
-at91_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flags,
- bus_space_handle_t *bshp)
-{
- vm_paddr_t pa, endpa;
-
- pa = trunc_page(bpa);
- if (pa >= 0xfff00000) {
- *bshp = pa - 0xf0000000 + 0xd0000000;
- return (0);
- }
- if (pa >= 0xdff00000)
- return (0);
- endpa = round_page(bpa + size);
-
- *bshp = (vm_offset_t)pmap_mapdev(pa, endpa - pa);
-
- return (0);
-}
-
-static void
-at91_bs_unmap(void *t, bus_space_handle_t h, bus_size_t size)
-{
- vm_offset_t va, endva;
-
- va = trunc_page((vm_offset_t)t);
- endva = va + round_page(size);
-
- /* Free the kernel virtual mapping. */
- kmem_free(kernel_map, va, endva - va);
-}
-
-static int
-at91_bs_subregion(void *t, bus_space_handle_t bsh, bus_size_t offset,
- bus_size_t size, bus_space_handle_t *nbshp)
-{
-
- *nbshp = bsh + offset;
- return (0);
-}
-
-static void
-at91_barrier(void *t, bus_space_handle_t bsh, bus_size_t size, bus_size_t b,
- int a)
-{
-}
-
-bs_protos(generic);
-bs_protos(generic_armv4);
-
-struct bus_space at91_bs_tag = {
- /* cookie */
- (void *) 0,
-
- /* mapping/unmapping */
- at91_bs_map,
- at91_bs_unmap,
- at91_bs_subregion,
-
- /* allocation/deallocation */
- NULL,
- NULL,
-
- /* barrier */
- at91_barrier,
-
- /* read (single) */
- generic_bs_r_1,
- generic_armv4_bs_r_2,
- generic_bs_r_4,
- NULL,
-
- /* read multiple */
- generic_bs_rm_1,
- generic_armv4_bs_rm_2,
- generic_bs_rm_4,
- NULL,
-
- /* read region */
- generic_bs_rr_1,
- generic_armv4_bs_rr_2,
- generic_bs_rr_4,
- NULL,
-
- /* write (single) */
- generic_bs_w_1,
- generic_armv4_bs_w_2,
- generic_bs_w_4,
- NULL,
-
- /* write multiple */
- generic_bs_wm_1,
- generic_armv4_bs_wm_2,
- generic_bs_wm_4,
- NULL,
-
- /* write region */
- NULL,
- generic_armv4_bs_wr_2,
- generic_bs_wr_4,
- NULL,
-
- /* set multiple */
- NULL,
- NULL,
- NULL,
- NULL,
-
- /* set region */
- NULL,
- generic_armv4_bs_sr_2,
- generic_bs_sr_4,
- NULL,
-
- /* copy */
- NULL,
- generic_armv4_bs_c_2,
- NULL,
- NULL,
-
- /* read (single) stream */
- generic_bs_r_1,
- generic_armv4_bs_r_2,
- generic_bs_r_4,
- NULL,
-
- /* read multiple stream */
- generic_bs_rm_1,
- generic_armv4_bs_rm_2,
- generic_bs_rm_4,
- NULL,
-
- /* read region stream */
- generic_bs_rr_1,
- generic_armv4_bs_rr_2,
- generic_bs_rr_4,
- NULL,
-
- /* write (single) stream */
- generic_bs_w_1,
- generic_armv4_bs_w_2,
- generic_bs_w_4,
- NULL,
-
- /* write multiple stream */
- generic_bs_wm_1,
- generic_armv4_bs_wm_2,
- generic_bs_wm_4,
- NULL,
-
- /* write region stream */
- NULL,
- generic_armv4_bs_wr_2,
- generic_bs_wr_4,
- NULL,
-};
-
-static int
-at91_probe(device_t dev)
-{
- device_set_desc(dev, "AT91 device bus");
- arm_post_filter = at91_eoi;
- return (0);
-}
-
-static void
-at91_identify(driver_t *drv, device_t parent)
-{
-
- BUS_ADD_CHILD(parent, 0, "atmelarm", 0);
-}
-
-struct arm32_dma_range *
-bus_dma_get_range(void)
-{
-
- return (NULL);
-}
-
-int
-bus_dma_get_range_nb(void)
-{
- return (0);
-}
-
-extern void irq_entry(void);
-
-static 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 (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);
- if (addr != 0)
- bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
-}
-
-struct cpu_devs
-{
- const char *name;
- int unit;
- bus_addr_t mem_base;
- bus_size_t mem_len;
- int irq0;
- int irq1;
- int irq2;
-};
-
-struct cpu_devs at91sam9_devs[] =
-{
- {
- "at91_pit", 0,
- AT91SAM9G20_BASE + AT91SAM9G20_PIT_BASE, AT91SAM9G20_PIT_SIZE,
- AT91SAM9G20_IRQ_SYSTEM
- },
- {
- "at91_wdt", 0,
- AT91SAM9G20_BASE + AT91SAM9G20_WDT_BASE, AT91SAM9G20_WDT_SIZE,
- AT91SAM9G20_IRQ_SYSTEM
- },
- {
- "at91_pmc", 0,
- AT91SAM9G20_BASE + AT91SAM9G20_PMC_BASE, AT91SAM9G20_PMC_SIZE,
- AT91SAM9G20_IRQ_SYSTEM
- },
- {
- "at91_pio", 0,
- AT91SAM9G20_BASE + AT91SAM9G20_PIOA_BASE, AT91SAM9G20_PIO_SIZE,
- AT91SAM9G20_IRQ_SYSTEM
- },
- {
- "at91_pio", 1,
- AT91SAM9G20_BASE + AT91SAM9G20_PIOB_BASE, AT91SAM9G20_PIO_SIZE,
- AT91SAM9G20_IRQ_SYSTEM
- },
- {
- "at91_pio", 2,
- AT91SAM9G20_BASE + AT91SAM9G20_PIOC_BASE, AT91SAM9G20_PIO_SIZE,
- AT91SAM9G20_IRQ_SYSTEM
- },
- {
- "uart", 0,
- AT91SAM9G20_BASE + AT91SAM9G20_DBGU_BASE, AT91SAM9G20_DBGU_SIZE,
- AT91SAM9G20_IRQ_SYSTEM
- },
- {
- "uart", 1,
- AT91SAM9G20_BASE + AT91SAM9G20_USART0_BASE, AT91SAM9G20_USART_SIZE,
- AT91SAM9G20_IRQ_USART0
- },
- {
- "uart", 2,
- AT91SAM9G20_BASE + AT91SAM9G20_USART1_BASE, AT91SAM9G20_USART_SIZE,
- AT91SAM9G20_IRQ_USART1
- },
- {
- "uart", 3,
- AT91SAM9G20_BASE + AT91SAM9G20_USART2_BASE, AT91SAM9G20_USART_SIZE,
- AT91SAM9G20_IRQ_USART2
- },
- {
- "spi", 0,
- AT91SAM9G20_BASE + AT91SAM9G20_SPI0_BASE, AT91SAM9G20_SPI0_SIZE,
- AT91SAM9G20_IRQ_SPI0
- },
- {
- "spi", 1,
- AT91SAM9G20_BASE + AT91SAM9G20_SPI1_BASE, AT91SAM9G20_SPI1_SIZE,
- AT91SAM9G20_IRQ_SPI1
- },
- {
- "ohci", 0,
- AT91SAM9G20_OHCI_BASE, AT91SAM9G20_OHCI_SIZE,
- AT91SAM9G20_IRQ_UHP
- },
- {
- "macb", 0,
- AT91SAM9G20_BASE + AT91SAM9G20_EMAC_BASE, AT91SAM9G20_EMAC_SIZE,
- AT91SAM9G20_IRQ_EMAC
- },
- {
- "nand", 0,
- AT91SAM9G20_NAND_BASE, AT91SAM9G20_NAND_SIZE,
- -1
- },
- { 0, 0, 0, 0, 0 }
-};
-
-static void
-at91_cpu_add_builtin_children(device_t dev, struct at91_softc *sc)
-{
- int i;
- struct cpu_devs *walker;
-
- // XXX should look at the device id in the DBGU register and
- // XXX based on the CPU load in these devices
- for (i = 0, walker = at91sam9_devs; 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);
- }
-}
-
-#define NORMDEV 50
-
-/*
- * 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 int 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,
- 0,
- 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 */
- 0, /* Advanced Interrupt Controller */
- 0, /* Advanced Interrupt Controller */
-};
-
-static int
-at91_attach(device_t dev)
-{
- struct at91_softc *sc = device_get_softc(dev);
- int i;
-
- at91_softc = sc;
- sc->sc_st = &at91_bs_tag;
- sc->sc_sh = AT91SAM9G20_BASE;
- sc->dev = dev;
- if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9G20_SYS_BASE,
- AT91SAM9G20_SYS_SIZE, &sc->sc_sys_sh) != 0)
- panic("Enable to map IRQ registers");
- sc->sc_irq_rman.rm_type = RMAN_ARRAY;
- sc->sc_irq_rman.rm_descr = "AT91 IRQs";
- sc->sc_mem_rman.rm_type = RMAN_ARRAY;
- sc->sc_mem_rman.rm_descr = "AT91 Memory";
- 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");
- if (rman_init(&sc->sc_mem_rman) != 0 ||
- rman_manage_region(&sc->sc_mem_rman, 0xdff00000ul,
- 0xdffffffful) != 0)
- panic("at91_attach: failed to set up memory rman");
- if (rman_manage_region(&sc->sc_mem_rman, AT91SAM9G20_OHCI_BASE,
- AT91SAM9G20_OHCI_BASE + AT91SAM9G20_OHCI_SIZE - 1) != 0)
- panic("at91_attach: failed to set up ohci memory");
-
- if (rman_manage_region(&sc->sc_mem_rman, AT91SAM9G20_NAND_BASE,
- AT91SAM9G20_NAND_BASE + AT91SAM9G20_NAND_SIZE - 1) != 0)
- panic("at91_attach: failed to set up ohci memory");
-
-
-#if 0
- if (rman_manage_region(&sc->sc_mem_rman, AT91SAM9G20_CF_BASE,
- AT91SAM9G20_CF_BASE + AT91SAM9G20_CF_SIZE - 1) != 0)
- panic("at91_attach: failed to set up CompactFlash ATA memory");
-#endif
-
- for (i = 0; i < 32; i++) {
- bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x1000 + IC_SVR +
- i * 4, i);
- /* Priority. */
- bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x1000 + IC_SMR + i * 4,
- irq_prio[i]);
- if (i < 8)
- bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x1000 + IC_EOICR,
- 1);
- }
- bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x1000 + IC_SPU, 32);
- /* No debug. */
- bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x1000 + IC_DCR, 0);
- /* Disable and clear all interrupts. */
- bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x1000 + IC_IDCR, 0xffffffff);
- bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x1000 + IC_ICCR, 0xffffffff);
-
- /* XXX */
- /* 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 DBGU */
- bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x120c, 0xffffffff);
- /* Disable all interrupts for the SDRAM controller */
- //bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xfa8, 0xffffffff);
-
-
- i = bus_space_read_4(sc->sc_st,
- sc->sc_sys_sh, AT91SAM9G20_EBICSA);
-
- /*activate NAND*/
- bus_space_write_4(sc->sc_st, sc->sc_sys_sh, AT91SAM9G20_EBICSA,
- i | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
-
-
- at91_cpu_add_builtin_children(dev, sc);
-
- bus_generic_probe(dev);
- bus_generic_attach(dev);
- enable_interrupts(I32_bit | F32_bit);
- return (0);
-}
-
-static struct resource *
-at91_alloc_resource(device_t dev, device_t child, int type, int *rid,
- u_long start, u_long end, u_long 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;
-
- 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 (start == 0UL && end == ~0UL) {
- 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) {
- rman_set_bustag(rle->res, &at91_bs_tag);
- rman_set_bushandle(rle->res, start);
- }
- 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)
-{
- struct at91_softc *sc = device_get_softc(dev);
-
- if (rman_get_start(ires) == AT91SAM9G20_IRQ_SYSTEM && filt == NULL)
- panic("All system interrupt ISRs must be FILTER");
- BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, filt,
- intr, arg, cookiep);
- bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x1000 + IC_IECR,
- 1 << rman_get_start(ires));
- 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_sys_sh, 0x1000 + 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
- u_long 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, "%#lx");
- retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx");
- retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld");
- if (device_get_flags(dev))
- retval += printf(" flags %#x", device_get_flags(dev));
-
- retval += bus_print_child_footer(dev, child);
-
- return (retval);
-}
-
-void
-arm_mask_irq(uintptr_t nb)
-{
-
- bus_space_write_4(at91_softc->sc_st,
- at91_softc->sc_sys_sh, 0x1000 + IC_IDCR, 1 << nb);
-
-}
-
-int
-arm_get_next_irq(int last __unused)
-{
- int status;
- int irq;
-
- irq = bus_space_read_4(at91_softc->sc_st,
- at91_softc->sc_sys_sh, 0x1000 + IC_IVR);
- status = bus_space_read_4(at91_softc->sc_st,
- at91_softc->sc_sys_sh, 0x1000 + IC_ISR);
- if (status == 0) {
- bus_space_write_4(at91_softc->sc_st,
- at91_softc->sc_sys_sh, 0x1000 + IC_EOICR, 1);
- return (-1);
- }
- return (irq);
-}
-
-void
-arm_unmask_irq(uintptr_t nb)
-{
-
- bus_space_write_4(at91_softc->sc_st,
- at91_softc->sc_sys_sh, 0x1000 + IC_IECR, 1 << nb);
- bus_space_write_4(at91_softc->sc_st, at91_softc->sc_sys_sh,
- 0x1000 + IC_EOICR, 0);
-
-}
-
-static void
-at91_eoi(void *unused)
-{
- bus_space_write_4(at91_softc->sc_st, at91_softc->sc_sys_sh,
- 0x1000 + IC_EOICR, 0);
-}
-
-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);
diff --git a/sys/arm/at91/at91sam9_machdep.c b/sys/arm/at91/at91sam9_machdep.c
deleted file mode 100644
index c3e5613..0000000
--- a/sys/arm/at91/at91sam9_machdep.c
+++ /dev/null
@@ -1,420 +0,0 @@
-/*-
- * 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 dependant functions for kernel setup
- *
- * This file needs a lot of work.
- *
- * Created : 17/09/94
- */
-
-#include "opt_msgbuf.h"
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#define _ARM32_BUS_DMA_PRIVATE
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/sysproto.h>
-#include <sys/signalvar.h>
-#include <sys/imgact.h>
-#include <sys/kernel.h>
-#include <sys/ktr.h>
-#include <sys/linker.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mutex.h>
-#include <sys/pcpu.h>
-#include <sys/proc.h>
-#include <sys/ptrace.h>
-#include <sys/cons.h>
-#include <sys/bio.h>
-#include <sys/bus.h>
-#include <sys/buf.h>
-#include <sys/exec.h>
-#include <sys/kdb.h>
-#include <sys/msgbuf.h>
-#include <machine/reg.h>
-#include <machine/cpu.h>
-
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <vm/vm_object.h>
-#include <vm/vm_page.h>
-#include <vm/vm_pager.h>
-#include <vm/vm_map.h>
-#include <machine/pmap.h>
-#include <machine/vmparam.h>
-#include <machine/pcb.h>
-#include <machine/undefined.h>
-#include <machine/machdep.h>
-#include <machine/metadata.h>
-#include <machine/armreg.h>
-#include <machine/bus.h>
-#include <sys/reboot.h>
-
-#include <arm/at91/at91board.h>
-#include <arm/at91/at91sam9g20reg.h>
-#include <arm/at91/at91_piovar.h>
-#include <arm/at91/at91_pio_rm9200.h>
-
-#define KERNEL_PT_SYS 0 /* Page table for mapping proc0 zero page */
-#define KERNEL_PT_KERN 1
-#define KERNEL_PT_KERN_NUM 22
-#define KERNEL_PT_AFKERNEL KERNEL_PT_KERN + KERNEL_PT_KERN_NUM /* L2 table for mapping after kernel */
-#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)
-
-/* Define various stack sizes in pages */
-#define IRQ_STACK_SIZE 1
-#define ABT_STACK_SIZE 1
-#define UND_STACK_SIZE 1
-
-extern u_int data_abort_handler_address;
-extern u_int prefetch_abort_handler_address;
-extern u_int undefined_handler_address;
-
-struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
-
-extern void *_end;
-
-extern int *end;
-
-struct pcpu __pcpu;
-struct pcpu *pcpup = &__pcpu;
-
-/* Physical and virtual addresses for some global pages */
-
-vm_paddr_t phys_avail[10];
-vm_paddr_t dump_avail[4];
-vm_offset_t physical_pages;
-
-struct pv_addr systempage;
-struct pv_addr msgbufpv;
-struct pv_addr irqstack;
-struct pv_addr undstack;
-struct pv_addr abtstack;
-struct pv_addr kernelstack;
-
-static void *boot_arg1;
-static void *boot_arg2;
-
-static struct trapframe proc0_tf;
-
-/* Static device mappings. */
-static const struct pmap_devmap at91sam9_devmap[] = {
- /*
- * Map the on-board devices VA == PA so that we can access them
- * with the MMU on or off.
- */
- {
- /*
- * This at least maps the interrupt controller, the UART
- * and the timer. Other devices should use newbus to
- * map their memory anyway.
- */
- 0xdff00000,
- 0xfff00000,
- 0x100000,
- VM_PROT_READ|VM_PROT_WRITE,
- PTE_NOCACHE,
- },
- /*
- * We can't just map the OHCI registers VA == PA, because
- * AT91RM92_OHCI_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.
- */
- {
- /*
- * Add the ohci controller, and anything else that might be
- * on this chip select for a VA/PA mapping.
- */
- AT91SAM9G20_OHCI_BASE,
- AT91SAM9G20_OHCI_PA_BASE,
- AT91SAM9G20_OHCI_SIZE,
- VM_PROT_READ|VM_PROT_WRITE,
- PTE_NOCACHE,
- },
- {
- AT91SAM9G20_NAND_BASE,
- AT91SAM9G20_NAND_PA_BASE,
- AT91SAM9G20_NAND_SIZE,
- VM_PROT_READ|VM_PROT_WRITE,
- PTE_NOCACHE,
- },
- {
- 0,
- 0,
- 0,
- 0,
- 0,
- }
-};
-
-long
-at91_ramsize(void)
-{
-#if 0
- uint32_t *SDRAMC = (uint32_t *)(AT91SAM9G20_BASE + AT91SAM9G20_SDRAMC_BASE);
- uint32_t cr, mr;
- int banks, rows, cols, bw;
-
- cr = SDRAMC[AT91SAM9G20_SDRAMC_CR / 4];
- mr = SDRAMC[AT91SAM9G20_SDRAMC_MR / 4];
- bw = (mr & AT91SAM9G20_SDRAMC_MR_DBW_16) ? 1 : 2;
- 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;
- return (1 << (cols + rows + banks + bw));
-#endif
- return 64*1024*1024;
-}
-
-void *
-initarm(void *arg, void *arg2)
-{
- struct pv_addr kernel_l1pt;
- struct pv_addr dpcpu;
- int loop, i;
- u_int l1pagetable;
- vm_offset_t freemempos;
- vm_offset_t afterkern;
- uint32_t memsize;
- vm_offset_t lastaddr;
-
- boot_arg1 = arg;
- boot_arg2 = arg2;
-
-
- set_cpufuncs();
- lastaddr = fake_preload_metadata();
- pcpu_init(pcpup, 0, sizeof(struct pcpu));
- PCPU_SET(curthread, &thread0);
-
- freemempos = (lastaddr + PAGE_MASK) & ~PAGE_MASK;
- /* Define a macro to simplify memory allocation */
-#define valloc_pages(var, np) \
- alloc_pages((var).pv_va, (np)); \
- (var).pv_pa = (var).pv_va + (KERNPHYSADDR - KERNVIRTADDR);
-
-#define alloc_pages(var, np) \
- (var) = freemempos; \
- freemempos += (np * PAGE_SIZE); \
- memset((char *)(var), 0, ((np) * PAGE_SIZE));
-
- while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0)
- freemempos += PAGE_SIZE;
- valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
- for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
- if (!(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) {
- valloc_pages(kernel_pt_table[loop],
- L2_TABLE_SIZE / PAGE_SIZE);
- } else {
- kernel_pt_table[loop].pv_va = freemempos -
- (loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) *
- L2_TABLE_SIZE_REAL;
- kernel_pt_table[loop].pv_pa =
- kernel_pt_table[loop].pv_va - KERNVIRTADDR +
- KERNPHYSADDR;
- }
- i++;
- }
- /*
- * Allocate a page for the system page mapped to V0x00000000
- * 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);
- valloc_pages(abtstack, ABT_STACK_SIZE);
- valloc_pages(undstack, UND_STACK_SIZE);
- valloc_pages(kernelstack, KSTACK_PAGES);
- valloc_pages(msgbufpv, round_page(MSGBUF_SIZE) / 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,
- (((uint32_t)lastaddr - KERNBASE) + PAGE_SIZE) & ~(PAGE_SIZE - 1),
- VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
- afterkern = round_page((lastaddr + L1_S_SIZE) & ~(L1_S_SIZE - 1));
- 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,
- MSGBUF_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
-
- for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
- pmap_map_chunk(l1pagetable, kernel_pt_table[loop].pv_va,
- kernel_pt_table[loop].pv_pa, L2_TABLE_SIZE,
- VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
- }
-
- pmap_devmap_bootstrap(l1pagetable, at91sam9_devmap);
- cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
- setttb(kernel_l1pt.pv_pa);
- cpu_tlb_flushID();
- cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
- cninit();
- memsize = board_init();
- physmem = memsize / PAGE_SIZE;
-
- /*
- * Pages were allocated during the secondary bootstrap for the
- * stacks for different CPU modes.
- * We must now set the r13 registers in the different CPU modes to
- * point to these stacks.
- * Since the ARM stacks use STMFD etc. we must set r13 to the top end
- * of the stack memory.
- */
- cpu_control(CPU_CONTROL_MMU_ENABLE, CPU_CONTROL_MMU_ENABLE);
- set_stackptr(PSR_IRQ32_MODE,
- irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE);
- set_stackptr(PSR_ABT32_MODE,
- abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE);
- set_stackptr(PSR_UND32_MODE,
- undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE);
-
- /*
- * We must now clean the cache again....
- * Cleaning may be done by reading new data to displace any
- * dirty data in the cache. This will have happened in setttb()
- * but since we are boot strapping the addresses used for the read
- * may have just been remapped and thus the cache could be out
- * of sync. A re-clean after the switch will cure this.
- * After booting there are no gross relocations of the kernel thus
- * this problem will not occur after initarm().
- */
- cpu_idcache_wbinv_all();
-
- /* Set stack for exception handlers */
-
- data_abort_handler_address = (u_int)data_abort_handler;
- prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
- undefined_handler_address = (u_int)undefinedinstruction_bounce;
- undefined_init();
-
- proc_linkup0(&proc0, &thread0);
- thread0.td_kstack = kernelstack.pv_va;
- thread0.td_pcb = (struct pcb *)
- (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
- thread0.td_pcb->pcb_flags = 0;
- thread0.td_frame = &proc0_tf;
- pcpup->pc_curpcb = thread0.td_pcb;
-
- arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
-
- pmap_curmaxkvaddr = afterkern + L1_S_SIZE * (KERNEL_PT_KERN_NUM - 1);
-
- /*
- * ARM_USE_SMALL_ALLOC uses dump_avail, so it must be filled before
- * calling pmap_bootstrap.
- */
- dump_avail[0] = PHYSADDR;
- dump_avail[1] = PHYSADDR + memsize;
- dump_avail[2] = 0;
- dump_avail[3] = 0;
-
- pmap_bootstrap(freemempos,
- KERNVIRTADDR + 3 * memsize,
- &kernel_l1pt);
- msgbufp = (void*)msgbufpv.pv_va;
- msgbufinit(msgbufp, MSGBUF_SIZE);
- mutex_init();
-
- i = 0;
-#if PHYSADDR != KERNPHYSADDR
- phys_avail[i++] = PHYSADDR;
- phys_avail[i++] = KERNPHYSADDR;
-#endif
- phys_avail[i++] = virtual_avail - KERNVIRTADDR + KERNPHYSADDR;
- phys_avail[i++] = PHYSADDR + memsize;
- phys_avail[i++] = 0;
- phys_avail[i++] = 0;
- /* Do basic tuning, hz etc */
- init_param1();
- init_param2(physmem);
- kdb_init();
- return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
- sizeof(struct pcb)));
-}
diff --git a/sys/arm/at91/at91sam9g20.c b/sys/arm/at91/at91sam9g20.c
new file mode 100644
index 0000000..4acedae
--- /dev/null
+++ b/sys/arm/at91/at91sam9g20.c
@@ -0,0 +1,317 @@
+/*-
+ * 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/at91_aicreg.h>
+#include <arm/at91/at91sam9g20reg.h>
+#include <arm/at91/at91_pmcreg.h>
+#include <arm/at91/at91_pmcvar.h>
+
+struct at91sam9_softc {
+ device_t dev;
+ bus_space_tag_t sc_st;
+ bus_space_handle_t sc_sh;
+ bus_space_handle_t sc_sys_sh;
+ bus_space_handle_t sc_aic_sh;
+ bus_space_handle_t sc_dbg_sh;
+ bus_space_handle_t sc_matrix_sh;
+};
+
+/*
+ * 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 */
+};
+
+#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_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_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 != AT91SAM9G20_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);
+ if (addr != 0 && addr < AT91SAM9G20_BASE)
+ addr += AT91SAM9G20_BASE;
+ if (addr != 0)
+ bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
+}
+
+static void
+at91_cpu_add_builtin_children(device_t dev)
+{
+ int i;
+ const struct cpu_devs *walker;
+
+ for (i = 1, walker = at91_devs; 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 void
+at91_identify(driver_t *drv, device_t parent)
+{
+
+ if (at91_cpu_is(AT91_CPU_SAM9G20)) {
+ at91_add_child(parent, 0, "at91sam", 9, 0, 0, -1, 0, 0);
+ at91_cpu_add_builtin_children(parent);
+ }
+}
+
+static int
+at91_probe(device_t dev)
+{
+
+ if (at91_cpu_is(AT91_CPU_SAM9G20)) {
+ device_set_desc(dev, "AT91SAM9G20");
+ return (0);
+ }
+ return (ENXIO);
+}
+
+static int
+at91_attach(device_t dev)
+{
+ struct at91_pmc_clock *clk;
+ struct at91sam9_softc *sc = device_get_softc(dev);
+ int i;
+
+ struct at91_softc *at91sc = device_get_softc(device_get_parent(dev));
+
+ sc->sc_st = at91sc->sc_st;
+ sc->sc_sh = at91sc->sc_sh;
+ sc->dev = dev;
+
+ /*
+ * XXX These values work for the RM9200, SAM926[01], and SAM9G20
+ * will have to fix this when we want to support anything else. XXX
+ */
+ if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9G20_SYS_BASE,
+ AT91SAM9G20_SYS_SIZE, &sc->sc_sys_sh) != 0)
+ panic("Enable to map system registers");
+
+ if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9G20_DBGU_BASE,
+ AT91SAM9G20_DBGU_SIZE, &sc->sc_dbg_sh) != 0)
+ panic("Enable to map DBGU registers");
+
+ if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9G20_AIC_BASE,
+ AT91SAM9G20_AIC_SIZE, &sc->sc_aic_sh) != 0)
+ panic("Enable to map system registers");
+
+ /* XXX Hack to tell atmelarm about the AIC */
+ at91sc->sc_aic_sh = sc->sc_aic_sh;
+ at91sc->sc_irq_system = AT91SAM9G20_IRQ_SYSTEM;
+
+ for (i = 0; i < 32; i++) {
+ bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SVR +
+ i * 4, i);
+ /* Priority. */
+ bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SMR + i * 4,
+ at91_irq_prio[i]);
+ if (i < 8)
+ bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_EOICR,
+ 1);
+ }
+
+ bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SPU, 32);
+ /* No debug. */
+ bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_DCR, 0);
+ /* Disable and clear all interrupts. */
+ bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_IDCR, 0xffffffff);
+ bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_ICCR, 0xffffffff);
+
+ /* Disable all interrupts for DBGU */
+ bus_space_write_4(sc->sc_st, sc->sc_dbg_sh, 0x0c, 0xffffffff);
+
+ if (bus_space_subregion(sc->sc_st, sc->sc_sh,
+ AT91SAM9G20_MATRIX_BASE, AT91SAM9G20_MATRIX_SIZE,
+ &sc->sc_matrix_sh) != 0)
+ panic("Enable to map matrix registers");
+
+ /* activate NAND*/
+ i = bus_space_read_4(sc->sc_st, sc->sc_matrix_sh,
+ AT91SAM9G20_EBICSA);
+ bus_space_write_4(sc->sc_st, sc->sc_matrix_sh,
+ AT91SAM9G20_EBICSA,
+ i | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
+
+
+ /* 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;
+ 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;
+ at91_pmc_clock_deref(clk);
+ return (0);
+}
+
+static device_method_t at91_methods[] = {
+ DEVMETHOD(device_probe, at91_probe),
+ DEVMETHOD(device_attach, at91_attach),
+ DEVMETHOD(device_identify, at91_identify),
+ {0, 0},
+};
+
+static driver_t at91sam9_driver = {
+ "at91sam",
+ at91_methods,
+ sizeof(struct at91sam9_softc),
+};
+
+static devclass_t at91sam9_devclass;
+
+DRIVER_MODULE(at91sam, atmelarm, at91sam9_driver, at91sam9_devclass, 0, 0);
diff --git a/sys/arm/at91/at91sam9g20reg.h b/sys/arm/at91/at91sam9g20reg.h
index 9194b11..71683e9 100644
--- a/sys/arm/at91/at91sam9g20reg.h
+++ b/sys/arm/at91/at91sam9g20reg.h
@@ -1,5 +1,6 @@
/*-
* 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
@@ -28,6 +29,29 @@
#ifndef AT91SAM9G20REG_H_
#define AT91SAM9G20REG_H_
+#ifndef AT91SAM9G20_MASTER_CLOCK
+#define AT91SAM9G20_MASTER_CLOCK ((18432000 * 43)/6)
+#endif
+
+/* 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
@@ -56,11 +80,11 @@
#define AT91SAM9G20_BASE 0xd0000000
-#define AT91SAM9G20_IRQ_EMAC 21
#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)
@@ -69,13 +93,25 @@
/* 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_USART_SIZE 0x4000
+#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
@@ -99,28 +135,27 @@
#define AT91SAM9G20_IRQ_SPI1 13
/* System Registers */
-#define AT91SAM9G20_SYS_BASE 0xfffe000
-#define AT91SAM9G20_SYS_SIZE 0x2000
-
-#define AT91SAM9G20_MATRIX (0xe00)
+#define AT91SAM9G20_SYS_BASE 0xffff000
+#define AT91SAM9G20_SYS_SIZE 0x1000
-#define AT91SAM9G20_EBICSA (AT91SAM9G20_MATRIX + 0x011C)
+#define AT91SAM9G20_MATRIX_BASE 0xfffee00
+#define AT91SAM9G20_MATRIX_SIZE 0x1000
+#define AT91SAM9G20_EBICSA 0x011C
#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3)
-#define DBGU 0x200
-#define DBGU_SIZE 0x200
-#define DBGU_C1R (0x200 + 64) /* Chip ID1 Register */
-#define DBGU_C2R (0x200 + 68) /* Chip ID2 Register */
-#define DBGU_FNTR (0x200 + 72) /* Force NTRST Register */
+#define AT91SAM9G20_DBGU_BASE 0xffff200
+#define AT91SAM9G20_DBGU_SIZE 0x200
/*
* PIO
*/
#define AT91SAM9G20_PIOA_BASE 0xffff400
-#define AT91SAM9G20_PIO_SIZE 0x200
+#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
@@ -131,27 +166,33 @@
* 2: PIO Controller A
* 3: PIO Controller B
* 4: PIO Controller C
- * 5: -
+ * 5: ADC
* 6: USART 0
* 7: USART 1
* 8: USART 2
* 9: MMC Interface
* 10: USB device port
* 11: Two-wirte interface
- * 12: SPI
- * 13: SPI
+ * 12: SPI 0
+ * 13: SPI 1
* 14: SSC
- * 15: SSC
- * 16: SSC
+ * 15: - (reserved)
+ * 16: - (reserved)
* 17: Timer Counter 0
* 18: Timer Counter 1
* 19: Timer Counter 2
* 20: USB Host port
* 21: EMAC
- * 22-28: -
- * 29: AIC
- * 30: AIC
- * 31: AIC
+ * 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
@@ -173,12 +214,25 @@
#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
-/* Timer */
+/* 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_DBGU_BASE 0xffff200
-#define AT91SAM9G20_DBGU_SIZE 0x200
+#define AT91SAM9G20_AIC_BASE 0xffff000
+#define AT91SAM9G20_AIC_SIZE 0x200
+
+/* Timer */
#define AT91SAM9G20_WDT_BASE 0xffffd40
#define AT91SAM9G20_WDT_SIZE 0x10
@@ -195,22 +249,24 @@
#define AT91SAM9G20_UDP_BASE 0xffa4000
#define AT91SAM9G20_UDP_SIZE 0x4000
-#define AT91SAM9G20_OHCI_BASE 0xdfe00000
-#define AT91SAM9G20_OHCI_PA_BASE 0x00500000
-#define AT91SAM9G20_OHCI_SIZE 0x00100000
+#define AT91SAM9G20_MCI_BASE 0xffa8000
+#define AT91SAM9G20_MCI_SIZE 0x4000
+#define AT91SAM9G20_TWI_BASE 0xffaC000
+#define AT91SAM9G20_TWI_SIZE 0x4000
-//#define AT91SAM9G20_NAND_BASE 0xdf100000
-
-//#define AT91SAM9G20_NAND_BASE 0x40000000
-
-#define AT91SAM9G20_NAND_BASE 0xe0000000
+/* XXX Needs to be carfully coordinated with
+ * other * soc's so phyical and vm address
+ * mapping are unique. XXX
+ */
+#define AT91SAM9G20_OHCI_BASE 0xdfc00000
+#define AT91SAM9G20_OHCI_PA_BASE 0x00500000
+#define AT91SAM9G20_OHCI_SIZE 0x00100000
-#define AT91SAM9G20_NAND_PA_BASE 0x40000000
-#define AT91SAM9G20_NAND_SIZE 0x10000000
-//#define AT91SAM9G20_NAND_SIZE 0x00900000
+#define AT91SAM9G20_NAND_BASE 0xe0000000
+#define AT91SAM9G20_NAND_PA_BASE 0x40000000
+#define AT91SAM9G20_NAND_SIZE 0x10000000
-//#define AT91SAM9G20_OHCI_SIZE 0x0004000
/* SDRAMC */
#define AT91SAM9G20_SDRAMC_BASE 0xfffea00
@@ -234,6 +290,7 @@
#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
diff --git a/sys/arm/at91/at91var.h b/sys/arm/at91/at91var.h
index 3f82dd7..94e759a 100644
--- a/sys/arm/at91/at91var.h
+++ b/sys/arm/at91/at91var.h
@@ -28,21 +28,62 @@
#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_sys_sh;
+ bus_space_handle_t sc_aic_sh;
struct rman sc_irq_rman;
struct rman sc_mem_rman;
+ uint32_t sc_irq_system;
};
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;
+};
+
+extern uint32_t at91_chip_id;
+
+static inline int at91_is_rm92(void);
+static inline int at91_is_sam9(void) ;
+static inline int at91_cpu_is(u_int cpu);
+
+static inline int
+at91_is_rm92(void)
+{
+ return (AT91_ARCH(at91_chip_id) == AT91_ARCH_RM92);
+}
+
+static inline int
+at91_is_sam9(void)
+{
+ return (AT91_ARCH(at91_chip_id) == AT91_ARCH_SAM9);
+}
+
+static inline int
+at91_cpu_is(u_int cpu)
+{
+ return (AT91_CPU(at91_chip_id) == cpu);
+}
+
+extern uint32_t at91_irq_system;
extern uint32_t at91_master_clock;
#endif /* _AT91VAR_H_ */
diff --git a/sys/arm/at91/board_hl201.c b/sys/arm/at91/board_hl201.c
index b4a0b59..f4497ec 100644
--- a/sys/arm/at91/board_hl201.c
+++ b/sys/arm/at91/board_hl201.c
@@ -32,11 +32,36 @@ __FBSDID("$FreeBSD$");
#include <arm/at91/at91board.h>
#include <arm/at91/at91sam9g20reg.h>
#include <arm/at91/at91_piovar.h>
-#include <arm/at91/at91_pio_sam9.h>
+#include <arm/at91/at91_pio_sam9g20.h>
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 */
return (at91_ramsize());
}
diff --git a/sys/arm/at91/board_kb920x.c b/sys/arm/at91/board_kb920x.c
index f1a2439..e79879d 100644
--- a/sys/arm/at91/board_kb920x.c
+++ b/sys/arm/at91/board_kb920x.c
@@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <arm/at91/at91var.h>
#include <arm/at91/at91board.h>
#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91_piovar.h>
@@ -59,5 +60,13 @@ board_init(void)
at91_pio_use_periph_a(AT91RM92_PIOB_BASE, AT91C_PB21_RXD1, 0);
at91_pio_use_periph_a(AT91RM92_PIOB_BASE, AT91C_PB20_TXD1, 1);
+ /* MMC/SD Interface */
+ at91_pio_use_periph_a(AT91RM92_PIOA_BASE,AT91C_PA27_MCCK, 0);
+ at91_pio_use_periph_a(AT91RM92_PIOA_BASE,AT91C_PA28_MCCDA, 1);
+ at91_pio_use_periph_a(AT91RM92_PIOA_BASE,AT91C_PA29_MCDA0, 1);
+ at91_pio_use_periph_b(AT91RM92_PIOB_BASE,AT91C_PB3_MCDA1, 1);
+ at91_pio_use_periph_b(AT91RM92_PIOB_BASE,AT91C_PB4_MCDA2, 1);
+ at91_pio_use_periph_b(AT91RM92_PIOB_BASE,AT91C_PB5_MCDA3, 1);
+
return (at91_ramsize());
}
diff --git a/sys/arm/at91/board_sam9g20ek.c b/sys/arm/at91/board_sam9g20ek.c
new file mode 100644
index 0000000..7971e5a
--- /dev/null
+++ b/sys/arm/at91/board_sam9g20ek.c
@@ -0,0 +1,176 @@
+/*-
+ * 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.
+ */
+
+/* Atmel AT91SAM9G20EK Rev. B Development Card */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/param.h>
+#include <sys/systm.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
+
+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);
+
+#if 1
+ /* 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);
+#endif
+#if 1
+ /*
+ * Turn off Clock to DataFlash, conflicts with MCI clock.
+ * Remove resistor R42 if you need both DataFlash and SD Card
+ * access at the same time
+ */
+ 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
+
+#if 0
+ static int at91_base = AT91SAM9G20_BASE;
+ volatile uint32_t *PIO = (uint32_t *)(at91_base + AT91SAM9G20_PIOA_BASE);
+ volatile uint32_t *RST = (uint32_t *)(at91_base + AT91SAM9G20_RSTC_BASE);
+ /*
+ * Disable pull-up on:
+ * ERX0 (PA14) => PHY ADDR0
+ * ERX1 (PA15) => PHY ADDR1
+ * RXDV (PA17) => PHY normal mode (not Test mode)
+ * ERX2 (PA25) => PHY ADDR2
+ * ERX3 (PA26) => PHY ADDR3
+ * ECRS (PA28) => PHY ADDR4 => PHYADDR = 0x0
+ *
+ * PHY has internal pull-down
+ */
+ PIO[PIO_PUDR/4] =
+ AT91C_PA14_ERX0 |
+ AT91C_PA15_ERX1 |
+ AT91C_PA17_ERXDV |
+ AT91C_PA25_ERX2 |
+ AT91C_PA26_ERX3 |
+ AT91C_PA28_ECRS;
+
+
+ /* Reset PHY - 500ms */
+ RST[2] = 0xA5000D01;
+ RST[0] = 0xA5000080;
+ while (!(RST[1] & (1 << 16))) ;
+
+ PIO[PIO_PUER/4] =
+ AT91C_PA14_ERX0 |
+ AT91C_PA15_ERX1 |
+ AT91C_PA17_ERXDV |
+ AT91C_PA25_ERX2 |
+ AT91C_PA26_ERX3 |
+ AT91C_PA28_ECRS;
+#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);
+
+#if 0
+ /* Handle Missing ETXER line */
+ at91_pio_use_gpio(AT91SAM9G20_PIOA_BASE,AT91C_PA22_ETXER);
+ at91_pio_gpio_output(AT91SAM9G20_PIOA_BASE,AT91C_PA22_ETXER, 0);
+ at91_pio_gpio_clear(AT91SAM9G20_PIOA_BASE,AT91C_PA22_ETXER);
+#endif
+ return (at91_ramsize());
+}
diff --git a/sys/arm/at91/files.at91 b/sys/arm/at91/files.at91
index 8b5d7e2..4aa0b0c 100644
--- a/sys/arm/at91/files.at91
+++ b/sys/arm/at91/files.at91
@@ -4,14 +4,15 @@ arm/arm/irq_dispatch.S standard
arm/at91/at91_machdep.c standard
arm/at91/at91.c standard
arm/at91/at91_cfata.c optional at91_cfata
-arm/at91/at91_st.c standard
arm/at91/at91_mci.c optional at91_mci
+arm/at91/at91_nand.c optional nand
arm/at91/at91_pio.c standard
arm/at91/at91_pmc.c standard
arm/at91/at91_rtc.c optional at91_rtc
-arm/at91/at91_ssc.c optional at91_ssc
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 standard
arm/at91/at91_tc.c optional at91_tc
arm/at91/at91_twi.c optional at91_twi
arm/at91/if_ate.c optional ate
@@ -19,6 +20,10 @@ arm/at91/uart_bus_at91usart.c optional uart
arm/at91/uart_cpu_at91rm9200usart.c optional uart
arm/at91/uart_dev_at91usart.c optional uart
#
+# All the "systems on a chip" we support
+#
+arm/at91/at91rm9200.c standard
+#
# All the boards we support
#
arm/at91/board_bwct.c optional at91_board_bwct
diff --git a/sys/arm/at91/files.at91sam9 b/sys/arm/at91/files.at91sam9
index fb61cb6..62d189d 100644
--- a/sys/arm/at91/files.at91sam9
+++ b/sys/arm/at91/files.at91sam9
@@ -1,27 +1,34 @@
# $FreeBSD$
arm/arm/cpufunc_asm_arm9.S standard
arm/arm/irq_dispatch.S standard
-arm/at91/at91sam9_machdep.c standard
-arm/at91/at91sam9.c standard
-arm/at91/at91_cfata.c optional at91_cfata
-#arm/at91/at91_pit.c standard
+arm/at91/at91_machdep.c standard
+arm/at91/at91.c standard
arm/at91/at91_mci.c optional at91_mci
arm/at91/at91_nand.c optional nand
arm/at91/at91_pio.c standard
arm/at91/at91_pmc.c standard
arm/at91/at91_pit.c standard
-arm/at91/at91_rtc.c optional at91_rtc
-arm/at91/at91_ssc.c optional at91_ssc
+arm/at91/at91_reset.S optional at91sam9g20
+arm/at91/at91_rst.c standard
arm/at91/at91_spi.c optional at91_spi \
dependency "spibus_if.h"
+arm/at91/at91_ssc.c optional at91_ssc
arm/at91/at91_tc.c optional at91_tc
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
arm/at91/uart_cpu_at91rm9200usart.c optional uart
arm/at91/uart_dev_at91usart.c optional uart
+dev/usb/controller/ohci_atmelarm.c optional ohci
+#
+# All the "systems on a chip" we support
+#
+arm/at91/at91sam9g20.c optional at91sam9g20
+#
#
# All the boards we support
#
arm/at91/board_hl201.c optional at91_board_hl201
-dev/usb/controller/ohci_atmelarm.c optional ohci
+arm/at91/board_sam9g20ek.c optional at91_board_sam9g20ek
diff --git a/sys/arm/at91/if_ate.c b/sys/arm/at91/if_ate.c
index 3c2a074..a469452 100644
--- a/sys/arm/at91/if_ate.c
+++ b/sys/arm/at91/if_ate.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2006 M. Warner Losh. All rights reserved.
+ * 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
@@ -36,13 +37,14 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
-#include <sys/mbuf.h>
#include <sys/malloc.h>
+#include <sys/mbuf.h>
#include <sys/module.h>
#include <sys/rman.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
+
#include <machine/bus.h>
#include <net/ethernet.h>
@@ -65,44 +67,91 @@ __FBSDID("$FreeBSD$");
#include <dev/mii/mii.h>
#include <dev/mii/miivar.h>
+
+#include "opt_at91.h"
+#include <arm/at91/at91reg.h>
+#include <arm/at91/at91var.h>
#include <arm/at91/if_atereg.h>
#include "miibus_if.h"
-#define ATE_MAX_TX_BUFFERS 2 /* We have ping-pong tx buffers */
-#define ATE_MAX_RX_BUFFERS 64
-
/*
* Driver-specific flags.
*/
-#define ATE_FLAG_MULTICAST 0x01
+#define ATE_FLAG_DETACHING 0x01
+#define ATE_FLAG_MULTICAST 0x02
+
+/*
+ * Old EMAC assumes whole packet fits in one buffer;
+ * new EBACB assumes all receive buffers are 128 bytes
+ */
+#define RX_BUF_SIZE(sc) (sc->is_emacb ? 128 : MCLBYTES)
+
+/*
+ * EMACB has an 11 bit counter for Rx/Tx Descriptors
+ * for max total of 1024 decriptors each.
+ */
+#define ATE_MAX_RX_DESCR 1024
+#define ATE_MAX_TX_DESCR 1024
+
+/* How many buffers to allocate */
+#define ATE_MAX_TX_BUFFERS 4 /* We have ping-pong tx buffers */
+
+/* How much memory to use for rx buffers */
+#define ATE_RX_MEMORY (ATE_MAX_RX_DESCR * 128)
+
+/* Actual number of descriptors we allocate */
+#define ATE_NUM_RX_DESCR ATE_MAX_RX_DESCR
+#define ATE_NUM_TX_DESCR ATE_MAX_TX_BUFFERS
+
+#if ATE_NUM_TX_DESCR > ATE_MAX_TX_DESCR
+#error "Can't have more TX buffers that descriptors"
+#endif
+#if ATE_NUM_RX_DESCR > ATE_MAX_RX_DESCR
+#error "Can't have more RX buffers that descriptors"
+#endif
+
+/* Wrap indexes the same way the hardware does */
+#define NEXT_RX_IDX(sc, cur) \
+ ((sc->rx_descs[cur].addr & ETH_WRAP_BIT) ? 0 : (cur + 1))
+
+#define NEXT_TX_IDX(sc, cur) \
+ ((sc->tx_descs[cur].status & ETHB_TX_WRAP) ? 0 : (cur + 1))
struct ate_softc
{
- struct ifnet *ifp; /* ifnet pointer */
- struct mtx sc_mtx; /* Basically a perimeter lock */
- device_t dev; /* Myself */
- device_t miibus; /* My child miibus */
- struct resource *irq_res; /* IRQ resource */
- struct resource *mem_res; /* Memory resource */
- struct callout tick_ch; /* Tick callout */
+ struct ifnet *ifp; /* ifnet pointer */
+ struct mtx sc_mtx; /* Basically a perimeter lock */
+ device_t dev; /* Myself */
+ device_t miibus; /* My child miibus */
+ struct resource *irq_res; /* IRQ resource */
+ struct resource *mem_res; /* Memory resource */
+ struct callout tick_ch; /* Tick callout */
struct ifmib_iso_8802_3 mibdata; /* Stuff for network mgmt */
- struct mbuf *sent_mbuf[ATE_MAX_TX_BUFFERS]; /* Sent mbufs */
- bus_dma_tag_t mtag; /* bus dma tag for mbufs */
- bus_dma_tag_t rxtag;
- bus_dma_tag_t rx_desc_tag;
- bus_dmamap_t rx_desc_map;
- bus_dmamap_t rx_map[ATE_MAX_RX_BUFFERS];
- bus_dmamap_t tx_map[ATE_MAX_TX_BUFFERS];
- bus_addr_t rx_desc_phys;
- eth_rx_desc_t *rx_descs;
- void *rx_buf[ATE_MAX_RX_BUFFERS]; /* RX buffer space */
- void *intrhand; /* Interrupt handle */
- int flags;
- int if_flags;
- int rx_buf_ptr;
- int txcur; /* Current TX map pointer */
- int use_rmii;
+ bus_dma_tag_t mtag; /* bus dma tag for mbufs */
+ bus_dma_tag_t rx_tag;
+ bus_dma_tag_t rx_desc_tag;
+ bus_dmamap_t rx_desc_map;
+ bus_dmamap_t rx_map[ATE_MAX_RX_DESCR];
+ bus_addr_t rx_desc_phys; /* PA of rx descriptors */
+ eth_rx_desc_t *rx_descs; /* VA of rx descriptors */
+ void *rx_buf[ATE_NUM_RX_DESCR]; /* RX buffer space */
+ int rxhead; /* Current RX map/desc index */
+ uint32_t rx_buf_size; /* Size of Rx buffers */
+
+ bus_dma_tag_t tx_desc_tag;
+ bus_dmamap_t tx_desc_map;
+ bus_dmamap_t tx_map[ATE_MAX_TX_BUFFERS];
+ bus_addr_t tx_desc_phys; /* PA of tx descriptors */
+ eth_tx_desc_t *tx_descs; /* VA of tx descriptors */
+ int txhead; /* Current TX map/desc index */
+ int txtail; /* Current TX map/desc index */
+ struct mbuf *sent_mbuf[ATE_MAX_TX_BUFFERS]; /* Sent mbufs */
+ void *intrhand; /* Interrupt handle */
+ int flags;
+ int if_flags;
+ int use_rmii;
+ int is_emacb; /* SAM9x hardware version */
};
static inline uint32_t
@@ -167,9 +216,12 @@ static int ate_get_mac(struct ate_softc *sc, u_char *eaddr);
static void ate_set_mac(struct ate_softc *sc, u_char *eaddr);
static void ate_rxfilter(struct ate_softc *sc);
+static int ate_miibus_readreg(device_t dev, int phy, int reg);
+
+static int ate_miibus_writereg(device_t dev, int phy, int reg, int data);
/*
- * The AT91 family of products has the ethernet called EMAC. However,
- * it isn't self identifying. It is anticipated that the parent bus
+ * The AT91 family of products has the ethernet interface called EMAC.
+ * However, it isn't self identifying. It is anticipated that the parent bus
* code will take care to only add ate devices where they really are. As
* such, we do nothing here to identify the device and just set its name.
*/
@@ -195,11 +247,7 @@ ate_attach(device_t dev)
sc = device_get_softc(dev);
sc->dev = dev;
ATE_LOCK_INIT(sc);
- callout_init_mtx(&sc->tick_ch, &sc->sc_mtx, 0);
- /*
- * Allocate resources.
- */
rid = 0;
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
@@ -217,28 +265,41 @@ ate_attach(device_t dev)
goto out;
}
+ /* New or old version, chooses buffer size. */
+ sc->is_emacb = at91_is_sam9();
+ sc->rx_buf_size = RX_BUF_SIZE(sc);
+
err = ate_activate(dev);
if (err)
goto out;
- sc->use_rmii = (RD4(sc, ETH_CFG) & ETH_CFG_RMII) == ETH_CFG_RMII;
+ /* Default to what boot rom did */
+ if (!sc->is_emacb)
+ sc->use_rmii =
+ (RD4(sc, ETH_CFG) & ETH_CFG_RMII) == ETH_CFG_RMII;
+ else
+ sc->use_rmii =
+ (RD4(sc, ETHB_UIO) & ETHB_UIO_RMII) == ETHB_UIO_RMII;
+#ifdef AT91_ATE_USE_RMII
+ /* Compile time override */
+ sc->use_rmii = 1;
+#endif
/* Sysctls */
sctx = device_get_sysctl_ctx(dev);
soid = device_get_sysctl_tree(dev);
SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "rmii",
- CTLFLAG_RD, &sc->use_rmii, 0, "rmii in use");
+ CTLFLAG_RW, &sc->use_rmii, 0, "rmii in use");
/* Calling atestop before ifp is set is OK. */
ATE_LOCK(sc);
atestop(sc);
ATE_UNLOCK(sc);
+ callout_init_mtx(&sc->tick_ch, &sc->sc_mtx, 0);
if ((err = ate_get_mac(sc, eaddr)) != 0) {
- /*
- * No MAC address configured. Generate the random one.
- */
- if (bootverbose)
+ /* No MAC address configured. Generate the random one. */
+ if (bootverbose)
device_printf(dev,
"Generating random ethernet address.\n");
rnd = arc4random();
@@ -252,8 +313,8 @@ ate_attach(device_t dev)
eaddr[1] = 's';
eaddr[2] = 'd';
eaddr[3] = (rnd >> 16) & 0xff;
- eaddr[4] = (rnd >> 8) & 0xff;
- eaddr[5] = rnd & 0xff;
+ eaddr[4] = (rnd >> 8) & 0xff;
+ eaddr[5] = (rnd >> 0) & 0xff;
}
sc->ifp = ifp = if_alloc(IFT_ETHER);
@@ -262,6 +323,11 @@ ate_attach(device_t dev)
err = ENXIO;
goto out;
}
+ /*
+ * XXX: Clear the isolate bit, or we won't get up,
+ * at least on the HL201
+ */
+ ate_miibus_writereg(dev, 0, 0, 0x3000);
ifp->if_softc = sc;
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
@@ -272,8 +338,8 @@ ate_attach(device_t dev)
ifp->if_ioctl = ateioctl;
ifp->if_init = ateinit;
ifp->if_baudrate = 10000000;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
+ IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
+ ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
IFQ_SET_READY(&ifp->if_snd);
ifp->if_linkmib = &sc->mibdata;
ifp->if_linkmiblen = sizeof(sc->mibdata);
@@ -282,9 +348,7 @@ ate_attach(device_t dev)
ether_ifattach(ifp, eaddr);
- /*
- * Activate the interrupt.
- */
+ /* Activate the interrupt. */
err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
NULL, ate_intr, sc, &sc->intrhand);
if (err) {
@@ -309,11 +373,12 @@ ate_detach(device_t dev)
KASSERT(sc != NULL, ("[ate: %d]: sc is NULL", __LINE__));
ifp = sc->ifp;
if (device_is_attached(dev)) {
- ether_ifdetach(ifp);
ATE_LOCK(sc);
- atestop(sc);
+ sc->flags |= ATE_FLAG_DETACHING;
+ atestop(sc);
ATE_UNLOCK(sc);
callout_drain(&sc->tick_ch);
+ ether_ifdetach(ifp);
}
if (sc->miibus != NULL) {
device_delete_child(dev, sc->miibus);
@@ -346,48 +411,25 @@ ate_detach(device_t dev)
static void
ate_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
{
- struct ate_softc *sc;
if (error != 0)
return;
- sc = (struct ate_softc *)arg;
- sc->rx_desc_phys = segs[0].ds_addr;
+ *(bus_addr_t *)arg = segs[0].ds_addr;
}
static void
ate_load_rx_buf(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
{
struct ate_softc *sc;
- int i;
if (error != 0)
return;
sc = (struct ate_softc *)arg;
- i = sc->rx_buf_ptr;
- /*
- * For the last buffer, set the wrap bit so the controller
- * restarts from the first descriptor.
- */
bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, BUS_DMASYNC_PREWRITE);
- if (i == ATE_MAX_RX_BUFFERS - 1)
- sc->rx_descs[i].addr = segs[0].ds_addr | ETH_WRAP_BIT;
- else
- sc->rx_descs[i].addr = segs[0].ds_addr;
+ sc->rx_descs[sc->rxhead].addr = segs[0].ds_addr;
+ sc->rx_descs[sc->rxhead].status = 0;
bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, BUS_DMASYNC_POSTWRITE);
- sc->rx_descs[i].status = 0;
- /* Flush the memory in the mbuf */
- bus_dmamap_sync(sc->rxtag, sc->rx_map[i], BUS_DMASYNC_PREREAD);
-}
-
-static uint32_t
-ate_mac_hash(const uint8_t *buf)
-{
- uint32_t index = 0;
- for (int i = 0; i < 48; i++) {
- index ^= ((buf[i >> 3] >> (i & 7)) & 1) << (i % 6);
- }
- return (index);
}
/*
@@ -412,17 +454,15 @@ ate_setmcast(struct ate_softc *sc)
return (1);
}
- /*
- * Compute the multicast hash.
- */
+ /* Compute the multicast hash. */
mcaf[0] = 0;
mcaf[1] = 0;
if_maddr_rlock(ifp);
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
- index = ate_mac_hash(LLADDR((struct sockaddr_dl *)
- ifma->ifma_addr));
+ index = ether_crc32_be(LLADDR((struct sockaddr_dl *)
+ ifma->ifma_addr), ETHER_ADDR_LEN) >> 26;
af[index >> 3] |= 1 << (index & 7);
}
if_maddr_runlock(ifp);
@@ -443,69 +483,124 @@ static int
ate_activate(device_t dev)
{
struct ate_softc *sc;
- int err, i;
+ int i;
sc = device_get_softc(dev);
- /*
- * Allocate DMA tags and maps.
- */
- err = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
+ /* Allocate DMA tags and maps for TX mbufs */
+ if (bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
- 1, MCLBYTES, 0, busdma_lock_mutex, &sc->sc_mtx, &sc->mtag);
- if (err != 0)
+ 1, MCLBYTES, 0, busdma_lock_mutex, &sc->sc_mtx, &sc->mtag))
goto errout;
for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) {
- err = bus_dmamap_create(sc->mtag, 0, &sc->tx_map[i]);
- if (err != 0)
+ if ( bus_dmamap_create(sc->mtag, 0, &sc->tx_map[i]))
goto errout;
}
- /*
- * Allocate DMA tags and maps for RX.
- */
- err = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
- 1, MCLBYTES, 0, busdma_lock_mutex, &sc->sc_mtx, &sc->rxtag);
- if (err != 0)
- goto errout;
- /*
- * DMA tag and map for the RX descriptors.
- */
- err = bus_dma_tag_create(bus_get_dma_tag(dev), sizeof(eth_rx_desc_t),
+ /* DMA tag and map for the RX descriptors. */
+ if (bus_dma_tag_create(bus_get_dma_tag(dev), sizeof(eth_rx_desc_t),
0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- ATE_MAX_RX_BUFFERS * sizeof(eth_rx_desc_t), 1,
- ATE_MAX_RX_BUFFERS * sizeof(eth_rx_desc_t), 0, busdma_lock_mutex,
- &sc->sc_mtx, &sc->rx_desc_tag);
- if (err != 0)
+ ATE_NUM_RX_DESCR * sizeof(eth_rx_desc_t), 1,
+ ATE_NUM_RX_DESCR * sizeof(eth_rx_desc_t), 0, busdma_lock_mutex,
+ &sc->sc_mtx, &sc->rx_desc_tag))
goto errout;
if (bus_dmamem_alloc(sc->rx_desc_tag, (void **)&sc->rx_descs,
BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &sc->rx_desc_map) != 0)
goto errout;
if (bus_dmamap_load(sc->rx_desc_tag, sc->rx_desc_map,
- sc->rx_descs, ATE_MAX_RX_BUFFERS * sizeof(eth_rx_desc_t),
- ate_getaddr, sc, 0) != 0)
+ sc->rx_descs, ATE_NUM_RX_DESCR * sizeof(eth_rx_desc_t),
+ ate_getaddr, &sc->rx_desc_phys, 0) != 0)
+ goto errout;
+
+ /* Allocate DMA tags and maps for RX. buffers */
+ if (bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
+ BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+ sc->rx_buf_size, 1, sc->rx_buf_size, 0,
+ busdma_lock_mutex, &sc->sc_mtx, &sc->rx_tag))
goto errout;
/*
- * Allocate our RX buffers. This chip has a RX structure that's filled
- * in.
+ * Allocate our RX buffers.
+ * This chip has a RX structure that's filled in.
+ * XXX On MACB (SAM9 part) we should receive directly into mbuf
+ * to avoid the copy. XXX
*/
- for (i = 0; i < ATE_MAX_RX_BUFFERS; i++) {
- sc->rx_buf_ptr = i;
- if (bus_dmamem_alloc(sc->rxtag, (void **)&sc->rx_buf[i],
- BUS_DMA_NOWAIT, &sc->rx_map[i]) != 0)
+ sc->rxhead = 0;
+ for (sc->rxhead = 0; sc->rxhead < ATE_RX_MEMORY/sc->rx_buf_size;
+ sc->rxhead++) {
+ if (bus_dmamem_alloc(sc->rx_tag,
+ (void **)&sc->rx_buf[sc->rxhead], BUS_DMA_NOWAIT,
+ &sc->rx_map[sc->rxhead]) != 0)
goto errout;
- if (bus_dmamap_load(sc->rxtag, sc->rx_map[i], sc->rx_buf[i],
- MCLBYTES, ate_load_rx_buf, sc, 0) != 0)
+
+ if (bus_dmamap_load(sc->rx_tag, sc->rx_map[sc->rxhead],
+ sc->rx_buf[sc->rxhead], sc->rx_buf_size,
+ ate_load_rx_buf, sc, 0) != 0) {
+ printf("bus_dmamem_load\n");
goto errout;
+ }
+ bus_dmamap_sync(sc->rx_tag, sc->rx_map[sc->rxhead], BUS_DMASYNC_PREREAD);
}
- sc->rx_buf_ptr = 0;
+
+ /*
+ * For the last buffer, set the wrap bit so the controller
+ * restarts from the first descriptor.
+ */
+ sc->rx_descs[--sc->rxhead].addr |= ETH_WRAP_BIT;
+ sc->rxhead = 0;
+
/* Flush the memory for the EMAC rx descriptor. */
bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, BUS_DMASYNC_PREWRITE);
+
/* Write the descriptor queue address. */
WR4(sc, ETH_RBQP, sc->rx_desc_phys);
+
+ /*
+ * DMA tag and map for the TX descriptors.
+ * XXX Old EMAC (not EMACB) doesn't really need DMA'able
+ * memory. We could just malloc it. gja XXX
+ */
+ if (bus_dma_tag_create(bus_get_dma_tag(dev), sizeof(eth_tx_desc_t),
+ 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+ ATE_MAX_TX_BUFFERS * sizeof(eth_tx_desc_t), 1,
+ ATE_MAX_TX_BUFFERS * sizeof(eth_tx_desc_t), 0, busdma_lock_mutex,
+ &sc->sc_mtx, &sc->tx_desc_tag) != 0)
+ goto errout;
+
+ if (bus_dmamem_alloc(sc->tx_desc_tag, (void **)&sc->tx_descs,
+ BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &sc->tx_desc_map) != 0)
+ goto errout;
+
+ if (bus_dmamap_load(sc->tx_desc_tag, sc->tx_desc_map,
+ sc->tx_descs, ATE_MAX_TX_BUFFERS * sizeof(eth_tx_desc_t),
+ ate_getaddr, &sc->tx_desc_phys, 0) != 0)
+ goto errout;
+
+ /* Initilize descriptors; mark all empty */
+ for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) {
+ sc->tx_descs[i].addr =0;
+ sc->tx_descs[i].status = ETHB_TX_USED;
+ sc->sent_mbuf[i] = NULL;
+ }
+
+ /* Mark last entry to cause wrap when indexing through */
+ sc->tx_descs[ATE_MAX_TX_BUFFERS - 1].status =
+ ETHB_TX_WRAP | ETHB_TX_USED;
+
+ /* Flush the memory for the EMAC tx descriptor. */
+ bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map, BUS_DMASYNC_PREWRITE);
+
+ sc->txhead = sc->txtail = 0;
+ if (sc->is_emacb) {
+ /* Write the descriptor queue address. */
+ WR4(sc, ETHB_TBQP, sc->tx_desc_phys);
+ }
+
+ /* EMACB: Enable transceiver input clock */
+ if (sc->is_emacb)
+ WR4(sc, ETHB_UIO, RD4(sc, ETHB_UIO) | ETHB_UIO_CLKE);
+
return (0);
errout:
@@ -543,24 +638,22 @@ ate_deactivate(struct ate_softc *sc)
}
}
}
- if (sc->rxtag != NULL) {
- for (i = 0; i < ATE_MAX_RX_BUFFERS; i++) {
- if (sc->rx_buf[i] != NULL) {
- if (sc->rx_descs[i].addr != 0) {
- bus_dmamap_sync(sc->rxtag,
- sc->rx_map[i],
- BUS_DMASYNC_POSTREAD);
- bus_dmamap_unload(sc->rxtag,
- sc->rx_map[i]);
- sc->rx_descs[i].addr = 0;
- }
- bus_dmamem_free(sc->rxtag, sc->rx_buf[i],
+ if (sc->rx_tag != NULL) {
+ for (i = 0; sc->rx_buf[i] != NULL; i++) {
+ if (sc->rx_descs[i].addr != 0) {
+ bus_dmamap_sync(sc->rx_tag,
+ sc->rx_map[i],
+ BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(sc->rx_tag,
sc->rx_map[i]);
- sc->rx_buf[i] = NULL;
- sc->rx_map[i] = NULL;
+ sc->rx_descs[i].addr = 0;
}
+ bus_dmamem_free(sc->rx_tag, sc->rx_buf[i],
+ sc->rx_map[i]);
+ sc->rx_buf[i] = NULL;
+ sc->rx_map[i] = NULL;
}
- bus_dma_tag_destroy(sc->rxtag);
+ bus_dma_tag_destroy(sc->rx_tag);
}
if (sc->rx_desc_tag != NULL) {
if (sc->rx_descs != NULL)
@@ -570,6 +663,9 @@ ate_deactivate(struct ate_softc *sc)
sc->rx_descs = NULL;
sc->rx_desc_tag = NULL;
}
+
+ if (sc->is_emacb)
+ WR4(sc, ETHB_UIO, RD4(sc, ETHB_UIO) & ~ETHB_UIO_CLKE);
}
/*
@@ -686,9 +782,7 @@ ate_tick(void *xsc)
sc->ifp->if_ierrors += RD4(sc, ETH_CDE) + RD4(sc, ETH_RJB) +
RD4(sc, ETH_USF);
- /*
- * Schedule another timeout one second from now.
- */
+ /* Schedule another timeout one second from now. */
callout_reset(&sc->tick_ch, hz, ate_tick, sc);
}
@@ -710,8 +804,8 @@ ate_get_mac(struct ate_softc *sc, u_char *eaddr)
int i;
/*
- * The boot loader setup the MAC with an address, if one is set in
- * the loader. Grab one MAC address from the SA[1-4][HL] registers.
+ * The boot loader may setup the MAC with an address(es), grab the
+ * first MAC address from the SA[1-4][HL] registers.
*/
for (i = 0; i < 4; i++) {
low = RD4(sc, sa_low_reg[i]);
@@ -735,87 +829,162 @@ ate_intr(void *xsc)
struct ate_softc *sc = xsc;
struct ifnet *ifp = sc->ifp;
struct mbuf *mb;
- void *bp;
- uint32_t status, reg, rx_stat;
- int i;
+ eth_rx_desc_t *rxdhead;
+ uint32_t status, reg, idx;
+ int remain, count, done;
status = RD4(sc, ETH_ISR);
if (status == 0)
return;
+
if (status & ETH_ISR_RCOM) {
- bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map,
+
+ bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map,
BUS_DMASYNC_POSTREAD);
- while (sc->rx_descs[sc->rx_buf_ptr].addr & ETH_CPU_OWNER) {
- i = sc->rx_buf_ptr;
- sc->rx_buf_ptr = (i + 1) % ATE_MAX_RX_BUFFERS;
- bp = sc->rx_buf[i];
- rx_stat = sc->rx_descs[i].status;
- if ((rx_stat & ETH_LEN_MASK) == 0) {
- if (bootverbose)
- device_printf(sc->dev, "ignoring bogus zero-length packet\n");
- bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map,
- BUS_DMASYNC_PREWRITE);
- sc->rx_descs[i].addr &= ~ETH_CPU_OWNER;
- bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map,
- BUS_DMASYNC_POSTWRITE);
+
+ rxdhead = &sc->rx_descs[sc->rxhead];
+ while (rxdhead->addr & ETH_CPU_OWNER) {
+ if (!sc->is_emacb) {
+ /*
+ * Simulate SAM9 FIRST/LAST bits for RM9200.
+ * RM9200 EMAC has only on Rx buffer per packet.
+ * But sometime we are handed a zero lenght packet.
+ */
+ if ((rxdhead->status & ETH_LEN_MASK) == 0)
+ rxdhead->status = 0; /* Mark error */
+ else
+ rxdhead->status |= ETH_BUF_FIRST | ETH_BUF_LAST;
+ }
+
+ if ((rxdhead->status & ETH_BUF_FIRST) == 0) {
+ /* Something went wrong during RX so
+ release back to EMAC all buffers of invalid packets.
+ */
+ rxdhead->status = 0;
+ rxdhead->addr &= ~ETH_CPU_OWNER;
+ sc->rxhead = NEXT_RX_IDX(sc, sc->rxhead);
+ rxdhead = &sc->rx_descs[sc->rxhead];
continue;
}
- /* Flush memory for mbuf so we don't get stale bytes */
- bus_dmamap_sync(sc->rxtag, sc->rx_map[i],
- BUS_DMASYNC_POSTREAD);
- WR4(sc, ETH_RSR, RD4(sc, ETH_RSR));
-
- /*
- * The length returned by the device includes the
- * ethernet CRC calculation for the packet, but
- * ifnet drivers are supposed to discard it.
- */
- mb = m_devget(sc->rx_buf[i],
- (rx_stat & ETH_LEN_MASK) - ETHER_CRC_LEN,
- ETHER_ALIGN, ifp, NULL);
- bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map,
- BUS_DMASYNC_PREWRITE);
- sc->rx_descs[i].addr &= ~ETH_CPU_OWNER;
- bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map,
- BUS_DMASYNC_POSTWRITE);
- bus_dmamap_sync(sc->rxtag, sc->rx_map[i],
- BUS_DMASYNC_PREREAD);
+
+ /* Find end of packet or start of next */
+ idx = sc->rxhead;
+ if ((sc->rx_descs[idx].status & ETH_BUF_LAST) == 0) {
+ idx = NEXT_RX_IDX(sc, idx);
+
+ while ((sc->rx_descs[idx].addr & ETH_CPU_OWNER) &&
+ ((sc->rx_descs[idx].status &
+ (ETH_BUF_FIRST|ETH_BUF_LAST))== 0))
+ idx = NEXT_RX_IDX(sc, idx);
+ }
+
+ /* Packet NOT yet completely in memory; we are done */
+ if ((sc->rx_descs[idx].addr & ETH_CPU_OWNER) == 0 ||
+ ((sc->rx_descs[idx].status & (ETH_BUF_FIRST|ETH_BUF_LAST))== 0))
+ break;
+
+ /* Packets with no end descriptor are invalid. */
+ if ((sc->rx_descs[idx].status & ETH_BUF_LAST) == 0) {
+ rxdhead->status &= ~ETH_BUF_FIRST;
+ continue;
+ }
+
+ /* FCS is not coppied into mbuf. */
+ remain = (sc->rx_descs[idx].status & ETH_LEN_MASK) - 4;
+
+ /* Get an appropriately sized mbuf */
+ if (remain + ETHER_ALIGN >= MINCLSIZE)
+ mb = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+ else
+ MGETHDR(mb, M_DONTWAIT, MT_DATA);
+
+ if (mb == NULL) {
+ sc->ifp->if_iqdrops++;
+ rxdhead->status = 0;
+ continue;
+ }
+ mb->m_data += ETHER_ALIGN;
+ mb->m_pkthdr.rcvif = ifp;
+
+ WR4(sc, ETH_RSR, RD4(sc, ETH_RSR)); /* Reset status */
+
+ /* Now we process the buffers that make up the packet */
+ do {
+
+ /* Last buffer may just be 1-4 bytes of FCS so remain
+ * may be zero for last decriptor. */
+ if (remain > 0) {
+ /* Make sure we get the current bytes */
+ bus_dmamap_sync(sc->rx_tag, sc->rx_map[sc->rxhead],
+ BUS_DMASYNC_POSTREAD);
+
+ count = MIN(remain, sc->rx_buf_size);
+
+ /* XXX Performance robbing copy. Could
+ * recieve directly to mbufs if not an
+ * RM9200. XXX */
+ m_append(mb, count, sc->rx_buf[sc->rxhead]);
+ remain -= count;
+ }
+
+ done = (rxdhead->status & ETH_BUF_LAST) != 0;
+
+ /* Return the descriptor to the EMAC */
+ rxdhead->status = 0;
+ rxdhead->addr &= ~ETH_CPU_OWNER;
+ bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map,
+ BUS_DMASYNC_PREWRITE);
+
+ /* Move on to next descriptor with wrap */
+ sc->rxhead = NEXT_RX_IDX(sc, sc->rxhead);
+ rxdhead = &sc->rx_descs[sc->rxhead];
+
+ } while (!done);
+
if (mb != NULL) {
ifp->if_ipackets++;
(*ifp->if_input)(ifp, mb);
}
-
}
}
+
+
if (status & ETH_ISR_TCOM) {
+ bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map,
+ BUS_DMASYNC_POSTREAD);
+
ATE_LOCK(sc);
/* XXX TSR register should be cleared */
- if (sc->sent_mbuf[0]) {
- bus_dmamap_sync(sc->mtag, sc->tx_map[0],
+ if (!sc->is_emacb) {
+ /* Simulate Transmit descriptor table */
+
+ /* First packet done */
+ if (sc->txtail < sc->txhead)
+ sc->tx_descs[sc->txtail].status |= ETHB_TX_USED;
+
+ /* Second Packet done */
+ if (sc->txtail + 1 < sc->txhead &&
+ RD4(sc, ETH_TSR) & ETH_TSR_IDLE)
+ sc->tx_descs[sc->txtail + 1].status |= ETHB_TX_USED;
+ }
+
+ while (sc->txtail != sc->txhead &&
+ sc->tx_descs[sc->txtail].status & ETHB_TX_USED ) {
+
+ bus_dmamap_sync(sc->mtag, sc->tx_map[sc->txtail],
BUS_DMASYNC_POSTWRITE);
- bus_dmamap_unload(sc->mtag, sc->tx_map[0]);
- m_freem(sc->sent_mbuf[0]);
+ bus_dmamap_unload(sc->mtag, sc->tx_map[sc->txtail]);
+ m_freem(sc->sent_mbuf[sc->txtail]);
+ sc->tx_descs[sc->txtail].addr = 0;
+ sc->sent_mbuf[sc->txtail] = NULL;
+
ifp->if_opackets++;
- sc->sent_mbuf[0] = NULL;
- }
- if (sc->sent_mbuf[1]) {
- if (RD4(sc, ETH_TSR) & ETH_TSR_IDLE) {
- bus_dmamap_sync(sc->mtag, sc->tx_map[1],
- BUS_DMASYNC_POSTWRITE);
- bus_dmamap_unload(sc->mtag, sc->tx_map[1]);
- m_freem(sc->sent_mbuf[1]);
- ifp->if_opackets++;
- sc->txcur = 0;
- sc->sent_mbuf[0] = sc->sent_mbuf[1] = NULL;
- } else {
- sc->sent_mbuf[0] = sc->sent_mbuf[1];
- sc->sent_mbuf[1] = NULL;
- sc->txcur = 1;
- }
- } else {
- sc->sent_mbuf[0] = NULL;
- sc->txcur = 0;
+ sc->txtail = NEXT_TX_IDX(sc, sc->txtail);
}
+
+ /* Flush descriptors to EMAC */
+ bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map, BUS_DMASYNC_PREWRITE);
+
/*
* We're no longer busy, so clear the busy flag and call the
* start routine to xmit more packets.
@@ -824,8 +993,9 @@ ate_intr(void *xsc)
atestart_locked(sc->ifp);
ATE_UNLOCK(sc);
}
+
if (status & ETH_ISR_RBNA) {
- /* Workaround Errata #11 */
+ /* Workaround RM9200 Errata #11 */
if (bootverbose)
device_printf(sc->dev, "RBNA workaround\n");
reg = RD4(sc, ETH_CTL);
@@ -843,7 +1013,7 @@ ateinit_locked(void *xsc)
{
struct ate_softc *sc = xsc;
struct ifnet *ifp = sc->ifp;
- struct mii_data *mii;
+ struct mii_data *mii;
uint8_t eaddr[ETHER_ADDR_LEN];
uint32_t reg;
@@ -856,20 +1026,27 @@ ateinit_locked(void *xsc)
* need to think about how best to turn it on/off as the interface
* is brought up/down, as well as dealing with the mii bus...
*
- * We also need to multiplex the pins correctly.
+ * We also need to multiplex the pins correctly (in board_xxx.c).
*/
/*
* There are two different ways that the mii bus is connected
- * to this chip. Select the right one based on a compile-time
- * option.
+ * to this chip mii or rmii.
*/
- reg = RD4(sc, ETH_CFG);
- if (sc->use_rmii)
- reg |= ETH_CFG_RMII;
- else
- reg &= ~ETH_CFG_RMII;
- WR4(sc, ETH_CFG, reg);
+ if (!sc->is_emacb) {
+ /* RM9200 */
+ reg = RD4(sc, ETH_CFG);
+ if (sc->use_rmii)
+ reg |= ETH_CFG_RMII;
+ else
+ reg &= ~ETH_CFG_RMII;
+ WR4(sc, ETH_CFG, reg);
+ } else {
+ /* SAM9 */
+ reg = ETHB_UIO_CLKE;
+ reg |= (sc->use_rmii) ? ETHB_UIO_RMII : 0;
+ WR4(sc, ETHB_UIO, reg);
+ }
ate_rxfilter(sc);
@@ -879,6 +1056,13 @@ ateinit_locked(void *xsc)
bcopy(IF_LLADDR(ifp), eaddr, ETHER_ADDR_LEN);
ate_set_mac(sc, eaddr);
+ /* Make sure we know state of TX queue */
+ sc->txhead = sc->txtail = 0;
+ if (sc->is_emacb) {
+ /* Write the descriptor queue address. */
+ WR4(sc, ETHB_TBQP, sc->tx_desc_phys);
+ }
+
/*
* Turn on MACs and interrupt processing.
*/
@@ -918,23 +1102,26 @@ atestart_locked(struct ifnet *ifp)
if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
return;
- while (sc->txcur < ATE_MAX_TX_BUFFERS) {
+ while (sc->tx_descs[sc->txhead].status & ETHB_TX_USED) {
/*
* Check to see if there's room to put another packet into the
- * xmit queue. The EMAC chip has a ping-pong buffer for xmit
- * packets. We use OACTIVE to indicate "we can stuff more into
- * our buffers (clear) or not (set)."
+ * xmit queue. The old EMAC version has a ping-pong buffer for
+ * xmit packets. We use OACTIVE to indicate "we can stuff more
+ * into our buffers (clear) or not (set)."
*/
- if (!(RD4(sc, ETH_TSR) & ETH_TSR_BNQ)) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- return;
+ if (!sc->is_emacb) {
+ /* RM9200 has only two hardware entries */
+ if (!sc->is_emacb && (RD4(sc, ETH_TSR) & ETH_TSR_BNQ) == 0) {
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ return;
+ }
}
+
IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == 0) {
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- return;
- }
- e = bus_dmamap_load_mbuf_sg(sc->mtag, sc->tx_map[sc->txcur], m,
+ if (m == 0)
+ break;
+
+ e = bus_dmamap_load_mbuf_sg(sc->mtag, sc->tx_map[sc->txhead], m,
segs, &nseg, 0);
if (e == EFBIG) {
mdefrag = m_defrag(m, M_DONTWAIT);
@@ -944,30 +1131,41 @@ atestart_locked(struct ifnet *ifp)
}
m = mdefrag;
e = bus_dmamap_load_mbuf_sg(sc->mtag,
- sc->tx_map[sc->txcur], m, segs, &nseg, 0);
+ sc->tx_map[sc->txhead], m, segs, &nseg, 0);
}
if (e != 0) {
m_freem(m);
continue;
}
- bus_dmamap_sync(sc->mtag, sc->tx_map[sc->txcur],
+ sc->sent_mbuf[sc->txhead] = m;
+
+ bus_dmamap_sync(sc->mtag, sc->tx_map[sc->txhead],
BUS_DMASYNC_PREWRITE);
- /*
- * Tell the hardware to xmit the packet.
- */
- WR4(sc, ETH_TAR, segs[0].ds_addr);
- BARRIER(sc, ETH_TAR, 8, BUS_SPACE_BARRIER_WRITE);
- WR4(sc, ETH_TCR, segs[0].ds_len);
+ /* Tell the hardware to xmit the packet. */
+ if (!sc->is_emacb) {
+ WR4(sc, ETH_TAR, segs[0].ds_addr);
+ BARRIER(sc, ETH_TAR, 4, BUS_SPACE_BARRIER_WRITE);
+ WR4(sc, ETH_TCR, segs[0].ds_len);
+ } else {
+ bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map,
+ BUS_DMASYNC_POSTWRITE);
+ sc->tx_descs[sc->txhead].addr = segs[0].ds_addr;
+ sc->tx_descs[sc->txhead].status = segs[0].ds_len |
+ (sc->tx_descs[sc->txhead].status & ETHB_TX_WRAP) |
+ ETHB_TX_BUF_LAST;
+ bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map,
+ BUS_DMASYNC_PREWRITE);
+ WR4(sc, ETH_CTL, RD4(sc, ETH_CTL) | ETHB_CTL_TGO);
+ }
+ sc->txhead = NEXT_TX_IDX(sc, sc->txhead);
- /*
- * Tap off here if there is a bpf listener.
- */
+ /* Tap off here if there is a bpf listener. */
BPF_MTAP(ifp, m);
-
- sc->sent_mbuf[sc->txcur] = m;
- sc->txcur++;
}
+
+ if ((sc->tx_descs[sc->txhead].status & ETHB_TX_USED) == 0)
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
}
static void
@@ -1003,6 +1201,7 @@ atestop(struct ate_softc *sc)
ATE_ASSERT_LOCKED(sc);
ifp = sc->ifp;
if (ifp) {
+ //ifp->if_timer = 0;
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
}
@@ -1019,7 +1218,18 @@ atestop(struct ate_softc *sc)
/*
* Turn off all the configured options and revert to defaults.
*/
- WR4(sc, ETH_CFG, ETH_CFG_CLK_32);
+
+ /* Make sure thate the MDIO clk is less than
+ * 2.5 Mhz. Can no longer default to /32 since
+ * SAM9 family may have MCK > 80 Mhz */
+ if (at91_master_clock <= 2000000)
+ WR4(sc, ETH_CFG, ETH_CFG_CLK_8);
+ else if (at91_master_clock <= 4000000)
+ WR4(sc, ETH_CFG, ETH_CFG_CLK_16);
+ else if (at91_master_clock <= 800000)
+ WR4(sc, ETH_CFG, ETH_CFG_CLK_32);
+ else
+ WR4(sc, ETH_CFG, ETH_CFG_CLK_64);
/*
* Turn off all the interrupts, and ack any pending ones by reading
@@ -1035,9 +1245,7 @@ atestop(struct ate_softc *sc)
WR4(sc, ETH_TSR, 0xffffffff);
WR4(sc, ETH_RSR, 0xffffffff);
- /*
- * Release TX resources.
- */
+ /* Release TX resources. */
for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) {
if (sc->sent_mbuf[i] != NULL) {
bus_dmamap_sync(sc->mtag, sc->tx_map[i],
@@ -1048,6 +1256,10 @@ atestop(struct ate_softc *sc)
}
}
+ /* Turn off transeiver input clock */
+ if (sc->is_emacb)
+ WR4(sc, ETHB_UIO, RD4(sc, ETHB_UIO) & ~ETHB_UIO_CLKE);
+
/*
* XXX we should power down the EMAC if it isn't in use, after
* putting it into loopback mode. This saves about 400uA according
@@ -1066,17 +1278,13 @@ ate_rxfilter(struct ate_softc *sc)
ATE_ASSERT_LOCKED(sc);
ifp = sc->ifp;
- /*
- * Wipe out old filter settings.
- */
+ /* Wipe out old filter settings. */
reg = RD4(sc, ETH_CFG);
reg &= ~(ETH_CFG_CAF | ETH_CFG_MTI | ETH_CFG_UNI);
reg |= ETH_CFG_NBC;
sc->flags &= ~ATE_FLAG_MULTICAST;
- /*
- * Set new parameters.
- */
+ /* Set new parameters. */
if ((ifp->if_flags & IFF_BROADCAST) != 0)
reg &= ~ETH_CFG_NBC;
if ((ifp->if_flags & IFF_PROMISC) != 0) {
@@ -1095,8 +1303,8 @@ static int
ateioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
struct ate_softc *sc = ifp->if_softc;
- struct mii_data *mii;
- struct ifreq *ifr = (struct ifreq *)data;
+ struct mii_data *mii;
+ struct ifreq *ifr = (struct ifreq *)data;
int drv_flags, flags;
int mask, error, enabled;
@@ -1112,9 +1320,11 @@ ateioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
& (IFF_PROMISC | IFF_ALLMULTI)) != 0)
ate_rxfilter(sc);
} else {
- ateinit_locked(sc);
+ if ((sc->flags & ATE_FLAG_DETACHING) == 0)
+ ateinit_locked(sc);
}
} else if ((drv_flags & IFF_DRV_RUNNING) != 0) {
+ ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
atestop(sc);
}
sc->if_flags = flags;
@@ -1132,11 +1342,11 @@ ateioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
break;
- case SIOCSIFMEDIA:
- case SIOCGIFMEDIA:
- mii = device_get_softc(sc->miibus);
- error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
- break;
+ case SIOCSIFMEDIA:
+ case SIOCGIFMEDIA:
+ mii = device_get_softc(sc->miibus);
+ error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
+ break;
case SIOCSIFCAP:
mask = ifp->if_capenable ^ ifr->ifr_reqcap;
if (mask & IFCAP_VLAN_MTU) {
diff --git a/sys/arm/at91/if_atereg.h b/sys/arm/at91/if_atereg.h
index 10fbfdb..fc7e4de 100644
--- a/sys/arm/at91/if_atereg.h
+++ b/sys/arm/at91/if_atereg.h
@@ -28,6 +28,8 @@
#ifndef ARM_AT91_IF_ATEREG_H
#define ARM_AT91_IF_ATEREG_H
+/* deines begining 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 */
@@ -35,7 +37,7 @@
#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 */
- /* 0x1c reserved */
+#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 */
@@ -74,6 +76,8 @@
#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 */
@@ -87,6 +91,9 @@
#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 */
@@ -105,6 +112,17 @@
#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 */
@@ -142,6 +160,10 @@
#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)
@@ -160,8 +182,11 @@ 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 */
@@ -173,4 +198,17 @@ typedef struct {
#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 */
diff --git a/sys/arm/at91/if_macb.c b/sys/arm/at91/if_macb.c
index 7504c07..dfe7182 100644
--- a/sys/arm/at91/if_macb.c
+++ b/sys/arm/at91/if_macb.c
@@ -1336,34 +1336,8 @@ macb_attach(device_t dev)
goto out;
}
- 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 clock*/
- sc->clk = at91_pmc_clock_ref("macb_clk");
+ sc->clk = at91_pmc_clock_ref(device_get_nameunit(sc->dev));
at91_pmc_clock_enable(sc->clk);
macb_reset(sc);
diff --git a/sys/arm/at91/std.at91sam9 b/sys/arm/at91/std.at91sam9
index 96aeb2b..1a63144 100644
--- a/sys/arm/at91/std.at91sam9
+++ b/sys/arm/at91/std.at91sam9
@@ -2,5 +2,7 @@
files "../at91/files.at91sam9"
cpu CPU_ARM9
-makeoptions CONF_CFLAGS="-mcpu=arm9 -DAT91SAM9G20"
+makeoptions CONF_CFLAGS="-mcpu=arm9"
options PHYSADDR=0x20000000
+
+device at91sam9g20
diff --git a/sys/arm/at91/std.kb920x b/sys/arm/at91/std.kb920x
index 85c8d03..26d0443 100644
--- a/sys/arm/at91/std.kb920x
+++ b/sys/arm/at91/std.kb920x
@@ -6,5 +6,6 @@ makeoptions KERNPHYSADDR=0x20000000
options KERNPHYSADDR=0x20000000
makeoptions KERNVIRTADDR=0xc0000000
options KERNVIRTADDR=0xc0000000
+options AT91C_MASTER_CLOCK=60000000
device at91_board_kb920x
diff --git a/sys/arm/at91/std.sam9g20ek b/sys/arm/at91/std.sam9g20ek
new file mode 100644
index 0000000..5a0d743
--- /dev/null
+++ b/sys/arm/at91/std.sam9g20ek
@@ -0,0 +1,11 @@
+#$FreeBSD$
+include "../at91/std.at91sam9"
+
+options STARTUP_PAGETABLE_ADDR=0x20800000
+makeoptions KERNPHYSADDR=0x20000000
+makeoptions KERNVIRTADDR=0xc0000000
+options KERNPHYSADDR=0x20000000
+options KERNVIRTADDR=0xc0000000
+options AT91C_MASTER_CLOCK=((18432000*43)/6)
+
+device at91_board_sam9g20ek
diff --git a/sys/arm/at91/uart_cpu_at91rm9200usart.c b/sys/arm/at91/uart_cpu_at91rm9200usart.c
index d290c28..9e9baa2 100644
--- a/sys/arm/at91/uart_cpu_at91rm9200usart.c
+++ b/sys/arm/at91/uart_cpu_at91rm9200usart.c
@@ -64,7 +64,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
struct uart_class *class;
class = &at91_usart_class;
- if (class->uc_rclk == 0)
+ if (class->uc_rclk == 0 && at91_master_clock != 0)
class->uc_rclk = at91_master_clock;
di->ops = uart_getops(class);
di->bas.chan = 0;
@@ -77,7 +77,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
di->bas.bsh = AT91RM92_BASE + AT91RM92_USART0_BASE;
di->baudrate = 38400;
#else
- di->bas.bsh = AT91RM92_BASE + AT91RM92_SYS_BASE + DBGU;
+ di->bas.bsh = AT91RM92_BASE + AT91RM92_DBGU_BASE;
di->baudrate = 115200;
#endif
di->bas.regshft = 0;
diff --git a/sys/arm/at91/uart_dev_at91usart.c b/sys/arm/at91/uart_dev_at91usart.c
index 77ab0ca..89ed2d2 100644
--- a/sys/arm/at91/uart_dev_at91usart.c
+++ b/sys/arm/at91/uart_dev_at91usart.c
@@ -190,9 +190,10 @@ at91_usart_param(struct uart_bas *bas, int baudrate, int databits,
WR4(bas, USART_MR, mr);
/*
- * Set the baud rate
+ * Set the baud rate (only if we know our master clock rate)
*/
- WR4(bas, USART_BRGR, BAUD2DIVISOR(baudrate));
+ if (DEFAULT_RCLK != 0)
+ WR4(bas, USART_BRGR, BAUD2DIVISOR(baudrate));
/* XXX Need to take possible synchronous mode into account */
return (0);
@@ -674,7 +675,10 @@ at91_usart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
case UART_IOCTL_OFLOW:
break;
case UART_IOCTL_BAUD:
- WR4(&sc->sc_bas, USART_BRGR, BAUD2DIVISOR(*(int *)data));
+ /* 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);
OpenPOWER on IntegriCloud