diff options
author | cognet <cognet@FreeBSD.org> | 2010-10-06 22:25:21 +0000 |
---|---|---|
committer | cognet <cognet@FreeBSD.org> | 2010-10-06 22:25:21 +0000 |
commit | 2edabad8a47c024ddbf097f91202a71b88cff6fc (patch) | |
tree | c231f180320438f262879021e2e02bbace0911b3 /sys/arm | |
parent | 87987160d6251c2bc94a904a9995d519ac8df5fd (diff) | |
download | FreeBSD-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/arm')
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); |