Index: head/sys/arm/at91/at91.c =================================================================== --- head/sys/arm/at91/at91.c +++ head/sys/arm/at91/at91.c @@ -1,373 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2005 Olivier Houchard. All rights reserved. - * Copyright (c) 2010 Greg Ansley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "opt_platform.h" - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#define _ARM32_BUS_DMA_PRIVATE -#include -#include - -#include -#include -#include - -uint32_t at91_master_clock; - -struct arm32_dma_range * -bus_dma_get_range(void) -{ - - return (NULL); -} - -int -bus_dma_get_range_nb(void) -{ - return (0); -} - -#ifndef FDT - -static struct at91_softc *at91_softc; - -static void at91_eoi(void *); - -static int -at91_probe(device_t dev) -{ - - device_set_desc(dev, soc_info.name); - return (BUS_PROBE_NOWILDCARD); -} - -static void -at91_identify(driver_t *drv, device_t parent) -{ - - BUS_ADD_CHILD(parent, 0, "atmelarm", 0); -} - -static void -at91_cpu_add_builtin_children(device_t dev, const struct cpu_devs *walker) -{ - int i; - - for (i = 0; walker->name; i++, walker++) { - at91_add_child(dev, i, walker->name, walker->unit, - walker->mem_base, walker->mem_len, walker->irq0, - walker->irq1, walker->irq2); - } -} - -static int -at91_attach(device_t dev) -{ - struct at91_softc *sc = device_get_softc(dev); - - arm_post_filter = at91_eoi; - - at91_softc = sc; - sc->sc_st = arm_base_bs_tag; - sc->sc_sh = AT91_BASE; - sc->sc_aic_sh = AT91_BASE + AT91_SYS_BASE; - sc->dev = dev; - - sc->sc_irq_rman.rm_type = RMAN_ARRAY; - sc->sc_irq_rman.rm_descr = "AT91 IRQs"; - if (rman_init(&sc->sc_irq_rman) != 0 || - rman_manage_region(&sc->sc_irq_rman, 1, 31) != 0) - panic("at91_attach: failed to set up IRQ rman"); - - sc->sc_mem_rman.rm_type = RMAN_ARRAY; - sc->sc_mem_rman.rm_descr = "AT91 Memory"; - if (rman_init(&sc->sc_mem_rman) != 0) - panic("at91_attach: failed to set up memory rman"); - /* - * Manage the physical space, defined as being everything that isn't - * DRAM. - */ - if (rman_manage_region(&sc->sc_mem_rman, 0, PHYSADDR - 1) != 0) - panic("at91_attach: failed to set up memory rman"); - if (rman_manage_region(&sc->sc_mem_rman, PHYSADDR + (256 << 20), - 0xfffffffful) != 0) - panic("at91_attach: failed to set up memory rman"); - - /* - * Add this device's children... - */ - at91_cpu_add_builtin_children(dev, soc_info.soc_data->soc_children); - soc_info.soc_data->soc_clock_init(); - - bus_generic_probe(dev); - bus_generic_attach(dev); - enable_interrupts(PSR_I | PSR_F); - return (0); -} - -static struct resource * -at91_alloc_resource(device_t dev, device_t child, int type, int *rid, - rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) -{ - struct at91_softc *sc = device_get_softc(dev); - struct resource_list_entry *rle; - struct at91_ivar *ivar = device_get_ivars(child); - struct resource_list *rl = &ivar->resources; - bus_space_handle_t bsh; - - if (device_get_parent(child) != dev) - return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, - type, rid, start, end, count, flags)); - - rle = resource_list_find(rl, type, *rid); - if (rle == NULL) - return (NULL); - if (rle->res) - panic("Resource rid %d type %d already in use", *rid, type); - if (RMAN_IS_DEFAULT_RANGE(start, end)) { - start = rle->start; - count = ulmax(count, rle->count); - end = ulmax(rle->end, start + count - 1); - } - switch (type) - { - case SYS_RES_IRQ: - rle->res = rman_reserve_resource(&sc->sc_irq_rman, - start, end, count, flags, child); - break; - case SYS_RES_MEMORY: - rle->res = rman_reserve_resource(&sc->sc_mem_rman, - start, end, count, flags, child); - if (rle->res != NULL) { - bus_space_map(arm_base_bs_tag, start, - rman_get_size(rle->res), 0, &bsh); - rman_set_bustag(rle->res, arm_base_bs_tag); - rman_set_bushandle(rle->res, bsh); - } - break; - } - if (rle->res) { - rle->start = rman_get_start(rle->res); - rle->end = rman_get_end(rle->res); - rle->count = count; - rman_set_rid(rle->res, *rid); - } - return (rle->res); -} - -static struct resource_list * -at91_get_resource_list(device_t dev, device_t child) -{ - struct at91_ivar *ivar; - - ivar = device_get_ivars(child); - return (&(ivar->resources)); -} - -static int -at91_release_resource(device_t dev, device_t child, int type, - int rid, struct resource *r) -{ - struct resource_list *rl; - struct resource_list_entry *rle; - - rl = at91_get_resource_list(dev, child); - if (rl == NULL) - return (EINVAL); - rle = resource_list_find(rl, type, rid); - if (rle == NULL) - return (EINVAL); - rman_release_resource(r); - rle->res = NULL; - return (0); -} - -static int -at91_setup_intr(device_t dev, device_t child, - struct resource *ires, int flags, driver_filter_t *filt, - driver_intr_t *intr, void *arg, void **cookiep) -{ - int error; - - if (rman_get_start(ires) == AT91_IRQ_SYSTEM && filt == NULL) - panic("All system interrupt ISRs must be FILTER"); - error = BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, - filt, intr, arg, cookiep); - if (error) - return (error); - - return (0); -} - -static int -at91_teardown_intr(device_t dev, device_t child, struct resource *res, - void *cookie) -{ - struct at91_softc *sc = device_get_softc(dev); - - bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_IDCR, - 1 << rman_get_start(res)); - return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie)); -} - -static int -at91_activate_resource(device_t bus, device_t child, int type, int rid, - struct resource *r) -{ -#if 0 - rman_res_t p; - int error; - - if (type == SYS_RES_MEMORY) { - error = bus_space_map(rman_get_bustag(r), - rman_get_bushandle(r), rman_get_size(r), 0, &p); - if (error) - return (error); - rman_set_bushandle(r, p); - } -#endif - return (rman_activate_resource(r)); -} - -static int -at91_print_child(device_t dev, device_t child) -{ - struct at91_ivar *ivars; - struct resource_list *rl; - int retval = 0; - - ivars = device_get_ivars(child); - rl = &ivars->resources; - - retval += bus_print_child_header(dev, child); - - retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#jx"); - retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx"); - retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%jd"); - if (device_get_flags(dev)) - retval += printf(" flags %#x", device_get_flags(dev)); - - retval += bus_print_child_footer(dev, child); - - return (retval); -} - -static void -at91_eoi(void *unused) -{ - bus_space_write_4(at91_softc->sc_st, at91_softc->sc_aic_sh, - IC_EOICR, 0); -} - -void -at91_add_child(device_t dev, int prio, const char *name, int unit, - bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2) -{ - device_t kid; - struct at91_ivar *ivar; - - kid = device_add_child_ordered(dev, prio, name, unit); - if (kid == NULL) { - printf("Can't add child %s%d ordered\n", name, unit); - return; - } - ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO); - if (ivar == NULL) { - device_delete_child(dev, kid); - printf("Can't add alloc ivar\n"); - return; - } - device_set_ivars(kid, ivar); - resource_list_init(&ivar->resources); - if (irq0 != -1) { - bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1); - if (irq0 != AT91_IRQ_SYSTEM) - at91_pmc_clock_add(device_get_nameunit(kid), irq0, 0); - } - if (irq1 != 0) - bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1); - if (irq2 != 0) - bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1); - /* - * Special case for on-board devices. These have their address - * defined relative to AT91_PA_BASE in all the register files we - * have. We could change this, but that's a lot of effort which - * will be obsoleted when FDT arrives. - */ - if (addr != 0 && addr < 0x10000000 && addr >= 0x0f000000) - addr += AT91_PA_BASE; - if (addr != 0) - bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size); -} - -static device_method_t at91_methods[] = { - DEVMETHOD(device_probe, at91_probe), - DEVMETHOD(device_attach, at91_attach), - DEVMETHOD(device_identify, at91_identify), - - DEVMETHOD(bus_alloc_resource, at91_alloc_resource), - DEVMETHOD(bus_setup_intr, at91_setup_intr), - DEVMETHOD(bus_teardown_intr, at91_teardown_intr), - DEVMETHOD(bus_activate_resource, at91_activate_resource), - DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), - DEVMETHOD(bus_get_resource_list,at91_get_resource_list), - DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), - DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), - DEVMETHOD(bus_release_resource, at91_release_resource), - DEVMETHOD(bus_print_child, at91_print_child), - - {0, 0}, -}; - -static driver_t at91_driver = { - "atmelarm", - at91_methods, - sizeof(struct at91_softc), -}; - -static devclass_t at91_devclass; - -DRIVER_MODULE(atmelarm, nexus, at91_driver, at91_devclass, 0, 0); -#endif Index: head/sys/arm/at91/at91_aic.c =================================================================== --- head/sys/arm/at91/at91_aic.c +++ head/sys/arm/at91/at91_aic.c @@ -1,184 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2014 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "opt_platform.h" - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#ifdef FDT -#include -#include -#endif - -static struct aic_softc { - struct resource *mem_res; /* Memory resource */ - void *intrhand; /* Interrupt handle */ - device_t sc_dev; -} *sc; - -static inline uint32_t -RD4(struct aic_softc *sc, bus_size_t off) -{ - - return (bus_read_4(sc->mem_res, off)); -} - -static inline void -WR4(struct aic_softc *sc, bus_size_t off, uint32_t val) -{ - - bus_write_4(sc->mem_res, off, val); -} - -void -arm_mask_irq(uintptr_t nb) -{ - - WR4(sc, IC_IDCR, 1 << nb); -} - -int -arm_get_next_irq(int last __unused) -{ - int status; - int irq; - - irq = RD4(sc, IC_IVR); - status = RD4(sc, IC_ISR); - if (status == 0) { - WR4(sc, IC_EOICR, 1); - return (-1); - } - return (irq); -} - -void -arm_unmask_irq(uintptr_t nb) -{ - - WR4(sc, IC_IECR, 1 << nb); - WR4(sc, IC_EOICR, 0); -} - -static int -at91_aic_probe(device_t dev) -{ -#ifdef FDT - if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-aic")) - return (ENXIO); -#endif - device_set_desc(dev, "AIC"); - return (0); -} - -static int -at91_aic_attach(device_t dev) -{ - int i, rid, err = 0; - - device_printf(dev, "Attach %d\n", bus_current_pass); - - sc = device_get_softc(dev); - sc->sc_dev = dev; - - rid = 0; - sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - - if (sc->mem_res == NULL) - panic("couldn't allocate register resources"); - - /* - * Setup the interrupt table. - */ - if (soc_info.soc_data == NULL || soc_info.soc_data->soc_irq_prio == NULL) - panic("Interrupt priority table missing\n"); - for (i = 0; i < 32; i++) { - WR4(sc, IC_SVR + i * 4, i); - /* Priority. */ - WR4(sc, IC_SMR + i * 4, soc_info.soc_data->soc_irq_prio[i]); - if (i < 8) - WR4(sc, IC_EOICR, 1); - } - - WR4(sc, IC_SPU, 32); - /* No debug. */ - WR4(sc, IC_DCR, 0); - /* Disable and clear all interrupts. */ - WR4(sc, IC_IDCR, 0xffffffff); - WR4(sc, IC_ICCR, 0xffffffff); - enable_interrupts(PSR_I | PSR_F); - - return (err); -} - -static void -at91_aic_new_pass(device_t dev) -{ - device_printf(dev, "Pass %d\n", bus_current_pass); -} - -static device_method_t at91_aic_methods[] = { - DEVMETHOD(device_probe, at91_aic_probe), - DEVMETHOD(device_attach, at91_aic_attach), - DEVMETHOD(bus_new_pass, at91_aic_new_pass), - DEVMETHOD_END -}; - -static driver_t at91_aic_driver = { - "at91_aic", - at91_aic_methods, - sizeof(struct aic_softc), -}; - -static devclass_t at91_aic_devclass; - -#ifdef FDT -EARLY_DRIVER_MODULE(at91_aic, simplebus, at91_aic_driver, at91_aic_devclass, - NULL, NULL, BUS_PASS_INTERRUPT); -#else -EARLY_DRIVER_MODULE(at91_aic, atmelarm, at91_aic_driver, at91_aic_devclass, - NULL, NULL, BUS_PASS_INTERRUPT); -#endif Index: head/sys/arm/at91/at91_aicreg.h =================================================================== --- head/sys/arm/at91/at91_aicreg.h +++ head/sys/arm/at91/at91_aicreg.h @@ -1,53 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2009 Sylvestre Gallon. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef ARM_AT91_AT91_AICREG_H -#define ARM_AT91_AT91_AICREG_H - -/* Interrupt Controller */ -#define IC_SMR (0) /* Source mode register */ -#define IC_SVR (128) /* Source vector register */ -#define IC_IVR (256) /* IRQ vector register */ -#define IC_FVR (260) /* FIQ vector register */ -#define IC_ISR (264) /* Interrupt status register */ -#define IC_IPR (268) /* Interrupt pending register */ -#define IC_IMR (272) /* Interrupt status register */ -#define IC_CISR (276) /* Core interrupt status register */ -#define IC_IECR (288) /* Interrupt enable command register */ -#define IC_IDCR (292) /* Interrupt disable command register */ -#define IC_ICCR (296) /* Interrupt clear command register */ -#define IC_ISCR (300) /* Interrupt set command register */ -#define IC_EOICR (304) /* End of interrupt command register */ -#define IC_SPU (308) /* Spurious vector register */ -#define IC_DCR (312) /* Debug control register */ -#define IC_FFER (320) /* Fast forcing enable register */ -#define IC_FFDR (324) /* Fast forcing disable register */ -#define IC_FFSR (328) /* Fast forcing status register */ - -#endif /*ARM_AT91_AT91_AICREG_H*/ Index: head/sys/arm/at91/at91_cfata.c =================================================================== --- head/sys/arm/at91/at91_cfata.c +++ head/sys/arm/at91/at91_cfata.c @@ -1,281 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2008 Deglitch Networks, Stanislav Sedov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Driver for the AT91RM9200 CompactFlash controller operating in a - * common memory mode. Interrupts are driven by polling. The driver - * implements an ATA bridge and attached ATA channel driver on top - * of it. - * NOTE WELL: this driver uses polling mode. To achieve an acceptable - * operating speed you will probably want to use HZ=2000 in kernel - * config. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -struct at91_cfata_softc { - device_t dev; - struct resource *mem_res; - struct resource irq; - void (*isr_cb)(void *); - void *isr_arg; - struct callout tick; -}; - -static int at91_cfata_detach(device_t dev); -static void at91_cfata_callout(void *arg); - -static int -at91_cfata_probe(device_t dev) -{ - - device_set_desc_copy(dev, "AT91RM9200 CompactFlash controller"); - return (0); -} - -static int -at91_cfata_attach(device_t dev) -{ - struct at91_cfata_softc *sc; - int rid, error; - - sc = device_get_softc(dev); - sc->dev = dev; - rid = 0; - error = 0; - sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - if (sc->mem_res == NULL) - return (ENOMEM); - - /* XXX: init CF controller? */ - - callout_init(&sc->tick, 1); /* Callout to poll the device. */ - device_add_child(dev, "ata", -1); - bus_generic_attach(dev); - return (0); -} - -static int -at91_cfata_detach(device_t dev) -{ - struct at91_cfata_softc *sc; - - sc = device_get_softc(dev); - bus_generic_detach(sc->dev); - if (sc->mem_res != NULL) { - bus_release_resource(dev, SYS_RES_MEMORY, - rman_get_rid(sc->mem_res), sc->mem_res); - sc->mem_res = NULL; - } - return (0); -} - -static struct resource * -ata_at91_alloc_resource(device_t dev, device_t child, int type, int *rid, - rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) -{ - struct at91_cfata_softc *sc = device_get_softc(dev); - - KASSERT(type == SYS_RES_IRQ && *rid == ATA_IRQ_RID, - ("[at91_cfata, %d]: illegal resource request (type %u rid %u)", - __LINE__, type, *rid)); - return (&sc->irq); -} - -static int -ata_at91_release_resource(device_t dev, device_t child, int type, int rid, - struct resource *r) -{ - - KASSERT(type == SYS_RES_IRQ && rid == ATA_IRQ_RID, - ("[at91_cfata, %d]: illegal resource request (type %u rid %u)", - __LINE__, type, rid)); - return (0); -} - - -static int -ata_at91_setup_intr(device_t dev, device_t child, struct resource *irq, - int flags, driver_filter_t *filt, - driver_intr_t *function, void *argument, void **cookiep) -{ - struct at91_cfata_softc *sc = device_get_softc(dev); - - KASSERT(sc->isr_cb == NULL, - ("[at91_cfata, %d]: overwriting the old handler", __LINE__)); - sc->isr_cb = function; - sc->isr_arg = argument; - *cookiep = sc; - callout_reset(&sc->tick, 1, at91_cfata_callout, sc); - return (0); -} - -static int -ata_at91_teardown_intr(device_t dev, device_t child, struct resource *irq, - void *cookie) -{ - struct at91_cfata_softc *sc = device_get_softc(dev); - - sc->isr_cb = NULL; - sc->isr_arg = NULL; - return (0); -} - -static void -at91_cfata_callout(void *arg) -{ - struct at91_cfata_softc *sc; - - sc = (struct at91_cfata_softc *)arg; - if (sc->isr_cb != NULL) - sc->isr_cb(sc->isr_arg); - callout_reset(&sc->tick, 1, at91_cfata_callout, sc); -} - -static int -at91_channel_probe(device_t dev) -{ - struct ata_channel *ch = device_get_softc(dev); - - ch->unit = 0; - ch->flags |= ATA_USE_16BIT | ATA_NO_SLAVE; - device_set_desc_copy(dev, "ATA channel 0"); - - return (ata_probe(dev)); -} - -static int -at91_channel_attach(device_t dev) -{ - struct at91_cfata_softc *sc = device_get_softc(device_get_parent(dev)); - struct ata_channel *ch = device_get_softc(dev); - int i; - - for (i = 0; i < ATA_MAX_RES; i++) - ch->r_io[i].res = sc->mem_res; - - /* - * CF+ Specification. - * 6.1.3 Memory Mapped Addressing. - */ - ch->r_io[ATA_DATA].offset = 0x00; - ch->r_io[ATA_FEATURE].offset = 0x01; - ch->r_io[ATA_COUNT].offset = 0x02; - ch->r_io[ATA_SECTOR].offset = 0x03; - ch->r_io[ATA_CYL_LSB].offset = 0x04; - ch->r_io[ATA_CYL_MSB].offset = 0x05; - ch->r_io[ATA_DRIVE].offset = 0x06; - ch->r_io[ATA_COMMAND].offset = 0x07; - ch->r_io[ATA_ERROR].offset = 0x01; - ch->r_io[ATA_IREASON].offset = 0x02; - ch->r_io[ATA_STATUS].offset = 0x07; - ch->r_io[ATA_ALTSTAT].offset = 0x0e; - ch->r_io[ATA_CONTROL].offset = 0x0e; - - /* Should point at the base of registers. */ - ch->r_io[ATA_IDX_ADDR].offset = 0x0; - - ata_generic_hw(dev); - return (ata_attach(dev)); -} - -static device_method_t at91_cfata_methods[] = { - /* Device interface. */ - DEVMETHOD(device_probe, at91_cfata_probe), - DEVMETHOD(device_attach, at91_cfata_attach), - DEVMETHOD(device_detach, at91_cfata_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - - /* ATA bus methods. */ - DEVMETHOD(bus_alloc_resource, ata_at91_alloc_resource), - DEVMETHOD(bus_release_resource, ata_at91_release_resource), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), - DEVMETHOD(bus_deactivate_resource, - bus_generic_deactivate_resource), - DEVMETHOD(bus_setup_intr, ata_at91_setup_intr), - DEVMETHOD(bus_teardown_intr, ata_at91_teardown_intr), - - { 0, 0 } -}; - -devclass_t at91_cfata_devclass; - -static driver_t at91_cfata_driver = { - "at91_cfata", - at91_cfata_methods, - sizeof(struct at91_cfata_softc), -}; - -DRIVER_MODULE(at91_cfata, atmelarm, at91_cfata_driver, at91_cfata_devclass, 0, - 0); -MODULE_VERSION(at91_cfata, 1); -MODULE_DEPEND(at91_cfata, ata, 1, 1, 1); - -/* - * ATA channel driver. - */ -static device_method_t at91_channel_methods[] = { - /* device interface */ - DEVMETHOD(device_probe, at91_channel_probe), - DEVMETHOD(device_attach, at91_channel_attach), - DEVMETHOD(device_detach, ata_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, ata_suspend), - DEVMETHOD(device_resume, ata_resume), - - { 0, 0 } -}; - -driver_t at91_channel_driver = { - "ata", - at91_channel_methods, - sizeof(struct ata_channel), -}; - -DRIVER_MODULE(ata, at91_cfata, at91_channel_driver, ata_devclass, 0, 0); Index: head/sys/arm/at91/at91_common.c =================================================================== --- head/sys/arm/at91/at91_common.c +++ head/sys/arm/at91/at91_common.c @@ -1,121 +0,0 @@ -/*- - * Copyright (c) 2014 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#define _ARM32_BUS_DMA_PRIVATE -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include - -extern const struct devmap_entry at91_devmap[]; - -#ifndef INTRNG -static int -fdt_aic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig, - int *pol) -{ - int offset; - - if (ofw_bus_node_is_compatible(node, "atmel,at91rm9200-aic")) - offset = 0; - else - return (ENXIO); - - *interrupt = fdt32_to_cpu(intr[0]) + offset; - *trig = INTR_TRIGGER_CONFORM; - *pol = INTR_POLARITY_CONFORM; - - return (0); -} - -fdt_pic_decode_t fdt_pic_table[] = { - &fdt_aic_decode_ic, - NULL -}; -#endif - -static void -at91_eoi(void *unused) -{ - uint32_t *eoicr = (uint32_t *)(0xdffff000 + IC_EOICR); - - *eoicr = 0; -} - - -vm_offset_t -platform_lastaddr(void) -{ - - return (devmap_lastaddr()); -} - -void -platform_probe_and_attach(void) -{ - - arm_post_filter = at91_eoi; - at91_soc_id(); -} - -int -platform_devmap_init(void) -{ - -// devmap_add_entry(0xfff00000, 0x00100000); /* 1MB - uart, aic and timers*/ - - devmap_register_table(at91_devmap); - - return (0); -} - -void -platform_gpio_init(void) -{ -} - -void -platform_late_init(void) -{ -} Index: head/sys/arm/at91/at91_gpio.h =================================================================== --- head/sys/arm/at91/at91_gpio.h +++ head/sys/arm/at91/at91_gpio.h @@ -1,298 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2014 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef ARM_AT91_AT91_GPIO_H -#define ARM_AT91_AT91_GPIO_H - -typedef uint32_t at91_pin_t; - -#define AT91_PIN_NONE 0xfffffffful /* No pin / Not GPIO controlled */ - -/* - * Map Atmel PIO pins to a unique number. They are just numbered sequentially. - */ - -#define AT91_PIN_PA0 (at91_pin_t)0 -#define AT91_PIN_PA1 (at91_pin_t)1 -#define AT91_PIN_PA2 (at91_pin_t)2 -#define AT91_PIN_PA3 (at91_pin_t)3 -#define AT91_PIN_PA4 (at91_pin_t)4 -#define AT91_PIN_PA5 (at91_pin_t)5 -#define AT91_PIN_PA6 (at91_pin_t)6 -#define AT91_PIN_PA7 (at91_pin_t)7 -#define AT91_PIN_PA8 (at91_pin_t)8 -#define AT91_PIN_PA9 (at91_pin_t)9 -#define AT91_PIN_PA10 (at91_pin_t)10 -#define AT91_PIN_PA11 (at91_pin_t)11 -#define AT91_PIN_PA12 (at91_pin_t)12 -#define AT91_PIN_PA13 (at91_pin_t)13 -#define AT91_PIN_PA14 (at91_pin_t)14 -#define AT91_PIN_PA15 (at91_pin_t)15 -#define AT91_PIN_PA16 (at91_pin_t)16 -#define AT91_PIN_PA17 (at91_pin_t)17 -#define AT91_PIN_PA18 (at91_pin_t)18 -#define AT91_PIN_PA19 (at91_pin_t)19 -#define AT91_PIN_PA20 (at91_pin_t)20 -#define AT91_PIN_PA21 (at91_pin_t)21 -#define AT91_PIN_PA22 (at91_pin_t)22 -#define AT91_PIN_PA23 (at91_pin_t)23 -#define AT91_PIN_PA24 (at91_pin_t)24 -#define AT91_PIN_PA25 (at91_pin_t)25 -#define AT91_PIN_PA26 (at91_pin_t)26 -#define AT91_PIN_PA27 (at91_pin_t)27 -#define AT91_PIN_PA28 (at91_pin_t)28 -#define AT91_PIN_PA29 (at91_pin_t)29 -#define AT91_PIN_PA30 (at91_pin_t)30 -#define AT91_PIN_PA31 (at91_pin_t)31 -#define AT91_PIN_PB0 (at91_pin_t)32 -#define AT91_PIN_PB1 (at91_pin_t)33 -#define AT91_PIN_PB2 (at91_pin_t)34 -#define AT91_PIN_PB3 (at91_pin_t)35 -#define AT91_PIN_PB4 (at91_pin_t)36 -#define AT91_PIN_PB5 (at91_pin_t)37 -#define AT91_PIN_PB6 (at91_pin_t)38 -#define AT91_PIN_PB7 (at91_pin_t)39 -#define AT91_PIN_PB8 (at91_pin_t)40 -#define AT91_PIN_PB9 (at91_pin_t)41 -#define AT91_PIN_PB10 (at91_pin_t)42 -#define AT91_PIN_PB11 (at91_pin_t)43 -#define AT91_PIN_PB12 (at91_pin_t)44 -#define AT91_PIN_PB13 (at91_pin_t)45 -#define AT91_PIN_PB14 (at91_pin_t)46 -#define AT91_PIN_PB15 (at91_pin_t)47 -#define AT91_PIN_PB16 (at91_pin_t)48 -#define AT91_PIN_PB17 (at91_pin_t)49 -#define AT91_PIN_PB18 (at91_pin_t)50 -#define AT91_PIN_PB19 (at91_pin_t)51 -#define AT91_PIN_PB20 (at91_pin_t)52 -#define AT91_PIN_PB21 (at91_pin_t)53 -#define AT91_PIN_PB22 (at91_pin_t)54 -#define AT91_PIN_PB23 (at91_pin_t)55 -#define AT91_PIN_PB24 (at91_pin_t)56 -#define AT91_PIN_PB25 (at91_pin_t)57 -#define AT91_PIN_PB26 (at91_pin_t)58 -#define AT91_PIN_PB27 (at91_pin_t)59 -#define AT91_PIN_PB28 (at91_pin_t)60 -#define AT91_PIN_PB29 (at91_pin_t)61 -#define AT91_PIN_PB30 (at91_pin_t)62 -#define AT91_PIN_PB31 (at91_pin_t)63 -#define AT91_PIN_PC0 (at91_pin_t)64 -#define AT91_PIN_PC1 (at91_pin_t)65 -#define AT91_PIN_PC2 (at91_pin_t)66 -#define AT91_PIN_PC3 (at91_pin_t)67 -#define AT91_PIN_PC4 (at91_pin_t)68 -#define AT91_PIN_PC5 (at91_pin_t)69 -#define AT91_PIN_PC6 (at91_pin_t)70 -#define AT91_PIN_PC7 (at91_pin_t)71 -#define AT91_PIN_PC8 (at91_pin_t)72 -#define AT91_PIN_PC9 (at91_pin_t)73 -#define AT91_PIN_PC10 (at91_pin_t)74 -#define AT91_PIN_PC11 (at91_pin_t)75 -#define AT91_PIN_PC12 (at91_pin_t)76 -#define AT91_PIN_PC13 (at91_pin_t)77 -#define AT91_PIN_PC14 (at91_pin_t)78 -#define AT91_PIN_PC15 (at91_pin_t)79 -#define AT91_PIN_PC16 (at91_pin_t)80 -#define AT91_PIN_PC17 (at91_pin_t)81 -#define AT91_PIN_PC18 (at91_pin_t)82 -#define AT91_PIN_PC19 (at91_pin_t)83 -#define AT91_PIN_PC20 (at91_pin_t)84 -#define AT91_PIN_PC21 (at91_pin_t)85 -#define AT91_PIN_PC22 (at91_pin_t)86 -#define AT91_PIN_PC23 (at91_pin_t)87 -#define AT91_PIN_PC24 (at91_pin_t)88 -#define AT91_PIN_PC25 (at91_pin_t)89 -#define AT91_PIN_PC26 (at91_pin_t)90 -#define AT91_PIN_PC27 (at91_pin_t)91 -#define AT91_PIN_PC28 (at91_pin_t)92 -#define AT91_PIN_PC29 (at91_pin_t)93 -#define AT91_PIN_PC30 (at91_pin_t)94 -#define AT91_PIN_PC31 (at91_pin_t)95 -#define AT91_PIN_PD0 (at91_pin_t)96 -#define AT91_PIN_PD1 (at91_pin_t)97 -#define AT91_PIN_PD2 (at91_pin_t)98 -#define AT91_PIN_PD3 (at91_pin_t)99 -#define AT91_PIN_PD4 (at91_pin_t)100 -#define AT91_PIN_PD5 (at91_pin_t)101 -#define AT91_PIN_PD6 (at91_pin_t)102 -#define AT91_PIN_PD7 (at91_pin_t)103 -#define AT91_PIN_PD8 (at91_pin_t)104 -#define AT91_PIN_PD9 (at91_pin_t)105 -#define AT91_PIN_PD10 (at91_pin_t)106 -#define AT91_PIN_PD11 (at91_pin_t)107 -#define AT91_PIN_PD12 (at91_pin_t)108 -#define AT91_PIN_PD13 (at91_pin_t)109 -#define AT91_PIN_PD14 (at91_pin_t)110 -#define AT91_PIN_PD15 (at91_pin_t)111 -#define AT91_PIN_PD16 (at91_pin_t)112 -#define AT91_PIN_PD17 (at91_pin_t)113 -#define AT91_PIN_PD18 (at91_pin_t)114 -#define AT91_PIN_PD19 (at91_pin_t)115 -#define AT91_PIN_PD20 (at91_pin_t)116 -#define AT91_PIN_PD21 (at91_pin_t)117 -#define AT91_PIN_PD22 (at91_pin_t)118 -#define AT91_PIN_PD23 (at91_pin_t)119 -#define AT91_PIN_PD24 (at91_pin_t)120 -#define AT91_PIN_PD25 (at91_pin_t)121 -#define AT91_PIN_PD26 (at91_pin_t)122 -#define AT91_PIN_PD27 (at91_pin_t)123 -#define AT91_PIN_PD28 (at91_pin_t)124 -#define AT91_PIN_PD29 (at91_pin_t)125 -#define AT91_PIN_PD30 (at91_pin_t)126 -#define AT91_PIN_PD31 (at91_pin_t)127 -#define AT91_PIN_PE0 (at91_pin_t)128 -#define AT91_PIN_PE1 (at91_pin_t)129 -#define AT91_PIN_PE2 (at91_pin_t)130 -#define AT91_PIN_PE3 (at91_pin_t)131 -#define AT91_PIN_PE4 (at91_pin_t)132 -#define AT91_PIN_PE5 (at91_pin_t)133 -#define AT91_PIN_PE6 (at91_pin_t)134 -#define AT91_PIN_PE7 (at91_pin_t)135 -#define AT91_PIN_PE8 (at91_pin_t)136 -#define AT91_PIN_PE9 (at91_pin_t)137 -#define AT91_PIN_PE10 (at91_pin_t)138 -#define AT91_PIN_PE11 (at91_pin_t)139 -#define AT91_PIN_PE12 (at91_pin_t)140 -#define AT91_PIN_PE13 (at91_pin_t)141 -#define AT91_PIN_PE14 (at91_pin_t)142 -#define AT91_PIN_PE15 (at91_pin_t)143 -#define AT91_PIN_PE16 (at91_pin_t)144 -#define AT91_PIN_PE17 (at91_pin_t)145 -#define AT91_PIN_PE18 (at91_pin_t)146 -#define AT91_PIN_PE19 (at91_pin_t)147 -#define AT91_PIN_PE20 (at91_pin_t)148 -#define AT91_PIN_PE21 (at91_pin_t)149 -#define AT91_PIN_PE22 (at91_pin_t)150 -#define AT91_PIN_PE23 (at91_pin_t)151 -#define AT91_PIN_PE24 (at91_pin_t)152 -#define AT91_PIN_PE25 (at91_pin_t)153 -#define AT91_PIN_PE26 (at91_pin_t)154 -#define AT91_PIN_PE27 (at91_pin_t)155 -#define AT91_PIN_PE28 (at91_pin_t)156 -#define AT91_PIN_PE29 (at91_pin_t)157 -#define AT91_PIN_PE30 (at91_pin_t)158 -#define AT91_PIN_PE31 (at91_pin_t)159 -#define AT91_PIN_PF0 (at91_pin_t)160 -#define AT91_PIN_PF1 (at91_pin_t)161 -#define AT91_PIN_PF2 (at91_pin_t)162 -#define AT91_PIN_PF3 (at91_pin_t)163 -#define AT91_PIN_PF4 (at91_pin_t)164 -#define AT91_PIN_PF5 (at91_pin_t)165 -#define AT91_PIN_PF6 (at91_pin_t)166 -#define AT91_PIN_PF7 (at91_pin_t)167 -#define AT91_PIN_PF8 (at91_pin_t)168 -#define AT91_PIN_PF9 (at91_pin_t)169 -#define AT91_PIN_PF10 (at91_pin_t)170 -#define AT91_PIN_PF11 (at91_pin_t)171 -#define AT91_PIN_PF12 (at91_pin_t)172 -#define AT91_PIN_PF13 (at91_pin_t)173 -#define AT91_PIN_PF14 (at91_pin_t)174 -#define AT91_PIN_PF15 (at91_pin_t)175 -#define AT91_PIN_PF16 (at91_pin_t)176 -#define AT91_PIN_PF17 (at91_pin_t)177 -#define AT91_PIN_PF18 (at91_pin_t)178 -#define AT91_PIN_PF19 (at91_pin_t)179 -#define AT91_PIN_PF20 (at91_pin_t)180 -#define AT91_PIN_PF21 (at91_pin_t)181 -#define AT91_PIN_PF22 (at91_pin_t)182 -#define AT91_PIN_PF23 (at91_pin_t)183 -#define AT91_PIN_PF24 (at91_pin_t)184 -#define AT91_PIN_PF25 (at91_pin_t)185 -#define AT91_PIN_PF26 (at91_pin_t)186 -#define AT91_PIN_PF27 (at91_pin_t)187 -#define AT91_PIN_PF28 (at91_pin_t)188 -#define AT91_PIN_PF29 (at91_pin_t)189 -#define AT91_PIN_PF30 (at91_pin_t)190 -#define AT91_PIN_PF31 (at91_pin_t)191 -#define AT91_PIN_PG0 (at91_pin_t)192 -#define AT91_PIN_PG1 (at91_pin_t)193 -#define AT91_PIN_PG2 (at91_pin_t)194 -#define AT91_PIN_PG3 (at91_pin_t)195 -#define AT91_PIN_PG4 (at91_pin_t)196 -#define AT91_PIN_PG5 (at91_pin_t)197 -#define AT91_PIN_PG6 (at91_pin_t)198 -#define AT91_PIN_PG7 (at91_pin_t)199 -#define AT91_PIN_PG8 (at91_pin_t)200 -#define AT91_PIN_PG9 (at91_pin_t)201 -#define AT91_PIN_PG10 (at91_pin_t)202 -#define AT91_PIN_PG11 (at91_pin_t)203 -#define AT91_PIN_PG12 (at91_pin_t)204 -#define AT91_PIN_PG13 (at91_pin_t)205 -#define AT91_PIN_PG14 (at91_pin_t)206 -#define AT91_PIN_PG15 (at91_pin_t)207 -#define AT91_PIN_PG16 (at91_pin_t)208 -#define AT91_PIN_PG17 (at91_pin_t)209 -#define AT91_PIN_PG18 (at91_pin_t)210 -#define AT91_PIN_PG19 (at91_pin_t)211 -#define AT91_PIN_PG20 (at91_pin_t)212 -#define AT91_PIN_PG21 (at91_pin_t)213 -#define AT91_PIN_PG22 (at91_pin_t)214 -#define AT91_PIN_PG23 (at91_pin_t)215 -#define AT91_PIN_PG24 (at91_pin_t)216 -#define AT91_PIN_PG25 (at91_pin_t)217 -#define AT91_PIN_PG26 (at91_pin_t)218 -#define AT91_PIN_PG27 (at91_pin_t)219 -#define AT91_PIN_PG28 (at91_pin_t)220 -#define AT91_PIN_PG29 (at91_pin_t)221 -#define AT91_PIN_PG30 (at91_pin_t)222 -#define AT91_PIN_PG31 (at91_pin_t)223 -#define AT91_PIN_PH0 (at91_pin_t)224 -#define AT91_PIN_PH1 (at91_pin_t)225 -#define AT91_PIN_PH2 (at91_pin_t)226 -#define AT91_PIN_PH3 (at91_pin_t)227 -#define AT91_PIN_PH4 (at91_pin_t)228 -#define AT91_PIN_PH5 (at91_pin_t)229 -#define AT91_PIN_PH6 (at91_pin_t)230 -#define AT91_PIN_PH7 (at91_pin_t)231 -#define AT91_PIN_PH8 (at91_pin_t)232 -#define AT91_PIN_PH9 (at91_pin_t)233 -#define AT91_PIN_PH10 (at91_pin_t)234 -#define AT91_PIN_PH11 (at91_pin_t)235 -#define AT91_PIN_PH12 (at91_pin_t)236 -#define AT91_PIN_PH13 (at91_pin_t)237 -#define AT91_PIN_PH14 (at91_pin_t)238 -#define AT91_PIN_PH15 (at91_pin_t)239 -#define AT91_PIN_PH16 (at91_pin_t)240 -#define AT91_PIN_PH17 (at91_pin_t)241 -#define AT91_PIN_PH18 (at91_pin_t)242 -#define AT91_PIN_PH19 (at91_pin_t)243 -#define AT91_PIN_PH20 (at91_pin_t)244 -#define AT91_PIN_PH21 (at91_pin_t)245 -#define AT91_PIN_PH22 (at91_pin_t)246 -#define AT91_PIN_PH23 (at91_pin_t)247 -#define AT91_PIN_PH24 (at91_pin_t)248 -#define AT91_PIN_PH25 (at91_pin_t)249 -#define AT91_PIN_PH26 (at91_pin_t)250 -#define AT91_PIN_PH27 (at91_pin_t)251 -#define AT91_PIN_PH28 (at91_pin_t)252 -#define AT91_PIN_PH29 (at91_pin_t)253 -#define AT91_PIN_PH30 (at91_pin_t)254 -#define AT91_PIN_PH31 (at91_pin_t)255 - -#endif /* ARM_AT91_AT91_GPIO_H */ Index: head/sys/arm/at91/at91_machdep.c =================================================================== --- head/sys/arm/at91/at91_machdep.c +++ head/sys/arm/at91/at91_machdep.c @@ -1,689 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 1994-1998 Mark Brinicombe. - * Copyright (c) 1994 Brini. - * All rights reserved. - * - * This code is derived from software written for Brini by Mark Brinicombe - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Brini. - * 4. The name of the company nor the name of the author may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * RiscBSD kernel project - * - * machdep.c - * - * Machine dependent functions for kernel setup - * - * This file needs a lot of work. - * - * Created : 17/09/94 - */ - -#include "opt_kstack_pages.h" -#include "opt_platform.h" - -#include -__FBSDID("$FreeBSD$"); - -#define _ARM32_BUS_DMA_PRIVATE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifndef MAXCPU -#define MAXCPU 1 -#endif - -/* Page table for mapping proc0 zero page */ -#define KERNEL_PT_SYS 0 -#define KERNEL_PT_KERN 1 -#define KERNEL_PT_KERN_NUM 22 -/* L2 table for mapping after kernel */ -#define KERNEL_PT_AFKERNEL KERNEL_PT_KERN + KERNEL_PT_KERN_NUM -#define KERNEL_PT_AFKERNEL_NUM 5 - -/* this should be evenly divisable by PAGE_SIZE / L2_TABLE_SIZE_REAL (or 4) */ -#define NUM_KERNEL_PTS (KERNEL_PT_AFKERNEL + KERNEL_PT_AFKERNEL_NUM) - -struct pv_addr kernel_pt_table[NUM_KERNEL_PTS]; - -/* Static device mappings. */ -const struct devmap_entry at91_devmap[] = { - /* - * Map the critical on-board devices. The interrupt vector at - * 0xffff0000 makes it impossible to map them PA == VA, so we map all - * 0xfffxxxxx addresses to 0xdffxxxxx. This covers all critical devices - * on all members of the AT91SAM9 and AT91RM9200 families. - */ - { - 0xdff00000, - 0xfff00000, - 0x00100000, - }, - /* There's a notion that we should do the rest of these lazily. */ - /* - * We can't just map the OHCI registers VA == PA, because - * AT91xx_xxx_BASE belongs to the userland address space. - * We could just choose a different virtual address, but a better - * solution would probably be to just use pmap_mapdev() to allocate - * KVA, as we don't need the OHCI controller before the vm - * initialization is done. However, the AT91 resource allocation - * system doesn't know how to use pmap_mapdev() yet. - * Care must be taken to ensure PA and VM address do not overlap - * between entries. - */ - { - /* - * Add the ohci controller, and anything else that might be - * on this chip select for a VA/PA mapping. - */ - /* Internal Memory 1MB */ - AT91RM92_OHCI_VA_BASE, - AT91RM92_OHCI_BASE, - 0x00100000, - }, - { - /* CompactFlash controller. Portion of EBI CS4 1MB */ - AT91RM92_CF_VA_BASE, - AT91RM92_CF_BASE, - 0x00100000, - }, - /* - * The next two should be good for the 9260, 9261 and 9G20 since - * addresses mapping is the same. - */ - { - /* Internal Memory 1MB */ - AT91SAM9G20_OHCI_VA_BASE, - AT91SAM9G20_OHCI_BASE, - 0x00100000, - }, - { - /* EBI CS3 256MB */ - AT91SAM9G20_NAND_VA_BASE, - AT91SAM9G20_NAND_BASE, - AT91SAM9G20_NAND_SIZE, - }, - /* - * The next should be good for the 9G45. - */ - { - /* Internal Memory 1MB */ - AT91SAM9G45_OHCI_VA_BASE, - AT91SAM9G45_OHCI_BASE, - 0x00100000, - }, - { 0, 0, 0, } -}; - -#ifdef LINUX_BOOT_ABI -static int membanks; -static int memsize[]; -#endif - -long -at91_ramsize(void) -{ - uint32_t cr, mdr, mr, *SDRAMC; - int banks, rows, cols, bw; -#ifdef LINUX_BOOT_ABI - /* - * If we found any ATAGs that were for memory, return the first bank. - */ - if (membanks > 0) - return (memsize[0]); -#endif - - if (at91_is_rm92()) { - SDRAMC = (uint32_t *)(AT91_BASE + AT91RM92_SDRAMC_BASE); - cr = SDRAMC[AT91RM92_SDRAMC_CR / 4]; - mr = SDRAMC[AT91RM92_SDRAMC_MR / 4]; - banks = (cr & AT91RM92_SDRAMC_CR_NB_4) ? 2 : 1; - rows = ((cr & AT91RM92_SDRAMC_CR_NR_MASK) >> 2) + 11; - cols = (cr & AT91RM92_SDRAMC_CR_NC_MASK) + 8; - bw = (mr & AT91RM92_SDRAMC_MR_DBW_16) ? 1 : 2; - } else if (at91_cpu_is(AT91_T_SAM9G45)) { - SDRAMC = (uint32_t *)(AT91_BASE + AT91SAM9G45_DDRSDRC0_BASE); - cr = SDRAMC[AT91SAM9G45_DDRSDRC_CR / 4]; - mdr = SDRAMC[AT91SAM9G45_DDRSDRC_MDR / 4]; - banks = 0; - rows = ((cr & AT91SAM9G45_DDRSDRC_CR_NR_MASK) >> 2) + 11; - cols = (cr & AT91SAM9G45_DDRSDRC_CR_NC_MASK) + 8; - bw = (mdr & AT91SAM9G45_DDRSDRC_MDR_DBW_16) ? 1 : 2; - - /* Fix the calculation for DDR memory */ - mdr &= AT91SAM9G45_DDRSDRC_MDR_MASK; - if (mdr & AT91SAM9G45_DDRSDRC_MDR_LPDDR1 || - mdr & AT91SAM9G45_DDRSDRC_MDR_DDR2) { - /* The cols value is 1 higher for DDR */ - cols += 1; - /* DDR has 4 internal banks. */ - banks = 2; - } - } else { - /* - * This should be good for the 9260, 9261, 9G20, 9G35 and 9X25 - * as addresses and registers are the same. - */ - SDRAMC = (uint32_t *)(AT91_BASE + AT91SAM9G20_SDRAMC_BASE); - cr = SDRAMC[AT91SAM9G20_SDRAMC_CR / 4]; - mr = SDRAMC[AT91SAM9G20_SDRAMC_MR / 4]; - banks = (cr & AT91SAM9G20_SDRAMC_CR_NB_4) ? 2 : 1; - rows = ((cr & AT91SAM9G20_SDRAMC_CR_NR_MASK) >> 2) + 11; - cols = (cr & AT91SAM9G20_SDRAMC_CR_NC_MASK) + 8; - bw = (cr & AT91SAM9G20_SDRAMC_CR_DBW_16) ? 1 : 2; - } - - return (1 << (cols + rows + banks + bw)); -} - -static const char *soc_type_name[] = { - [AT91_T_CAP9] = "at91cap9", - [AT91_T_RM9200] = "at91rm9200", - [AT91_T_SAM9260] = "at91sam9260", - [AT91_T_SAM9261] = "at91sam9261", - [AT91_T_SAM9263] = "at91sam9263", - [AT91_T_SAM9G10] = "at91sam9g10", - [AT91_T_SAM9G20] = "at91sam9g20", - [AT91_T_SAM9G45] = "at91sam9g45", - [AT91_T_SAM9N12] = "at91sam9n12", - [AT91_T_SAM9RL] = "at91sam9rl", - [AT91_T_SAM9X5] = "at91sam9x5", - [AT91_T_NONE] = "UNKNOWN" -}; - -static const char *soc_subtype_name[] = { - [AT91_ST_NONE] = "UNKNOWN", - [AT91_ST_RM9200_BGA] = "at91rm9200_bga", - [AT91_ST_RM9200_PQFP] = "at91rm9200_pqfp", - [AT91_ST_SAM9XE] = "at91sam9xe", - [AT91_ST_SAM9G45] = "at91sam9g45", - [AT91_ST_SAM9M10] = "at91sam9m10", - [AT91_ST_SAM9G46] = "at91sam9g46", - [AT91_ST_SAM9M11] = "at91sam9m11", - [AT91_ST_SAM9G15] = "at91sam9g15", - [AT91_ST_SAM9G25] = "at91sam9g25", - [AT91_ST_SAM9G35] = "at91sam9g35", - [AT91_ST_SAM9X25] = "at91sam9x25", - [AT91_ST_SAM9X35] = "at91sam9x35", -}; - -struct at91_soc_info soc_info; - -/* - * Read the SoC ID from the CIDR register and try to match it against the - * values we know. If we find a good one, we return true. If not, we - * return false. When we find a good one, we also find the subtype - * and CPU family. - */ -static int -at91_try_id(uint32_t dbgu_base) -{ - uint32_t socid; - - soc_info.cidr = *(volatile uint32_t *)(AT91_BASE + dbgu_base + - DBGU_C1R); - socid = soc_info.cidr & ~AT91_CPU_VERSION_MASK; - - soc_info.type = AT91_T_NONE; - soc_info.subtype = AT91_ST_NONE; - soc_info.family = (soc_info.cidr & AT91_CPU_FAMILY_MASK) >> 20; - soc_info.exid = *(volatile uint32_t *)(AT91_BASE + dbgu_base + - DBGU_C2R); - - switch (socid) { - case AT91_CPU_CAP9: - soc_info.type = AT91_T_CAP9; - break; - case AT91_CPU_RM9200: - soc_info.type = AT91_T_RM9200; - break; - case AT91_CPU_SAM9XE128: - case AT91_CPU_SAM9XE256: - case AT91_CPU_SAM9XE512: - case AT91_CPU_SAM9260: - soc_info.type = AT91_T_SAM9260; - if (soc_info.family == AT91_FAMILY_SAM9XE) - soc_info.subtype = AT91_ST_SAM9XE; - break; - case AT91_CPU_SAM9261: - soc_info.type = AT91_T_SAM9261; - break; - case AT91_CPU_SAM9263: - soc_info.type = AT91_T_SAM9263; - break; - case AT91_CPU_SAM9G10: - soc_info.type = AT91_T_SAM9G10; - break; - case AT91_CPU_SAM9G20: - soc_info.type = AT91_T_SAM9G20; - break; - case AT91_CPU_SAM9G45: - soc_info.type = AT91_T_SAM9G45; - break; - case AT91_CPU_SAM9N12: - soc_info.type = AT91_T_SAM9N12; - break; - case AT91_CPU_SAM9RL64: - soc_info.type = AT91_T_SAM9RL; - break; - case AT91_CPU_SAM9X5: - soc_info.type = AT91_T_SAM9X5; - break; - default: - return (0); - } - - switch (soc_info.type) { - case AT91_T_SAM9G45: - switch (soc_info.exid) { - case AT91_EXID_SAM9G45: - soc_info.subtype = AT91_ST_SAM9G45; - break; - case AT91_EXID_SAM9G46: - soc_info.subtype = AT91_ST_SAM9G46; - break; - case AT91_EXID_SAM9M10: - soc_info.subtype = AT91_ST_SAM9M10; - break; - case AT91_EXID_SAM9M11: - soc_info.subtype = AT91_ST_SAM9M11; - break; - } - break; - case AT91_T_SAM9X5: - switch (soc_info.exid) { - case AT91_EXID_SAM9G15: - soc_info.subtype = AT91_ST_SAM9G15; - break; - case AT91_EXID_SAM9G25: - soc_info.subtype = AT91_ST_SAM9G25; - break; - case AT91_EXID_SAM9G35: - soc_info.subtype = AT91_ST_SAM9G35; - break; - case AT91_EXID_SAM9X25: - soc_info.subtype = AT91_ST_SAM9X25; - break; - case AT91_EXID_SAM9X35: - soc_info.subtype = AT91_ST_SAM9X35; - break; - } - break; - default: - break; - } - /* - * Disable interrupts in the DBGU unit... - */ - *(volatile uint32_t *)(AT91_BASE + dbgu_base + USART_IDR) = 0xffffffff; - - /* - * Save the name for later... - */ - snprintf(soc_info.name, sizeof(soc_info.name), "%s%s%s", - soc_type_name[soc_info.type], - soc_info.subtype == AT91_ST_NONE ? "" : " subtype ", - soc_info.subtype == AT91_ST_NONE ? "" : - soc_subtype_name[soc_info.subtype]); - - /* - * try to get the matching CPU support. - */ - soc_info.soc_data = at91_match_soc(soc_info.type, soc_info.subtype); - soc_info.dbgu_base = AT91_BASE + dbgu_base; - - return (1); -} - -void -at91_soc_id(void) -{ - - if (!at91_try_id(AT91_DBGU0)) - at91_try_id(AT91_DBGU1); -} - -#ifdef ARM_MANY_BOARD -/* likely belongs in arm/arm/machdep.c, but since board_init is still at91 only... */ -SET_DECLARE(arm_board_set, const struct arm_board); - -/* Not yet fully functional, but enough to build ATMEL config */ -static long -board_init(void) -{ - return -1; -} -#endif - -#ifndef FDT -/* Physical and virtual addresses for some global pages */ - -struct pv_addr msgbufpv; -struct pv_addr kernelstack; -struct pv_addr systempage; -struct pv_addr irqstack; -struct pv_addr abtstack; -struct pv_addr undstack; - -void * -initarm(struct arm_boot_params *abp) -{ - struct pv_addr kernel_l1pt; - struct pv_addr dpcpu; - int i; - u_int l1pagetable; - vm_offset_t freemempos; - vm_offset_t afterkern; - uint32_t memsize; - vm_offset_t lastaddr; - - lastaddr = parse_boot_param(abp); - arm_physmem_kernaddr = abp->abp_physaddr; - set_cpufuncs(); - pcpu0_init(); - - /* Do basic tuning, hz etc */ - init_param1(); - - freemempos = (lastaddr + PAGE_MASK) & ~PAGE_MASK; - /* Define a macro to simplify memory allocation */ -#define valloc_pages(var, np) \ - alloc_pages((var).pv_va, (np)); \ - (var).pv_pa = (var).pv_va + (abp->abp_physaddr - KERNVIRTADDR); - -#define alloc_pages(var, np) \ - (var) = freemempos; \ - freemempos += (np * PAGE_SIZE); \ - memset((char *)(var), 0, ((np) * PAGE_SIZE)); - - while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0) - freemempos += PAGE_SIZE; - valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE); - for (i = 0; i < NUM_KERNEL_PTS; ++i) { - if (!(i % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) { - valloc_pages(kernel_pt_table[i], - L2_TABLE_SIZE / PAGE_SIZE); - } else { - kernel_pt_table[i].pv_va = freemempos - - (i % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) * - L2_TABLE_SIZE_REAL; - kernel_pt_table[i].pv_pa = - kernel_pt_table[i].pv_va - KERNVIRTADDR + - abp->abp_physaddr; - } - } - /* - * Allocate a page for the system page mapped to 0x00000000 - * or 0xffff0000. This page will just contain the system vectors - * and can be shared by all processes. - */ - valloc_pages(systempage, 1); - - /* Allocate dynamic per-cpu area. */ - valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE); - dpcpu_init((void *)dpcpu.pv_va, 0); - - /* Allocate stacks for all modes */ - valloc_pages(irqstack, IRQ_STACK_SIZE * MAXCPU); - valloc_pages(abtstack, ABT_STACK_SIZE * MAXCPU); - valloc_pages(undstack, UND_STACK_SIZE * MAXCPU); - valloc_pages(kernelstack, kstack_pages * MAXCPU); - valloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE); - - /* - * Now we start construction of the L1 page table - * We start by mapping the L2 page tables into the L1. - * This means that we can replace L1 mappings later on if necessary - */ - l1pagetable = kernel_l1pt.pv_va; - - /* Map the L2 pages tables in the L1 page table */ - pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH, - &kernel_pt_table[KERNEL_PT_SYS]); - for (i = 0; i < KERNEL_PT_KERN_NUM; i++) - pmap_link_l2pt(l1pagetable, KERNBASE + i * L1_S_SIZE, - &kernel_pt_table[KERNEL_PT_KERN + i]); - pmap_map_chunk(l1pagetable, KERNBASE, PHYSADDR, - rounddown2(((uint32_t)lastaddr - KERNBASE) + PAGE_SIZE, PAGE_SIZE), - VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); - afterkern = round_page(rounddown2(lastaddr + L1_S_SIZE, L1_S_SIZE)); - for (i = 0; i < KERNEL_PT_AFKERNEL_NUM; i++) { - pmap_link_l2pt(l1pagetable, afterkern + i * L1_S_SIZE, - &kernel_pt_table[KERNEL_PT_AFKERNEL + i]); - } - - /* Map the vector page. */ - pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa, - VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); - - /* Map the DPCPU pages */ - pmap_map_chunk(l1pagetable, dpcpu.pv_va, dpcpu.pv_pa, DPCPU_SIZE, - VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); - - /* Map the stack pages */ - pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa, - IRQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); - pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa, - ABT_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); - pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa, - UND_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); - pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa, - kstack_pages * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); - - pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa, - L1_TABLE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE); - pmap_map_chunk(l1pagetable, msgbufpv.pv_va, msgbufpv.pv_pa, - msgbufsize, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); - - for (i = 0; i < NUM_KERNEL_PTS; ++i) { - pmap_map_chunk(l1pagetable, kernel_pt_table[i].pv_va, - kernel_pt_table[i].pv_pa, L2_TABLE_SIZE, - VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE); - } - - devmap_bootstrap(l1pagetable, at91_devmap); - cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) | DOMAIN_CLIENT); - cpu_setttb(kernel_l1pt.pv_pa); - cpu_tlb_flushID(); - cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)); - - at91_soc_id(); - - /* - * Initialize all the clocks, so that the console can work. We can only - * do this if at91_soc_id() was able to fill in the support data. Even - * if we can't init the clocks, still try to do a console init so we can - * try to print the error message about missing soc support. There's a - * chance the printf will work if the bootloader set up the DBGU. - */ - if (soc_info.soc_data != NULL) { - soc_info.soc_data->soc_clock_init(); - at91_pmc_init_clock(); - } - - cninit(); - - if (soc_info.soc_data == NULL) - printf("Warning: No soc support for %s found.\n", soc_info.name); - - memsize = board_init(); - if (memsize == -1) { - printf("board_init() failed, cannot determine ram size; " - "assuming 16MB\n"); - memsize = 16 * 1024 * 1024; - } - - /* Enable MMU (set SCTLR), and do other cpu-specific setup. */ - cpu_control(CPU_CONTROL_MMU_ENABLE, CPU_CONTROL_MMU_ENABLE); - cpu_setup(); - - /* - * Pages were allocated during the secondary bootstrap for the - * stacks for different CPU modes. - * We must now set the r13 registers in the different CPU modes to - * point to these stacks. - * Since the ARM stacks use STMFD etc. we must set r13 to the top end - * of the stack memory. - */ - set_stackptrs(0); - - /* - * We must now clean the cache again.... - * Cleaning may be done by reading new data to displace any - * dirty data in the cache. This will have happened in cpu_setttb() - * but since we are boot strapping the addresses used for the read - * may have just been remapped and thus the cache could be out - * of sync. A re-clean after the switch will cure this. - * After booting there are no gross relocations of the kernel thus - * this problem will not occur after initarm(). - */ - cpu_idcache_wbinv_all(); - - undefined_init(); - - init_proc0(kernelstack.pv_va); - - arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL); - - pmap_curmaxkvaddr = afterkern + L1_S_SIZE * (KERNEL_PT_KERN_NUM - 1); - /* Always use the 256MB of KVA we have available between the kernel and devices */ - vm_max_kernel_address = KERNVIRTADDR + (256 << 20); - pmap_bootstrap(freemempos, &kernel_l1pt); - msgbufp = (void*)msgbufpv.pv_va; - msgbufinit(msgbufp, msgbufsize); - mutex_init(); - - /* - * Add the physical ram we have available. - * - * Exclude the kernel, and all the things we allocated which immediately - * follow the kernel, from the VM allocation pool but not from crash - * dumps. virtual_avail is a global variable which tracks the kva we've - * "allocated" while setting up pmaps. - * - * Prepare the list of physical memory available to the vm subsystem. - */ - arm_physmem_hardware_region(PHYSADDR, memsize); - arm_physmem_exclude_region(abp->abp_physaddr, - virtual_avail - KERNVIRTADDR, EXFLAG_NOALLOC); - arm_physmem_init_kernel_globals(); - - init_param2(physmem); - kdb_init(); - return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP - - sizeof(struct pcb))); -} -#endif - -/* - * These functions are handled elsewhere, so make them nops here. - */ -void -cpu_startprofclock(void) -{ - -} - -void -cpu_stopprofclock(void) -{ - -} - -void -cpu_initclocks(void) -{ - -} - -void -DELAY(int n) -{ - - TSENTER(); - if (soc_info.soc_data) - soc_info.soc_data->soc_delay(n); - TSEXIT(); -} - -void -cpu_reset(void) -{ - - if (soc_info.soc_data) - soc_info.soc_data->soc_reset(); - while (1) - continue; -} Index: head/sys/arm/at91/at91_mci.c =================================================================== --- head/sys/arm/at91/at91_mci.c +++ head/sys/arm/at91/at91_mci.c @@ -1,1406 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2006 Bernd Walter. All rights reserved. - * Copyright (c) 2006 M. Warner Losh. - * Copyright (c) 2010 Greg Ansley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "opt_platform.h" - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include - -#ifdef FDT -#include -#include -#endif - -#include "mmcbr_if.h" - -#include "opt_at91.h" - -/* - * About running the MCI bus above 25MHz - * - * Historically, the MCI bus has been run at 30MHz on systems with a 60MHz - * master clock, in part due to a bug in dev/mmc.c making always request - * 30MHz, and in part over clocking the bus because 15MHz was too slow. - * Fixing that bug causes the mmc driver to request a 25MHz clock (as it - * should) and the logic in at91_mci_update_ios() picks the highest speed that - * doesn't exceed that limit. With a 60MHz MCK that would be 15MHz, and - * that's a real performance buzzkill when you've been getting away with 30MHz - * all along. - * - * By defining AT91_MCI_ALLOW_OVERCLOCK (or setting the allow_overclock=1 - * device hint or sysctl) you can enable logic in at91_mci_update_ios() to - * overlcock the SD bus a little by running it at MCK / 2 when the requested - * speed is 25MHz and the next highest speed is 15MHz or less. This appears - * to work on virtually all SD cards, since it is what this driver has been - * doing prior to the introduction of this option, where the overclocking vs - * underclocking decision was automatically "overclock". Modern SD cards can - * run at 45mhz/1-bit in standard mode (high speed mode enable commands not - * sent) without problems. - * - * Speaking of high-speed mode, the rm9200 manual says the MCI device supports - * the SD v1.0 specification and can run up to 50MHz. This is interesting in - * that the SD v1.0 spec caps the speed at 25MHz; high speed mode was added in - * the v1.10 spec. Furthermore, high speed mode doesn't just crank up the - * clock, it alters the signal timing. The rm9200 MCI device doesn't support - * these altered timings. So while speeds over 25MHz may work, they only work - * in what the SD spec calls "default" speed mode, and it amounts to violating - * the spec by overclocking the bus. - * - * If you also enable 4-wire mode it's possible transfers faster than 25MHz - * will fail. On the AT91RM9200, due to bugs in the bus contention logic, if - * you have the USB host device and OHCI driver enabled will fail. Even - * underclocking to 15MHz, intermittant overrun and underrun errors occur. - * Note that you don't even need to have usb devices attached to the system, - * the errors begin to occur as soon as the OHCI driver sets the register bit - * to enable periodic transfers. It appears (based on brief investigation) - * that the usb host controller uses so much ASB bandwidth that sometimes the - * DMA for MCI transfers doesn't get a bus grant in time and data gets - * dropped. Adding even a modicum of network activity changes the symptom - * from intermittant to very frequent. Members of the AT91SAM9 family have - * corrected this problem, or are at least better about their use of the bus. - */ -#ifndef AT91_MCI_ALLOW_OVERCLOCK -#define AT91_MCI_ALLOW_OVERCLOCK 1 -#endif - -/* - * Allocate 2 bounce buffers we'll use to endian-swap the data due to the rm9200 - * erratum. We use a pair of buffers because when reading that lets us begin - * endian-swapping the data in the first buffer while the DMA is reading into - * the second buffer. (We can't use the same trick for writing because we might - * not get all the data in the 2nd buffer swapped before the hardware needs it; - * dealing with that would add complexity to the driver.) - * - * The buffers are sized at 16K each due to the way the busdma cache sync - * operations work on arm. A dcache_inv_range() operation on a range larger - * than 16K gets turned into a dcache_wbinv_all(). That needlessly flushes the - * entire data cache, impacting overall system performance. - */ -#define BBCOUNT 2 -#define BBSIZE (16*1024) -#define MAX_BLOCKS ((BBSIZE*BBCOUNT)/512) - -static int mci_debug; - -struct at91_mci_softc { - void *intrhand; /* Interrupt handle */ - device_t dev; - int sc_cap; -#define CAP_HAS_4WIRE 1 /* Has 4 wire bus */ -#define CAP_NEEDS_BYTESWAP 2 /* broken hardware needing bounce */ -#define CAP_MCI1_REV2XX 4 /* MCI 1 rev 2.x */ - int flags; -#define PENDING_CMD 0x01 -#define PENDING_STOP 0x02 -#define CMD_MULTIREAD 0x10 -#define CMD_MULTIWRITE 0x20 - int has_4wire; - int allow_overclock; - struct resource *irq_res; /* IRQ resource */ - struct resource *mem_res; /* Memory resource */ - struct mtx sc_mtx; - bus_dma_tag_t dmatag; - struct mmc_host host; - int bus_busy; - struct mmc_request *req; - struct mmc_command *curcmd; - bus_dmamap_t bbuf_map[BBCOUNT]; - char * bbuf_vaddr[BBCOUNT]; /* bounce bufs in KVA space */ - uint32_t bbuf_len[BBCOUNT]; /* len currently queued for bounce buf */ - uint32_t bbuf_curidx; /* which bbuf is the active DMA buffer */ - uint32_t xfer_offset; /* offset so far into caller's buf */ -}; - -/* bus entry points */ -static int at91_mci_probe(device_t dev); -static int at91_mci_attach(device_t dev); -static int at91_mci_detach(device_t dev); -static void at91_mci_intr(void *); - -/* helper routines */ -static int at91_mci_activate(device_t dev); -static void at91_mci_deactivate(device_t dev); -static int at91_mci_is_mci1rev2xx(void); - -#define AT91_MCI_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) -#define AT91_MCI_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) -#define AT91_MCI_LOCK_INIT(_sc) \ - mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \ - "mci", MTX_DEF) -#define AT91_MCI_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); -#define AT91_MCI_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED); -#define AT91_MCI_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); - -static inline uint32_t -RD4(struct at91_mci_softc *sc, bus_size_t off) -{ - return (bus_read_4(sc->mem_res, off)); -} - -static inline void -WR4(struct at91_mci_softc *sc, bus_size_t off, uint32_t val) -{ - bus_write_4(sc->mem_res, off, val); -} - -static void -at91_bswap_buf(struct at91_mci_softc *sc, void * dptr, void * sptr, uint32_t memsize) -{ - uint32_t * dst = (uint32_t *)dptr; - uint32_t * src = (uint32_t *)sptr; - uint32_t i; - - /* - * If the hardware doesn't need byte-swapping, let bcopy() do the - * work. Use bounce buffer even if we don't need byteswap, since - * buffer may straddle a page boundary, and we don't handle - * multi-segment transfers in hardware. Seen from 'bsdlabel -w' which - * uses raw geom access to the volume. Greg Ansley (gja (at) - * ansley.com) - */ - if (!(sc->sc_cap & CAP_NEEDS_BYTESWAP)) { - memcpy(dptr, sptr, memsize); - return; - } - - /* - * Nice performance boost for slightly unrolling this loop. - * (But very little extra boost for further unrolling it.) - */ - for (i = 0; i < memsize; i += 16) { - *dst++ = bswap32(*src++); - *dst++ = bswap32(*src++); - *dst++ = bswap32(*src++); - *dst++ = bswap32(*src++); - } - - /* Mop up the last 1-3 words, if any. */ - for (i = 0; i < (memsize & 0x0F); i += 4) { - *dst++ = bswap32(*src++); - } -} - -static void -at91_mci_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error) -{ - if (error != 0) - return; - *(bus_addr_t *)arg = segs[0].ds_addr; -} - -static void -at91_mci_pdc_disable(struct at91_mci_softc *sc) -{ - WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS); - WR4(sc, PDC_RPR, 0); - WR4(sc, PDC_RCR, 0); - WR4(sc, PDC_RNPR, 0); - WR4(sc, PDC_RNCR, 0); - WR4(sc, PDC_TPR, 0); - WR4(sc, PDC_TCR, 0); - WR4(sc, PDC_TNPR, 0); - WR4(sc, PDC_TNCR, 0); -} - -/* - * Reset the controller, then restore most of the current state. - * - * This is called after detecting an error. It's also called after stopping a - * multi-block write, to un-wedge the device so that it will handle the NOTBUSY - * signal correctly. See comments in at91_mci_stop_done() for more details. - */ -static void at91_mci_reset(struct at91_mci_softc *sc) -{ - uint32_t mr; - uint32_t sdcr; - uint32_t dtor; - uint32_t imr; - - at91_mci_pdc_disable(sc); - - /* save current state */ - - imr = RD4(sc, MCI_IMR); - mr = RD4(sc, MCI_MR) & 0x7fff; - sdcr = RD4(sc, MCI_SDCR); - dtor = RD4(sc, MCI_DTOR); - - /* reset the controller */ - - WR4(sc, MCI_IDR, 0xffffffff); - WR4(sc, MCI_CR, MCI_CR_MCIDIS | MCI_CR_SWRST); - - /* restore state */ - - WR4(sc, MCI_CR, MCI_CR_MCIEN|MCI_CR_PWSEN); - WR4(sc, MCI_MR, mr); - WR4(sc, MCI_SDCR, sdcr); - WR4(sc, MCI_DTOR, dtor); - WR4(sc, MCI_IER, imr); - - /* - * Make sure sdio interrupts will fire. Not sure why reading - * SR ensures that, but this is in the linux driver. - */ - - RD4(sc, MCI_SR); -} - -static void -at91_mci_init(device_t dev) -{ - struct at91_mci_softc *sc = device_get_softc(dev); - uint32_t val; - - WR4(sc, MCI_CR, MCI_CR_MCIDIS | MCI_CR_SWRST); /* device into reset */ - WR4(sc, MCI_IDR, 0xffffffff); /* Turn off interrupts */ - WR4(sc, MCI_DTOR, MCI_DTOR_DTOMUL_1M | 1); - val = MCI_MR_PDCMODE; - val |= 0x34a; /* PWSDIV = 3; CLKDIV = 74 */ -// if (sc->sc_cap & CAP_MCI1_REV2XX) -// val |= MCI_MR_RDPROOF | MCI_MR_WRPROOF; - WR4(sc, MCI_MR, val); -#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 - /* - * Enable controller, including power-save. The slower clock - * of the power-save mode is only in effect when there is no - * transfer in progress, so it can be left in this mode all - * the time. - */ - WR4(sc, MCI_CR, MCI_CR_MCIEN|MCI_CR_PWSEN); -} - -static void -at91_mci_fini(device_t dev) -{ - struct at91_mci_softc *sc = device_get_softc(dev); - - WR4(sc, MCI_IDR, 0xffffffff); /* Turn off interrupts */ - at91_mci_pdc_disable(sc); - WR4(sc, MCI_CR, MCI_CR_MCIDIS | MCI_CR_SWRST); /* device into reset */ -} - -static int -at91_mci_probe(device_t dev) -{ -#ifdef FDT - if (!ofw_bus_is_compatible(dev, "atmel,hsmci")) - return (ENXIO); -#endif - device_set_desc(dev, "MCI mmc/sd host bridge"); - return (0); -} - -static int -at91_mci_attach(device_t dev) -{ - struct at91_mci_softc *sc = device_get_softc(dev); - struct sysctl_ctx_list *sctx; - struct sysctl_oid *soid; - device_t child; - int err, i; - - sctx = device_get_sysctl_ctx(dev); - soid = device_get_sysctl_tree(dev); - - sc->dev = dev; - sc->sc_cap = 0; - if (at91_is_rm92()) - sc->sc_cap |= CAP_NEEDS_BYTESWAP; - /* - * MCI1 Rev 2 controllers need some workarounds, flag if so. - */ - if (at91_mci_is_mci1rev2xx()) - sc->sc_cap |= CAP_MCI1_REV2XX; - - err = at91_mci_activate(dev); - if (err) - goto out; - - AT91_MCI_LOCK_INIT(sc); - - at91_mci_fini(dev); - at91_mci_init(dev); - - /* - * Allocate DMA tags and maps and bounce buffers. - * - * The parms in the tag_create call cause the dmamem_alloc call to - * create each bounce buffer as a single contiguous buffer of BBSIZE - * bytes aligned to a 4096 byte boundary. - * - * Do not use DMA_COHERENT for these buffers because that maps the - * memory as non-cachable, which prevents cache line burst fills/writes, - * which is something we need since we're trying to overlap the - * byte-swapping with the DMA operations. - */ - err = bus_dma_tag_create(bus_get_dma_tag(dev), 4096, 0, - BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, - BBSIZE, 1, BBSIZE, 0, NULL, NULL, &sc->dmatag); - if (err != 0) - goto out; - - for (i = 0; i < BBCOUNT; ++i) { - err = bus_dmamem_alloc(sc->dmatag, (void **)&sc->bbuf_vaddr[i], - BUS_DMA_NOWAIT, &sc->bbuf_map[i]); - if (err != 0) - goto out; - } - - /* - * Activate the interrupt - */ - err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, - NULL, at91_mci_intr, sc, &sc->intrhand); - if (err) { - AT91_MCI_LOCK_DESTROY(sc); - goto out; - } - - /* - * Allow 4-wire to be initially set via #define. - * Allow a device hint to override that. - * Allow a sysctl to override that. - */ -#if defined(AT91_MCI_HAS_4WIRE) && AT91_MCI_HAS_4WIRE != 0 - sc->has_4wire = 1; -#endif - resource_int_value(device_get_name(dev), device_get_unit(dev), - "4wire", &sc->has_4wire); - SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "4wire", - CTLFLAG_RW, &sc->has_4wire, 0, "has 4 wire SD Card bus"); - if (sc->has_4wire) - sc->sc_cap |= CAP_HAS_4WIRE; - - sc->allow_overclock = AT91_MCI_ALLOW_OVERCLOCK; - resource_int_value(device_get_name(dev), device_get_unit(dev), - "allow_overclock", &sc->allow_overclock); - SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "allow_overclock", - CTLFLAG_RW, &sc->allow_overclock, 0, - "Allow up to 30MHz clock for 25MHz request when next highest speed 15MHz or less."); - - SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "debug", - CTLFLAG_RWTUN, &mci_debug, 0, "enable debug output"); - - /* - * Our real min freq is master_clock/512, but upper driver layers are - * going to set the min speed during card discovery, and the right speed - * for that is 400kHz, so advertise a safe value just under that. - * - * For max speed, while the rm9200 manual says the max is 50mhz, it also - * says it supports only the SD v1.0 spec, which means the real limit is - * 25mhz. On the other hand, historical use has been to slightly violate - * the standard by running the bus at 30MHz. For more information on - * that, see the comments at the top of this file. - */ - sc->host.f_min = 375000; - sc->host.f_max = at91_master_clock / 2; - if (sc->host.f_max > 25000000) - sc->host.f_max = 25000000; - 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; - - child = device_add_child(dev, "mmc", 0); - device_set_ivars(dev, &sc->host); - err = bus_generic_attach(dev); -out: - if (err) - at91_mci_deactivate(dev); - return (err); -} - -static int -at91_mci_detach(device_t dev) -{ - struct at91_mci_softc *sc = device_get_softc(dev); - - at91_mci_fini(dev); - at91_mci_deactivate(dev); - - bus_dmamem_free(sc->dmatag, sc->bbuf_vaddr[0], sc->bbuf_map[0]); - bus_dmamem_free(sc->dmatag, sc->bbuf_vaddr[1], sc->bbuf_map[1]); - bus_dma_tag_destroy(sc->dmatag); - - return (EBUSY); /* XXX */ -} - -static int -at91_mci_activate(device_t dev) -{ - struct at91_mci_softc *sc; - int rid; - - sc = device_get_softc(dev); - rid = 0; - sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - if (sc->mem_res == NULL) - goto errout; - - rid = 0; - sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_ACTIVE); - if (sc->irq_res == NULL) - goto errout; - - return (0); -errout: - at91_mci_deactivate(dev); - return (ENOMEM); -} - -static void -at91_mci_deactivate(device_t dev) -{ - struct at91_mci_softc *sc; - - sc = device_get_softc(dev); - if (sc->intrhand) - bus_teardown_intr(dev, sc->irq_res, sc->intrhand); - sc->intrhand = NULL; - bus_generic_detach(sc->dev); - if (sc->mem_res) - bus_release_resource(dev, SYS_RES_MEMORY, - rman_get_rid(sc->mem_res), sc->mem_res); - sc->mem_res = NULL; - if (sc->irq_res) - bus_release_resource(dev, SYS_RES_IRQ, - rman_get_rid(sc->irq_res), sc->irq_res); - sc->irq_res = NULL; - return; -} - -static int -at91_mci_is_mci1rev2xx(void) -{ - - switch (soc_info.type) { - case AT91_T_SAM9260: - case AT91_T_SAM9263: - case AT91_T_CAP9: - case AT91_T_SAM9G10: - case AT91_T_SAM9G20: - case AT91_T_SAM9RL: - return(1); - default: - return (0); - } -} - -static int -at91_mci_update_ios(device_t brdev, device_t reqdev) -{ - struct at91_mci_softc *sc; - struct mmc_ios *ios; - uint32_t clkdiv; - uint32_t freq; - - sc = device_get_softc(brdev); - ios = &sc->host.ios; - - /* - * Calculate our closest available clock speed that doesn't exceed the - * requested speed. - * - * When overclocking is allowed, the requested clock is 25MHz, the - * computed frequency is 15MHz or smaller and clockdiv is 1, use - * clockdiv of 0 to double that. If less than 12.5MHz, double - * regardless of the overclocking setting. - * - * Whatever we come up with, store it back into ios->clock so that the - * upper layer drivers can report the actual speed of the bus. - */ - if (ios->clock == 0) { - WR4(sc, MCI_CR, MCI_CR_MCIDIS); - clkdiv = 0; - } else { - WR4(sc, MCI_CR, MCI_CR_MCIEN|MCI_CR_PWSEN); - if ((at91_master_clock % (ios->clock * 2)) == 0) - clkdiv = ((at91_master_clock / ios->clock) / 2) - 1; - else - clkdiv = (at91_master_clock / ios->clock) / 2; - freq = at91_master_clock / ((clkdiv+1) * 2); - if (clkdiv == 1 && ios->clock == 25000000 && freq <= 15000000) { - if (sc->allow_overclock || freq <= 12500000) { - clkdiv = 0; - freq = at91_master_clock / ((clkdiv+1) * 2); - } - } - ios->clock = freq; - } - if (ios->bus_width == bus_width_4) - WR4(sc, MCI_SDCR, RD4(sc, MCI_SDCR) | MCI_SDCR_SDCBUS); - else - WR4(sc, MCI_SDCR, RD4(sc, MCI_SDCR) & ~MCI_SDCR_SDCBUS); - WR4(sc, MCI_MR, (RD4(sc, MCI_MR) & ~MCI_MR_CLKDIV) | clkdiv); - /* Do we need a settle time here? */ - /* XXX We need to turn the device on/off here with a GPIO pin */ - return (0); -} - -static void -at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd) -{ - uint32_t cmdr, mr; - struct mmc_data *data; - - sc->curcmd = cmd; - data = cmd->data; - - /* XXX Upper layers don't always set this */ - cmd->mrq = sc->req; - - /* Begin setting up command register. */ - - cmdr = cmd->opcode; - - if (sc->host.ios.bus_mode == opendrain) - cmdr |= MCI_CMDR_OPDCMD; - - /* Set up response handling. Allow max timeout for responses. */ - - if (MMC_RSP(cmd->flags) == MMC_RSP_NONE) - cmdr |= MCI_CMDR_RSPTYP_NO; - else { - cmdr |= MCI_CMDR_MAXLAT; - if (cmd->flags & MMC_RSP_136) - cmdr |= MCI_CMDR_RSPTYP_136; - else - cmdr |= MCI_CMDR_RSPTYP_48; - } - - /* - * If there is no data transfer, just set up the right interrupt mask - * and start the command. - * - * The interrupt mask needs to be CMDRDY plus all non-data-transfer - * errors. It's important to leave the transfer-related errors out, to - * avoid spurious timeout or crc errors on a STOP command following a - * multiblock read. When a multiblock read is in progress, sending a - * STOP in the middle of a block occasionally triggers such errors, but - * we're totally disinterested in them because we've already gotten all - * the data we wanted without error before sending the STOP command. - */ - - if (data == NULL) { - uint32_t ier = MCI_SR_CMDRDY | - MCI_SR_RTOE | MCI_SR_RENDE | - MCI_SR_RCRCE | MCI_SR_RDIRE | MCI_SR_RINDE; - - at91_mci_pdc_disable(sc); - - if (cmd->opcode == MMC_STOP_TRANSMISSION) - cmdr |= MCI_CMDR_TRCMD_STOP; - - /* Ignore response CRC on CMD2 and ACMD41, per standard. */ - - if (cmd->opcode == MMC_SEND_OP_COND || - cmd->opcode == ACMD_SD_SEND_OP_COND) - ier &= ~MCI_SR_RCRCE; - - if (mci_debug) - printf("CMDR %x (opcode %d) ARGR %x no data\n", - cmdr, cmd->opcode, cmd->arg); - - WR4(sc, MCI_ARGR, cmd->arg); - WR4(sc, MCI_CMDR, cmdr); - WR4(sc, MCI_IDR, 0xffffffff); - WR4(sc, MCI_IER, ier); - return; - } - - /* There is data, set up the transfer-related parts of the command. */ - - if (data->flags & MMC_DATA_READ) - cmdr |= MCI_CMDR_TRDIR; - - if (data->flags & (MMC_DATA_READ | MMC_DATA_WRITE)) - cmdr |= MCI_CMDR_TRCMD_START; - - if (data->flags & MMC_DATA_STREAM) - cmdr |= MCI_CMDR_TRTYP_STREAM; - else if (data->flags & MMC_DATA_MULTI) { - cmdr |= MCI_CMDR_TRTYP_MULTIPLE; - sc->flags |= (data->flags & MMC_DATA_READ) ? - CMD_MULTIREAD : CMD_MULTIWRITE; - } - - /* - * Disable PDC until we're ready. - * - * Set block size and turn on PDC mode for dma xfer. - * Note that the block size is the smaller of the amount of data to be - * transferred, or 512 bytes. The 512 size is fixed by the standard; - * smaller blocks are possible, but never larger. - */ - - WR4(sc, PDC_PTCR, PDC_PTCR_RXTDIS | PDC_PTCR_TXTDIS); - - mr = RD4(sc,MCI_MR) & ~MCI_MR_BLKLEN; - mr |= min(data->len, 512) << 16; - WR4(sc, MCI_MR, mr | MCI_MR_PDCMODE|MCI_MR_PDCPADV); - - /* - * Set up DMA. - * - * Use bounce buffers even if we don't need to byteswap, because doing - * multi-block IO with large DMA buffers is way fast (compared to - * single-block IO), even after incurring the overhead of also copying - * from/to the caller's buffers (which may be in non-contiguous physical - * pages). - * - * In an ideal non-byteswap world we could create a dma tag that allows - * for discontiguous segments and do the IO directly from/to the - * caller's buffer(s), using ENDRX/ENDTX interrupts to chain the - * discontiguous buffers through the PDC. Someday. - * - * If a read is bigger than 2k, split it in half so that we can start - * byte-swapping the first half while the second half is on the wire. - * It would be best if we could split it into 8k chunks, but we can't - * always keep up with the byte-swapping due to other system activity, - * and if an RXBUFF interrupt happens while we're still handling the - * byte-swap from the prior buffer (IE, we haven't returned from - * handling the prior interrupt yet), then data will get dropped on the - * floor and we can't easily recover from that. The right fix for that - * would be to have the interrupt handling only keep the DMA flowing and - * enqueue filled buffers to be byte-swapped in a non-interrupt context. - * Even that won't work on the write side of things though; in that - * context we have to have all the data ready to go before starting the - * dma. - * - * XXX what about stream transfers? - */ - sc->xfer_offset = 0; - sc->bbuf_curidx = 0; - - if (data->flags & (MMC_DATA_READ | MMC_DATA_WRITE)) { - uint32_t len; - uint32_t remaining = data->len; - bus_addr_t paddr; - int err; - - if (remaining > (BBCOUNT*BBSIZE)) - panic("IO read size exceeds MAXDATA\n"); - - if (data->flags & MMC_DATA_READ) { - if (remaining > 2048) // XXX - len = remaining / 2; - else - len = remaining; - err = bus_dmamap_load(sc->dmatag, sc->bbuf_map[0], - sc->bbuf_vaddr[0], len, at91_mci_getaddr, - &paddr, BUS_DMA_NOWAIT); - if (err != 0) - panic("IO read dmamap_load failed\n"); - bus_dmamap_sync(sc->dmatag, sc->bbuf_map[0], - BUS_DMASYNC_PREREAD); - WR4(sc, PDC_RPR, paddr); - WR4(sc, PDC_RCR, len / 4); - sc->bbuf_len[0] = len; - remaining -= len; - if (remaining == 0) { - sc->bbuf_len[1] = 0; - } else { - len = remaining; - err = bus_dmamap_load(sc->dmatag, sc->bbuf_map[1], - sc->bbuf_vaddr[1], len, at91_mci_getaddr, - &paddr, BUS_DMA_NOWAIT); - if (err != 0) - panic("IO read dmamap_load failed\n"); - bus_dmamap_sync(sc->dmatag, sc->bbuf_map[1], - BUS_DMASYNC_PREREAD); - WR4(sc, PDC_RNPR, paddr); - WR4(sc, PDC_RNCR, len / 4); - sc->bbuf_len[1] = len; - remaining -= len; - } - WR4(sc, PDC_PTCR, PDC_PTCR_RXTEN); - } else { - len = min(BBSIZE, remaining); - at91_bswap_buf(sc, sc->bbuf_vaddr[0], data->data, len); - err = bus_dmamap_load(sc->dmatag, sc->bbuf_map[0], - sc->bbuf_vaddr[0], len, at91_mci_getaddr, - &paddr, BUS_DMA_NOWAIT); - if (err != 0) - panic("IO write dmamap_load failed\n"); - bus_dmamap_sync(sc->dmatag, sc->bbuf_map[0], - BUS_DMASYNC_PREWRITE); - /* - * Erratum workaround: PDC transfer length on a write - * must not be smaller than 12 bytes (3 words); only - * blklen bytes (set above) are actually transferred. - */ - WR4(sc, PDC_TPR,paddr); - WR4(sc, PDC_TCR, (len < 12) ? 3 : len / 4); - sc->bbuf_len[0] = len; - remaining -= len; - if (remaining == 0) { - sc->bbuf_len[1] = 0; - } else { - len = remaining; - at91_bswap_buf(sc, sc->bbuf_vaddr[1], - ((char *)data->data)+BBSIZE, len); - err = bus_dmamap_load(sc->dmatag, sc->bbuf_map[1], - sc->bbuf_vaddr[1], len, at91_mci_getaddr, - &paddr, BUS_DMA_NOWAIT); - if (err != 0) - panic("IO write dmamap_load failed\n"); - bus_dmamap_sync(sc->dmatag, sc->bbuf_map[1], - BUS_DMASYNC_PREWRITE); - WR4(sc, PDC_TNPR, paddr); - WR4(sc, PDC_TNCR, (len < 12) ? 3 : len / 4); - sc->bbuf_len[1] = len; - remaining -= len; - } - /* do not enable PDC xfer until CMDRDY asserted */ - } - data->xfer_len = 0; /* XXX what's this? appears to be unused. */ - } - - if (mci_debug) - printf("CMDR %x (opcode %d) ARGR %x with data len %d\n", - cmdr, cmd->opcode, cmd->arg, cmd->data->len); - - WR4(sc, MCI_ARGR, cmd->arg); - WR4(sc, MCI_CMDR, cmdr); - WR4(sc, MCI_IER, MCI_SR_ERROR | MCI_SR_CMDRDY); -} - -static void -at91_mci_next_operation(struct at91_mci_softc *sc) -{ - struct mmc_request *req; - - req = sc->req; - if (req == NULL) - return; - - if (sc->flags & PENDING_CMD) { - sc->flags &= ~PENDING_CMD; - at91_mci_start_cmd(sc, req->cmd); - return; - } else if (sc->flags & PENDING_STOP) { - sc->flags &= ~PENDING_STOP; - at91_mci_start_cmd(sc, req->stop); - return; - } - - WR4(sc, MCI_IDR, 0xffffffff); - sc->req = NULL; - sc->curcmd = NULL; - //printf("req done\n"); - req->done(req); -} - -static int -at91_mci_request(device_t brdev, device_t reqdev, struct mmc_request *req) -{ - struct at91_mci_softc *sc = device_get_softc(brdev); - - AT91_MCI_LOCK(sc); - if (sc->req != NULL) { - AT91_MCI_UNLOCK(sc); - return (EBUSY); - } - //printf("new req\n"); - sc->req = req; - sc->flags = PENDING_CMD; - if (sc->req->stop) - sc->flags |= PENDING_STOP; - at91_mci_next_operation(sc); - AT91_MCI_UNLOCK(sc); - return (0); -} - -static int -at91_mci_get_ro(device_t brdev, device_t reqdev) -{ - return (0); -} - -static int -at91_mci_acquire_host(device_t brdev, device_t reqdev) -{ - struct at91_mci_softc *sc = device_get_softc(brdev); - int err = 0; - - AT91_MCI_LOCK(sc); - while (sc->bus_busy) - msleep(sc, &sc->sc_mtx, PZERO, "mciah", hz / 5); - sc->bus_busy++; - AT91_MCI_UNLOCK(sc); - return (err); -} - -static int -at91_mci_release_host(device_t brdev, device_t reqdev) -{ - struct at91_mci_softc *sc = device_get_softc(brdev); - - AT91_MCI_LOCK(sc); - sc->bus_busy--; - wakeup(sc); - AT91_MCI_UNLOCK(sc); - return (0); -} - -static void -at91_mci_read_done(struct at91_mci_softc *sc, uint32_t sr) -{ - struct mmc_command *cmd = sc->curcmd; - char * dataptr = (char *)cmd->data->data; - uint32_t curidx = sc->bbuf_curidx; - uint32_t len = sc->bbuf_len[curidx]; - - /* - * We arrive here when a DMA transfer for a read is done, whether it's - * a single or multi-block read. - * - * We byte-swap the buffer that just completed, and if that is the - * last buffer that's part of this read then we move on to the next - * operation, otherwise we wait for another ENDRX for the next bufer. - */ - - bus_dmamap_sync(sc->dmatag, sc->bbuf_map[curidx], BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(sc->dmatag, sc->bbuf_map[curidx]); - - at91_bswap_buf(sc, dataptr + sc->xfer_offset, sc->bbuf_vaddr[curidx], len); - - if (mci_debug) { - printf("read done sr %x curidx %d len %d xfer_offset %d\n", - sr, curidx, len, sc->xfer_offset); - } - - sc->xfer_offset += len; - sc->bbuf_curidx = !curidx; /* swap buffers */ - - /* - * If we've transferred all the data, move on to the next operation. - * - * If we're still transferring the last buffer, RNCR is already zero but - * we have to write a zero anyway to clear the ENDRX status so we don't - * re-interrupt until the last buffer is done. - */ - if (sc->xfer_offset == cmd->data->len) { - WR4(sc, PDC_PTCR, PDC_PTCR_RXTDIS | PDC_PTCR_TXTDIS); - cmd->error = MMC_ERR_NONE; - at91_mci_next_operation(sc); - } else { - WR4(sc, PDC_RNCR, 0); - WR4(sc, MCI_IER, MCI_SR_ERROR | MCI_SR_ENDRX); - } -} - -static void -at91_mci_write_done(struct at91_mci_softc *sc, uint32_t sr) -{ - struct mmc_command *cmd = sc->curcmd; - - /* - * We arrive here when the entire DMA transfer for a write is done, - * whether it's a single or multi-block write. If it's multi-block we - * have to immediately move on to the next operation which is to send - * the stop command. If it's a single-block transfer we need to wait - * for NOTBUSY, but if that's already asserted we can avoid another - * interrupt and just move on to completing the request right away. - */ - - WR4(sc, PDC_PTCR, PDC_PTCR_RXTDIS | PDC_PTCR_TXTDIS); - - bus_dmamap_sync(sc->dmatag, sc->bbuf_map[sc->bbuf_curidx], - BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->dmatag, sc->bbuf_map[sc->bbuf_curidx]); - - if ((cmd->data->flags & MMC_DATA_MULTI) || (sr & MCI_SR_NOTBUSY)) { - cmd->error = MMC_ERR_NONE; - at91_mci_next_operation(sc); - } else { - WR4(sc, MCI_IER, MCI_SR_ERROR | MCI_SR_NOTBUSY); - } -} - -static void -at91_mci_notbusy(struct at91_mci_softc *sc) -{ - struct mmc_command *cmd = sc->curcmd; - - /* - * We arrive here by either completion of a single-block write, or - * completion of the stop command that ended a multi-block write (and, - * I suppose, after a card-select or erase, but I haven't tested - * those). Anyway, we're done and it's time to move on to the next - * command. - */ - - cmd->error = MMC_ERR_NONE; - at91_mci_next_operation(sc); -} - -static void -at91_mci_stop_done(struct at91_mci_softc *sc, uint32_t sr) -{ - struct mmc_command *cmd = sc->curcmd; - - /* - * We arrive here after receiving CMDRDY for a MMC_STOP_TRANSMISSION - * command. Depending on the operation being stopped, we may have to - * do some unusual things to work around hardware bugs. - */ - - /* - * This is known to be true of at91rm9200 hardware; it may or may not - * apply to more recent chips: - * - * After stopping a multi-block write, the NOTBUSY bit in MCI_SR does - * not properly reflect the actual busy state of the card as signaled - * on the DAT0 line; it always claims the card is not-busy. If we - * believe that and let operations continue, following commands will - * fail with response timeouts (except of course MMC_SEND_STATUS -- it - * indicates the card is busy in the PRG state, which was the smoking - * gun that showed MCI_SR NOTBUSY was not tracking DAT0 correctly). - * - * The atmel docs are emphatic: "This flag [NOTBUSY] must be used only - * for Write Operations." I guess technically since we sent a stop - * it's not a write operation anymore. But then just what did they - * think it meant for the stop command to have "...an optional busy - * signal transmitted on the data line" according to the SD spec? - * - * I tried a variety of things to un-wedge the MCI and get the status - * register to reflect NOTBUSY correctly again, but the only thing - * that worked was a full device reset. It feels like an awfully big - * hammer, but doing a full reset after every multiblock write is - * still faster than doing single-block IO (by almost two orders of - * magnitude: 20KB/sec improves to about 1.8MB/sec best case). - * - * After doing the reset, wait for a NOTBUSY interrupt before - * continuing with the next operation. - * - * This workaround breaks multiwrite on the rev2xx parts, but some other - * workaround is needed. - */ - if ((sc->flags & CMD_MULTIWRITE) && (sc->sc_cap & CAP_NEEDS_BYTESWAP)) { - at91_mci_reset(sc); - WR4(sc, MCI_IER, MCI_SR_ERROR | MCI_SR_NOTBUSY); - return; - } - - /* - * This is known to be true of at91rm9200 hardware; it may or may not - * apply to more recent chips: - * - * After stopping a multi-block read, loop to read and discard any - * data that coasts in after we sent the stop command. The docs don't - * say anything about it, but empirical testing shows that 1-3 - * additional words of data get buffered up in some unmentioned - * internal fifo and if we don't read and discard them here they end - * up on the front of the next read DMA transfer we do. - * - * This appears to be unnecessary for rev2xx parts. - */ - if ((sc->flags & CMD_MULTIREAD) && (sc->sc_cap & CAP_NEEDS_BYTESWAP)) { - uint32_t sr; - int count = 0; - - do { - sr = RD4(sc, MCI_SR); - if (sr & MCI_SR_RXRDY) { - RD4(sc, MCI_RDR); - ++count; - } - } while (sr & MCI_SR_RXRDY); - at91_mci_reset(sc); - } - - cmd->error = MMC_ERR_NONE; - at91_mci_next_operation(sc); - -} - -static void -at91_mci_cmdrdy(struct at91_mci_softc *sc, uint32_t sr) -{ - struct mmc_command *cmd = sc->curcmd; - int i; - - if (cmd == NULL) - return; - - /* - * We get here at the end of EVERY command. We retrieve the command - * response (if any) then decide what to do next based on the command. - */ - - if (cmd->flags & MMC_RSP_PRESENT) { - for (i = 0; i < ((cmd->flags & MMC_RSP_136) ? 4 : 1); i++) { - cmd->resp[i] = RD4(sc, MCI_RSPR + i * 4); - if (mci_debug) - printf("RSPR[%d] = %x sr=%x\n", i, cmd->resp[i], sr); - } - } - - /* - * If this was a stop command, go handle the various special - * conditions (read: bugs) that have to be dealt with following a stop. - */ - if (cmd->opcode == MMC_STOP_TRANSMISSION) { - at91_mci_stop_done(sc, sr); - return; - } - - /* - * If this command can continue to assert BUSY beyond the response then - * we need to wait for NOTBUSY before the command is really done. - * - * Note that this may not work properly on the at91rm9200. It certainly - * doesn't work for the STOP command that follows a multi-block write, - * so post-stop CMDRDY is handled separately; see the special handling - * in at91_mci_stop_done(). - * - * Beside STOP, there are other R1B-type commands that use the busy - * signal after CMDRDY: CMD7 (card select), CMD28-29 (write protect), - * CMD38 (erase). I haven't tested any of them, but I rather expect - * them all to have the same sort of problem with MCI_SR not actually - * reflecting the state of the DAT0-line busy indicator. So this code - * may need to grow some sort of special handling for them too. (This - * just in: CMD7 isn't a problem right now because dev/mmc.c incorrectly - * sets the response flags to R1 rather than R1B.) XXX - */ - if ((cmd->flags & MMC_RSP_BUSY)) { - WR4(sc, MCI_IER, MCI_SR_ERROR | MCI_SR_NOTBUSY); - return; - } - - /* - * If there is a data transfer with this command, then... - * - If it's a read, we need to wait for ENDRX. - * - If it's a write, now is the time to enable the PDC, and we need - * to wait for a BLKE that follows a TXBUFE, because if we're doing - * a split transfer we get a BLKE after the first half (when TPR/TCR - * get loaded from TNPR/TNCR). So first we wait for the TXBUFE, and - * the handling for that interrupt will then invoke the wait for the - * subsequent BLKE which indicates actual completion. - */ - if (cmd->data) { - uint32_t ier; - if (cmd->data->flags & MMC_DATA_READ) { - ier = MCI_SR_ENDRX; - } else { - ier = MCI_SR_TXBUFE; - WR4(sc, PDC_PTCR, PDC_PTCR_TXTEN); - } - WR4(sc, MCI_IER, MCI_SR_ERROR | ier); - return; - } - - /* - * If we made it to here, we don't need to wait for anything more for - * the current command, move on to the next command (will complete the - * request if there is no next command). - */ - cmd->error = MMC_ERR_NONE; - at91_mci_next_operation(sc); -} - -static void -at91_mci_intr(void *arg) -{ - struct at91_mci_softc *sc = (struct at91_mci_softc*)arg; - struct mmc_command *cmd = sc->curcmd; - uint32_t sr, isr; - - AT91_MCI_LOCK(sc); - - sr = RD4(sc, MCI_SR); - isr = sr & RD4(sc, MCI_IMR); - - if (mci_debug) - printf("i 0x%x sr 0x%x\n", isr, sr); - - /* - * All interrupts are one-shot; disable it now. - * The next operation will re-enable whatever interrupts it wants. - */ - WR4(sc, MCI_IDR, isr); - if (isr & MCI_SR_ERROR) { - if (isr & (MCI_SR_RTOE | MCI_SR_DTOE)) - cmd->error = MMC_ERR_TIMEOUT; - else if (isr & (MCI_SR_RCRCE | MCI_SR_DCRCE)) - cmd->error = MMC_ERR_BADCRC; - else if (isr & (MCI_SR_OVRE | MCI_SR_UNRE)) - cmd->error = MMC_ERR_FIFO; - else - cmd->error = MMC_ERR_FAILED; - /* - * CMD8 is used to probe for SDHC cards, a standard SD card - * will get a response timeout; don't report it because it's a - * normal and expected condition. One might argue that all - * error reporting should be left to higher levels, but when - * they report at all it's always EIO, which isn't very - * helpful. XXX bootverbose? - */ - if (cmd->opcode != 8) { - device_printf(sc->dev, - "IO error; status MCI_SR = 0x%b cmd opcode = %d%s\n", - sr, MCI_SR_BITSTRING, cmd->opcode, - (cmd->opcode != 12) ? "" : - (sc->flags & CMD_MULTIREAD) ? " after read" : " after write"); - /* XXX not sure RTOE needs a full reset, just a retry */ - at91_mci_reset(sc); - } - at91_mci_next_operation(sc); - } else { - if (isr & MCI_SR_TXBUFE) { -// printf("TXBUFE\n"); - /* - * We need to wait for a BLKE that follows TXBUFE - * (intermediate BLKEs might happen after ENDTXes if - * we're chaining multiple buffers). If BLKE is also - * asserted at the time we get TXBUFE, we can avoid - * another interrupt and process it right away, below. - */ - if (sr & MCI_SR_BLKE) - isr |= MCI_SR_BLKE; - else - WR4(sc, MCI_IER, MCI_SR_BLKE); - } - if (isr & MCI_SR_RXBUFF) { -// printf("RXBUFF\n"); - } - if (isr & MCI_SR_ENDTX) { -// printf("ENDTX\n"); - } - if (isr & MCI_SR_ENDRX) { -// printf("ENDRX\n"); - at91_mci_read_done(sc, sr); - } - if (isr & MCI_SR_NOTBUSY) { -// printf("NOTBUSY\n"); - at91_mci_notbusy(sc); - } - if (isr & MCI_SR_DTIP) { -// printf("Data transfer in progress\n"); - } - if (isr & MCI_SR_BLKE) { -// printf("Block transfer end\n"); - at91_mci_write_done(sc, sr); - } - if (isr & MCI_SR_TXRDY) { -// printf("Ready to transmit\n"); - } - if (isr & MCI_SR_RXRDY) { -// printf("Ready to receive\n"); - } - if (isr & MCI_SR_CMDRDY) { -// printf("Command ready\n"); - at91_mci_cmdrdy(sc, sr); - } - } - AT91_MCI_UNLOCK(sc); -} - -static int -at91_mci_read_ivar(device_t bus, device_t child, int which, uintptr_t *result) -{ - struct at91_mci_softc *sc = device_get_softc(bus); - - switch (which) { - default: - return (EINVAL); - case MMCBR_IVAR_BUS_MODE: - *(int *)result = sc->host.ios.bus_mode; - break; - case MMCBR_IVAR_BUS_WIDTH: - *(int *)result = sc->host.ios.bus_width; - break; - case MMCBR_IVAR_CHIP_SELECT: - *(int *)result = sc->host.ios.chip_select; - break; - case MMCBR_IVAR_CLOCK: - *(int *)result = sc->host.ios.clock; - break; - case MMCBR_IVAR_F_MIN: - *(int *)result = sc->host.f_min; - break; - case MMCBR_IVAR_F_MAX: - *(int *)result = sc->host.f_max; - break; - case MMCBR_IVAR_HOST_OCR: - *(int *)result = sc->host.host_ocr; - break; - case MMCBR_IVAR_MODE: - *(int *)result = sc->host.mode; - break; - case MMCBR_IVAR_OCR: - *(int *)result = sc->host.ocr; - break; - case MMCBR_IVAR_POWER_MODE: - *(int *)result = sc->host.ios.power_mode; - break; - case MMCBR_IVAR_VDD: - *(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: - /* - * Something is wrong with the 2x parts and multiblock, so - * just do 1 block at a time for now, which really kills - * performance. - */ - if (sc->sc_cap & CAP_MCI1_REV2XX) - *(int *)result = 1; - else - *(int *)result = MAX_BLOCKS; - break; - } - return (0); -} - -static int -at91_mci_write_ivar(device_t bus, device_t child, int which, uintptr_t value) -{ - struct at91_mci_softc *sc = device_get_softc(bus); - - switch (which) { - default: - return (EINVAL); - case MMCBR_IVAR_BUS_MODE: - sc->host.ios.bus_mode = value; - break; - case MMCBR_IVAR_BUS_WIDTH: - sc->host.ios.bus_width = value; - break; - case MMCBR_IVAR_CHIP_SELECT: - sc->host.ios.chip_select = value; - break; - case MMCBR_IVAR_CLOCK: - sc->host.ios.clock = value; - break; - case MMCBR_IVAR_MODE: - sc->host.mode = value; - break; - case MMCBR_IVAR_OCR: - sc->host.ocr = value; - break; - case MMCBR_IVAR_POWER_MODE: - sc->host.ios.power_mode = value; - break; - case MMCBR_IVAR_VDD: - sc->host.ios.vdd = value; - break; - /* These are read-only */ - case MMCBR_IVAR_CAPS: - case MMCBR_IVAR_HOST_OCR: - case MMCBR_IVAR_F_MIN: - case MMCBR_IVAR_F_MAX: - case MMCBR_IVAR_MAX_DATA: - return (EINVAL); - } - return (0); -} - -static device_method_t at91_mci_methods[] = { - /* device_if */ - DEVMETHOD(device_probe, at91_mci_probe), - DEVMETHOD(device_attach, at91_mci_attach), - DEVMETHOD(device_detach, at91_mci_detach), - - /* Bus interface */ - DEVMETHOD(bus_read_ivar, at91_mci_read_ivar), - DEVMETHOD(bus_write_ivar, at91_mci_write_ivar), - - /* mmcbr_if */ - DEVMETHOD(mmcbr_update_ios, at91_mci_update_ios), - DEVMETHOD(mmcbr_request, at91_mci_request), - DEVMETHOD(mmcbr_get_ro, at91_mci_get_ro), - DEVMETHOD(mmcbr_acquire_host, at91_mci_acquire_host), - DEVMETHOD(mmcbr_release_host, at91_mci_release_host), - - DEVMETHOD_END -}; - -static driver_t at91_mci_driver = { - "at91_mci", - at91_mci_methods, - sizeof(struct at91_mci_softc), -}; - -static devclass_t at91_mci_devclass; - -#ifdef FDT -DRIVER_MODULE(at91_mci, simplebus, at91_mci_driver, at91_mci_devclass, NULL, - NULL); -#else -DRIVER_MODULE(at91_mci, atmelarm, at91_mci_driver, at91_mci_devclass, NULL, - NULL); -#endif - -MMC_DECLARE_BRIDGE(at91_mci); Index: head/sys/arm/at91/at91_mcireg.h =================================================================== --- head/sys/arm/at91/at91_mcireg.h +++ head/sys/arm/at91/at91_mcireg.h @@ -1,158 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2006 Berndt Walter. All rights reserved. - * Copyright (c) 2006 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef ARM_AT91_AT91_MCIREG_H -#define ARM_AT91_AT91_MCIREG_H - -#define MMC_MAX 30 - -#define MCI_CR 0x00 /* MCI Control Register */ -#define MCI_MR 0x04 /* MCI Mode Register */ -#define MCI_DTOR 0x08 /* MCI Data Timeout Register */ -#define MCI_SDCR 0x0c /* MCI SD Card Register */ -#define MCI_ARGR 0x10 /* MCI Argument Register */ -#define MCI_CMDR 0x14 /* MCI Command Register */ -#define MCI_RSPR 0x20 /* MCI Response Registers - 4 of them */ -#define MCI_RDR 0x30 /* MCI Receive Data Register */ -#define MCI_TDR 0x34 /* MCI Transmit Data Register */ -#define MCI_SR 0x40 /* MCI Status Register */ -#define MCI_IER 0x44 /* MCI Interrupt Enable Register */ -#define MCI_IDR 0x48 /* MCI Interrupt Disable Register */ -#define MCI_IMR 0x4c /* MCI Interrupt Mask Register */ - -/* -------- MCI_CR : (MCI Offset: 0x0) MCI Control Register -------- */ -#define MCI_CR_MCIEN (0x1u << 0) /* (MCI) Multimedia Interface Enable */ -#define MCI_CR_MCIDIS (0x1u << 1) /* (MCI) Multimedia Interface Disable */ -#define MCI_CR_PWSEN (0x1u << 2) /* (MCI) Power Save Mode Enable */ -#define MCI_CR_PWSDIS (0x1u << 3) /* (MCI) Power Save Mode Disable */ -#define MCI_CR_SWRST (0x1u << 7) /* (MCI) Software Reset */ -/* -------- MCI_MR : (MCI Offset: 0x4) MCI Mode Register -------- */ -#define MCI_MR_CLKDIV (0xffu << 0) /* (MCI) Clock Divider */ -#define MCI_MR_PWSDIV (0x3fu << 8) /* (MCI) Power Saving Divider */ -#define MCI_MR_RDPROOF (0x1u << 11) /* (MCI) Read Proof Enable */ -#define MCI_MR_WRPROOF (0x1u << 12) /* (MCI) Write Proof Enable */ -#define MCI_MR_PDCFBYTE (0x1u << 13) /* (MCI) PDC Force Byte Transfer */ -#define MCI_MR_PDCPADV (0x1u << 14) /* (MCI) PDC Padding Value */ -#define MCI_MR_PDCMODE (0x1u << 15) /* (MCI) PDC Oriented Mode */ -#define MCI_MR_BLKLEN 0x3fff0000ul /* (MCI) Data Block Length */ -/* -------- MCI_DTOR : (MCI Offset: 0x8) MCI Data Timeout Register -------- */ -#define MCI_DTOR_DTOCYC (0xfu << 0) /* (MCI) Data Timeout Cycle Number */ -#define MCI_DTOR_DTOMUL (0x7u << 4) /* (MCI) Data Timeout Multiplier */ -#define MCI_DTOR_DTOMUL_1 (0x0u << 4) /* (MCI) DTOCYC x 1 */ -#define MCI_DTOR_DTOMUL_16 (0x1u << 4) /* (MCI) DTOCYC x 16 */ -#define MCI_DTOR_DTOMUL_128 (0x2u << 4) /* (MCI) DTOCYC x 128 */ -#define MCI_DTOR_DTOMUL_256 (0x3u << 4) /* (MCI) DTOCYC x 256 */ -#define MCI_DTOR_DTOMUL_1k (0x4u << 4) /* (MCI) DTOCYC x 1024 */ -#define MCI_DTOR_DTOMUL_4k (0x5u << 4) /* (MCI) DTOCYC x 4096 */ -#define MCI_DTOR_DTOMUL_64k (0x6u << 4) /* (MCI) DTOCYC x 65536 */ -#define MCI_DTOR_DTOMUL_1M (0x7u << 4) /* (MCI) DTOCYC x 1048576 */ -/* -------- MCI_SDCR : (MCI Offset: 0xc) MCI SD Card Register -------- */ -#define MCI_SDCR_SDCSEL (0x1u << 0) /* (MCI) SD Card Selector */ -#define MCI_SDCR_SDCBUS (0x1u << 7) /* (MCI) SD Card Bus Width */ -/* -------- MCI_CMDR : (MCI Offset: 0x14) MCI Command Register -------- */ -#define MCI_CMDR_CMDNB (0x1Fu << 0) /* (MCI) Command Number */ -#define MCI_CMDR_RSPTYP (0x3u << 6) /* (MCI) Response Type */ -#define MCI_CMDR_RSPTYP_NO (0x0u << 6) /* (MCI) No response */ -#define MCI_CMDR_RSPTYP_48 (0x1u << 6) /* (MCI) 48-bit response */ -#define MCI_CMDR_RSPTYP_136 (0x2u << 6) /* (MCI) 136-bit response */ -#define MCI_CMDR_SPCMD (0x7u << 8) /* (MCI) Special CMD */ -#define MCI_CMDR_SPCMD_NONE (0x0u << 8) /* (MCI) Not a special CMD */ -#define MCI_CMDR_SPCMD_INIT (0x1u << 8) /* (MCI) Initialization CMD */ -#define MCI_CMDR_SPCMD_SYNC (0x2u << 8) /* (MCI) Synchronized CMD */ -#define MCI_CMDR_SPCMD_IT_CMD (0x4u << 8) /* (MCI) Interrupt command */ -#define MCI_CMDR_SPCMD_IT_REP (0x5u << 8) /* (MCI) Interrupt response */ -#define MCI_CMDR_OPDCMD (0x1u << 11) /* (MCI) Open Drain Command */ -#define MCI_CMDR_MAXLAT (0x1u << 12) /* (MCI) Maximum Latency for Command to respond */ -#define MCI_CMDR_TRCMD (0x3u << 16) /* (MCI) Transfer CMD */ -#define MCI_CMDR_TRCMD_NO (0x0u << 16) /* (MCI) No transfer */ -#define MCI_CMDR_TRCMD_START (0x1u << 16) /* (MCI) Start transfer */ -#define MCI_CMDR_TRCMD_STOP (0x2u << 16) /* (MCI) Stop transfer */ -#define MCI_CMDR_TRDIR (0x1u << 18) /* (MCI) Transfer Direction */ -#define MCI_CMDR_TRTYP (0x3u << 19) /* (MCI) Transfer Type */ -#define MCI_CMDR_TRTYP_BLOCK (0x0u << 19) /* (MCI) Block Transfer type */ -#define MCI_CMDR_TRTYP_MULTIPLE (0x1u << 19) /* (MCI) Multiple Block transfer type */ -#define MCI_CMDR_TRTYP_STREAM (0x2u << 19) /* (MCI) Stream transfer type */ -/* -------- MCI_SR : (MCI Offset: 0x40) MCI Status Register -------- */ -#define MCI_SR_CMDRDY (0x1u << 0) /* (MCI) Command Ready flag */ -#define MCI_SR_RXRDY (0x1u << 1) /* (MCI) RX Ready flag */ -#define MCI_SR_TXRDY (0x1u << 2) /* (MCI) TX Ready flag */ -#define MCI_SR_BLKE (0x1u << 3) /* (MCI) Data Block Transfer Ended flag */ -#define MCI_SR_DTIP (0x1u << 4) /* (MCI) Data Transfer in Progress flag */ -#define MCI_SR_NOTBUSY (0x1u << 5) /* (MCI) Data Line Not Busy flag */ -#define MCI_SR_ENDRX (0x1u << 6) /* (MCI) End of RX Buffer flag */ -#define MCI_SR_ENDTX (0x1u << 7) /* (MCI) End of TX Buffer flag */ -#define MCI_SR_RXBUFF (0x1u << 14) /* (MCI) RX Buffer Full flag */ -#define MCI_SR_TXBUFE (0x1u << 15) /* (MCI) TX Buffer Empty flag */ -#define MCI_SR_RINDE (0x1u << 16) /* (MCI) Response Index Error flag */ -#define MCI_SR_RDIRE (0x1u << 17) /* (MCI) Response Direction Error flag */ -#define MCI_SR_RCRCE (0x1u << 18) /* (MCI) Response CRC Error flag */ -#define MCI_SR_RENDE (0x1u << 19) /* (MCI) Response End Bit Error flag */ -#define MCI_SR_RTOE (0x1u << 20) /* (MCI) Response Time-out Error flag */ -#define MCI_SR_DCRCE (0x1u << 21) /* (MCI) data CRC Error flag */ -#define MCI_SR_DTOE (0x1u << 22) /* (MCI) Data timeout Error flag */ -#define MCI_SR_OVRE (0x1u << 30) /* (MCI) Overrun flag */ -#define MCI_SR_UNRE (0x1u << 31) /* (MCI) Underrun flag */ - -/* TXRDY,DTIP,ENDTX,TXBUFE,RTOE */ - -#define MCI_SR_BITSTRING \ - "\020" \ - "\001CMDRDY" \ - "\002RXRDY" \ - "\003TXRDY" \ - "\004BLKE" \ - "\005DTIP" \ - "\006NOTBUSY" \ - "\007ENDRX" \ - "\010ENDTX" \ - "\017RXBUFF" \ - "\020TXBUFE" \ - "\021RINDE" \ - "\022RDIRE" \ - "\023RCRCE" \ - "\024RENDE" \ - "\025RTOE" \ - "\026DCRCE" \ - "\027DTOE" \ - "\037OVRE" \ - "\040UNRE" - -/* -------- MCI_IER : (MCI Offset: 0x44) MCI Interrupt Enable Register -------- */ -/* -------- MCI_IDR : (MCI Offset: 0x48) MCI Interrupt Disable Register -------- */ -/* -------- MCI_IMR : (MCI Offset: 0x4c) MCI Interrupt Mask Register -------- */ - -#define MCI_SR_ERROR (MCI_SR_UNRE | MCI_SR_OVRE | MCI_SR_DTOE | \ - MCI_SR_DCRCE | MCI_SR_RTOE | MCI_SR_RENDE | \ - MCI_SR_RCRCE | MCI_SR_RDIRE | MCI_SR_RINDE) - -#define AT91C_BUS_WIDTH_1BIT 0x00 -#define AT91C_BUS_WIDTH_4BITS 0x02 - -#endif /* ARM_AT91_AT91_MCIREG_H */ Index: head/sys/arm/at91/at91_ohci.c =================================================================== --- head/sys/arm/at91/at91_ohci.c +++ head/sys/arm/at91/at91_ohci.c @@ -1,236 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include - -#define MEM_RID 0 - -static device_probe_t ohci_atmelarm_probe; -static device_attach_t ohci_atmelarm_attach; -static device_detach_t ohci_atmelarm_detach; - -struct at91_ohci_softc { - struct ohci_softc sc_ohci; /* must be first */ - struct at91_pmc_clock *mclk; - struct at91_pmc_clock *iclk; - struct at91_pmc_clock *fclk; -}; - -static int -ohci_atmelarm_probe(device_t dev) -{ - - device_set_desc(dev, "AT91 integrated OHCI controller"); - return (BUS_PROBE_DEFAULT); -} - -static int -ohci_atmelarm_attach(device_t dev) -{ - struct at91_ohci_softc *sc = device_get_softc(dev); - int err; - int rid; - - /* initialise some bus fields */ - sc->sc_ohci.sc_bus.parent = dev; - sc->sc_ohci.sc_bus.devices = sc->sc_ohci.sc_devices; - sc->sc_ohci.sc_bus.devices_max = OHCI_MAX_DEVICES; - sc->sc_ohci.sc_bus.dma_bits = 32; - - /* get all DMA memory */ - if (usb_bus_mem_alloc_all(&sc->sc_ohci.sc_bus, - USB_GET_DMA_TAG(dev), &ohci_iterate_hw_softc)) { - return (ENOMEM); - } - sc->mclk = at91_pmc_clock_ref("mck"); - sc->iclk = at91_pmc_clock_ref("ohci_clk"); - sc->fclk = at91_pmc_clock_ref("uhpck"); - - sc->sc_ohci.sc_dev = dev; - - rid = MEM_RID; - sc->sc_ohci.sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, - &rid, RF_ACTIVE); - - if (!(sc->sc_ohci.sc_io_res)) { - err = ENOMEM; - goto error; - } - sc->sc_ohci.sc_io_tag = rman_get_bustag(sc->sc_ohci.sc_io_res); - sc->sc_ohci.sc_io_hdl = rman_get_bushandle(sc->sc_ohci.sc_io_res); - sc->sc_ohci.sc_io_size = rman_get_size(sc->sc_ohci.sc_io_res); - - rid = 0; - sc->sc_ohci.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_ACTIVE); - if (!(sc->sc_ohci.sc_irq_res)) { - goto error; - } - sc->sc_ohci.sc_bus.bdev = device_add_child(dev, "usbus", -1); - if (!(sc->sc_ohci.sc_bus.bdev)) { - goto error; - } - device_set_ivars(sc->sc_ohci.sc_bus.bdev, &sc->sc_ohci.sc_bus); - - strlcpy(sc->sc_ohci.sc_vendor, "Atmel", sizeof(sc->sc_ohci.sc_vendor)); - - err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, - NULL, (driver_intr_t *)ohci_interrupt, sc, &sc->sc_ohci.sc_intr_hdl); - if (err) { - sc->sc_ohci.sc_intr_hdl = NULL; - goto error; - } - /* - * turn on the clocks from the AT91's point of view. Keep the unit in reset. - */ - at91_pmc_clock_enable(sc->mclk); - at91_pmc_clock_enable(sc->iclk); - at91_pmc_clock_enable(sc->fclk); - bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl, - OHCI_CONTROL, 0); - - err = ohci_init(&sc->sc_ohci); - if (!err) { - err = device_probe_and_attach(sc->sc_ohci.sc_bus.bdev); - } - if (err) { - goto error; - } - return (0); - -error: - ohci_atmelarm_detach(dev); - return (ENXIO); -} - -static int -ohci_atmelarm_detach(device_t dev) -{ - struct at91_ohci_softc *sc = device_get_softc(dev); - int err; - - /* during module unload there are lots of children leftover */ - device_delete_children(dev); - - /* - * Put the controller into reset, then disable clocks and do - * the MI tear down. We have to disable the clocks/hardware - * after we do the rest of the teardown. We also disable the - * clocks in the opposite order we acquire them, but that - * doesn't seem to be absolutely necessary. We free up the - * clocks after we disable them, so the system could, in - * theory, reuse them. - */ - bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl, - OHCI_CONTROL, 0); - - at91_pmc_clock_disable(sc->fclk); - at91_pmc_clock_disable(sc->iclk); - at91_pmc_clock_disable(sc->mclk); - at91_pmc_clock_deref(sc->fclk); - at91_pmc_clock_deref(sc->iclk); - at91_pmc_clock_deref(sc->mclk); - - if (sc->sc_ohci.sc_irq_res && sc->sc_ohci.sc_intr_hdl) { - /* - * only call ohci_detach() after ohci_init() - */ - ohci_detach(&sc->sc_ohci); - - err = bus_teardown_intr(dev, sc->sc_ohci.sc_irq_res, sc->sc_ohci.sc_intr_hdl); - sc->sc_ohci.sc_intr_hdl = NULL; - } - if (sc->sc_ohci.sc_irq_res) { - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_ohci.sc_irq_res); - sc->sc_ohci.sc_irq_res = NULL; - } - if (sc->sc_ohci.sc_io_res) { - bus_release_resource(dev, SYS_RES_MEMORY, MEM_RID, - sc->sc_ohci.sc_io_res); - sc->sc_ohci.sc_io_res = NULL; - } - usb_bus_mem_free_all(&sc->sc_ohci.sc_bus, &ohci_iterate_hw_softc); - - return (0); -} - -static device_method_t ohci_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, ohci_atmelarm_probe), - DEVMETHOD(device_attach, ohci_atmelarm_attach), - DEVMETHOD(device_detach, ohci_atmelarm_detach), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - - DEVMETHOD_END -}; - -static driver_t ohci_driver = { - .name = "ohci", - .methods = ohci_methods, - .size = sizeof(struct at91_ohci_softc), -}; - -static devclass_t ohci_devclass; - -DRIVER_MODULE(ohci, atmelarm, ohci_driver, ohci_devclass, 0, 0); -MODULE_DEPEND(ohci, usb, 1, 1, 1); Index: head/sys/arm/at91/at91_ohci_fdt.c =================================================================== --- head/sys/arm/at91/at91_ohci_fdt.c +++ head/sys/arm/at91/at91_ohci_fdt.c @@ -1,244 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include - -#include -#include - -#define MEM_RID 0 - -static device_probe_t ohci_at91_fdt_probe; -static device_attach_t ohci_at91_fdt_attach; -static device_detach_t ohci_at91_fdt_detach; - -struct at91_ohci_softc { - struct ohci_softc sc_ohci; /* must be first */ - struct at91_pmc_clock *mclk; - struct at91_pmc_clock *iclk; - struct at91_pmc_clock *fclk; -}; - -static int -ohci_at91_fdt_probe(device_t dev) -{ - if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-ohci")) - return (ENXIO); - device_set_desc(dev, "AT91 integrated OHCI controller"); - - return (BUS_PROBE_DEFAULT); -} - -static int -ohci_at91_fdt_attach(device_t dev) -{ - struct at91_ohci_softc *sc = device_get_softc(dev); - int err; - int rid; - - /* initialise some bus fields */ - sc->sc_ohci.sc_bus.parent = dev; - sc->sc_ohci.sc_bus.devices = sc->sc_ohci.sc_devices; - sc->sc_ohci.sc_bus.devices_max = OHCI_MAX_DEVICES; - sc->sc_ohci.sc_bus.dma_bits = 32; - - /* get all DMA memory */ - if (usb_bus_mem_alloc_all(&sc->sc_ohci.sc_bus, - USB_GET_DMA_TAG(dev), &ohci_iterate_hw_softc)) { - return (ENOMEM); - } - sc->mclk = at91_pmc_clock_ref("mck"); - sc->iclk = at91_pmc_clock_ref("ohci_clk"); - sc->fclk = at91_pmc_clock_ref("uhpck"); - - sc->sc_ohci.sc_dev = dev; - - rid = MEM_RID; - sc->sc_ohci.sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, - &rid, RF_ACTIVE); - - if (!(sc->sc_ohci.sc_io_res)) { - err = ENOMEM; - goto error; - } - sc->sc_ohci.sc_io_tag = rman_get_bustag(sc->sc_ohci.sc_io_res); - sc->sc_ohci.sc_io_hdl = rman_get_bushandle(sc->sc_ohci.sc_io_res); - sc->sc_ohci.sc_io_size = rman_get_size(sc->sc_ohci.sc_io_res); - - rid = 0; - sc->sc_ohci.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_ACTIVE); - if (!(sc->sc_ohci.sc_irq_res)) { - goto error; - } - sc->sc_ohci.sc_bus.bdev = device_add_child(dev, "usbus", -1); - if (!(sc->sc_ohci.sc_bus.bdev)) { - goto error; - } - device_set_ivars(sc->sc_ohci.sc_bus.bdev, &sc->sc_ohci.sc_bus); - - strlcpy(sc->sc_ohci.sc_vendor, "Atmel", sizeof(sc->sc_ohci.sc_vendor)); - - err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, - NULL, (driver_intr_t *)ohci_interrupt, sc, &sc->sc_ohci.sc_intr_hdl); - if (err) { - sc->sc_ohci.sc_intr_hdl = NULL; - goto error; - } - /* - * turn on the clocks from the AT91's point of view. Keep the unit in reset. - */ - at91_pmc_clock_enable(sc->mclk); - at91_pmc_clock_enable(sc->iclk); - at91_pmc_clock_enable(sc->fclk); - bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl, - OHCI_CONTROL, 0); - - err = ohci_init(&sc->sc_ohci); - if (!err) { - err = device_probe_and_attach(sc->sc_ohci.sc_bus.bdev); - } - if (err) { - goto error; - } - return (0); - -error: - ohci_at91_fdt_detach(dev); - return (ENXIO); -} - -static int -ohci_at91_fdt_detach(device_t dev) -{ - struct at91_ohci_softc *sc = device_get_softc(dev); - int err; - - /* during module unload there are lots of children leftover */ - device_delete_children(dev); - - if (sc->sc_ohci.sc_io_res != NULL) { - /* - * Put the controller into reset, then disable clocks and do - * the MI tear down. We have to disable the clocks/hardware - * after we do the rest of the teardown. We also disable the - * clocks in the opposite order we acquire them, but that - * doesn't seem to be absolutely necessary. We free up the - * clocks after we disable them, so the system could, in - * theory, reuse them. - */ - bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl, - OHCI_CONTROL, 0); - - at91_pmc_clock_disable(sc->fclk); - at91_pmc_clock_disable(sc->iclk); - at91_pmc_clock_disable(sc->mclk); - at91_pmc_clock_deref(sc->fclk); - at91_pmc_clock_deref(sc->iclk); - at91_pmc_clock_deref(sc->mclk); - - if (sc->sc_ohci.sc_irq_res && sc->sc_ohci.sc_intr_hdl) { - /* - * only call ohci_detach() after ohci_init() - */ - ohci_detach(&sc->sc_ohci); - - err = bus_teardown_intr(dev, sc->sc_ohci.sc_irq_res, - sc->sc_ohci.sc_intr_hdl); - sc->sc_ohci.sc_intr_hdl = NULL; - } - if (sc->sc_ohci.sc_irq_res) { - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_ohci.sc_irq_res); - sc->sc_ohci.sc_irq_res = NULL; - } - if (sc->sc_ohci.sc_io_res) { - bus_release_resource(dev, SYS_RES_MEMORY, MEM_RID, - sc->sc_ohci.sc_io_res); - sc->sc_ohci.sc_io_res = NULL; - } - } - usb_bus_mem_free_all(&sc->sc_ohci.sc_bus, &ohci_iterate_hw_softc); - - return (0); -} - -static device_method_t ohci_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, ohci_at91_fdt_probe), - DEVMETHOD(device_attach, ohci_at91_fdt_attach), - DEVMETHOD(device_detach, ohci_at91_fdt_detach), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - - DEVMETHOD_END -}; - -static driver_t ohci_driver = { - .name = "ohci", - .methods = ohci_methods, - .size = sizeof(struct at91_ohci_softc), -}; - -static devclass_t ohci_devclass; - -DRIVER_MODULE(ohci, simplebus, ohci_driver, ohci_devclass, 0, 0); -MODULE_DEPEND(ohci, usb, 1, 1, 1); Index: head/sys/arm/at91/at91_pdcreg.h =================================================================== --- head/sys/arm/at91/at91_pdcreg.h +++ head/sys/arm/at91/at91_pdcreg.h @@ -1,50 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2006 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef ARM_AT91_AT91_PDCREG_H -#define ARM_AT91_AT91_PDCREG_H - -#define PDC_RPR 0x100 /* PDC Receive Pointer Register */ -#define PDC_RCR 0x104 /* PDC Receive Counter Register */ -#define PDC_TPR 0x108 /* PDC Transmit Pointer Register */ -#define PDC_TCR 0x10c /* PDC Transmit Counter Register */ -#define PDC_RNPR 0x110 /* PDC Receive Next Pointer Register */ -#define PDC_RNCR 0x114 /* PDC Receive Next Counter Register */ -#define PDC_TNPR 0x118 /* PDC Transmit Next Pointer Reg */ -#define PDC_TNCR 0x11c /* PDC Transmit Next Counter Reg */ -#define PDC_PTCR 0x120 /* PDC Transfer Control Register */ -#define PDC_PTSR 0x124 /* PDC Transfer Status Register */ - -/* PTCR/PTSR */ -#define PDC_PTCR_RXTEN (1UL << 0) /* RXTEN: Receiver Transfer Enable */ -#define PDC_PTCR_RXTDIS (1UL << 1) /* RXTDIS: Receiver Transfer Disable */ -#define PDC_PTCR_TXTEN (1UL << 8) /* TXTEN: Transmitter Transfer En */ -#define PDC_PTCR_TXTDIS (1UL << 9) /* TXTDIS: Transmitter Transmit Dis */ - -#endif /* ARM_AT91_AT91_PDCREG_H */ Index: head/sys/arm/at91/at91_pinctrl.c =================================================================== --- head/sys/arm/at91/at91_pinctrl.c +++ head/sys/arm/at91/at91_pinctrl.c @@ -1,517 +0,0 @@ -/*- - * Copyright (c) 2014 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include -#include - -#define BUS_PASS_PINMUX (BUS_PASS_INTERRUPT + 1) - -struct pinctrl_range { - uint64_t bus; - uint64_t host; - uint64_t size; -}; - -struct pinctrl_softc { - device_t dev; - phandle_t node; - - struct pinctrl_range *ranges; - int nranges; - - pcell_t acells, scells; - int done_pinmux; -}; - -struct pinctrl_devinfo { - struct ofw_bus_devinfo obdinfo; - struct resource_list rl; -}; - -static int -at91_pinctrl_probe(device_t dev) -{ - - if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-pinctrl")) - return (ENXIO); - device_set_desc(dev, "pincontrol bus"); - return (0); -} - -/* XXX Make this a subclass of simplebus */ - -static struct pinctrl_devinfo * -at91_pinctrl_setup_dinfo(device_t dev, phandle_t node) -{ - struct pinctrl_softc *sc; - struct pinctrl_devinfo *ndi; - uint32_t *reg, *intr, icells; - uint64_t phys, size; - phandle_t iparent; - int i, j, k; - int nintr; - int nreg; - - sc = device_get_softc(dev); - - ndi = malloc(sizeof(*ndi), M_DEVBUF, M_WAITOK | M_ZERO); - if (ofw_bus_gen_setup_devinfo(&ndi->obdinfo, node) != 0) { - free(ndi, M_DEVBUF); - return (NULL); - } - - resource_list_init(&ndi->rl); - nreg = OF_getencprop_alloc_multi(node, "reg", sizeof(*reg), - (void **)®); - if (nreg == -1) - nreg = 0; - if (nreg % (sc->acells + sc->scells) != 0) { -// if (bootverbose) - device_printf(dev, "Malformed reg property on <%s>\n", - ndi->obdinfo.obd_name); - nreg = 0; - } - - for (i = 0, k = 0; i < nreg; i += sc->acells + sc->scells, k++) { - phys = size = 0; - for (j = 0; j < sc->acells; j++) { - phys <<= 32; - phys |= reg[i + j]; - } - for (j = 0; j < sc->scells; j++) { - size <<= 32; - size |= reg[i + sc->acells + j]; - } - - resource_list_add(&ndi->rl, SYS_RES_MEMORY, k, - phys, phys + size - 1, size); - } - OF_prop_free(reg); - - nintr = OF_getencprop_alloc_multi(node, "interrupts", sizeof(*intr), - (void **)&intr); - if (nintr > 0) { - if (OF_searchencprop(node, "interrupt-parent", &iparent, - sizeof(iparent)) == -1) { - device_printf(dev, "No interrupt-parent found, " - "assuming direct parent\n"); - iparent = OF_parent(node); - } - if (OF_searchencprop(OF_node_from_xref(iparent), - "#interrupt-cells", &icells, sizeof(icells)) == -1) { - device_printf(dev, "Missing #interrupt-cells property," - " assuming <1>\n"); - icells = 1; - } - if (icells < 1 || icells > nintr) { - device_printf(dev, "Invalid #interrupt-cells property " - "value <%d>, assuming <1>\n", icells); - icells = 1; - } - for (i = 0, k = 0; i < nintr; i += icells, k++) { - intr[i] = ofw_bus_map_intr(dev, iparent, icells, - &intr[i]); - resource_list_add(&ndi->rl, SYS_RES_IRQ, k, intr[i], - intr[i], 1); - } - OF_prop_free(intr); - } - - return (ndi); -} - -static int -at91_pinctrl_fill_ranges(phandle_t node, struct pinctrl_softc *sc) -{ - int host_address_cells; - cell_t *base_ranges; - ssize_t nbase_ranges; - int err; - int i, j, k; - - err = OF_searchencprop(OF_parent(node), "#address-cells", - &host_address_cells, sizeof(host_address_cells)); - if (err <= 0) - return (-1); - - nbase_ranges = OF_getproplen(node, "ranges"); - if (nbase_ranges < 0) - return (-1); - sc->nranges = nbase_ranges / sizeof(cell_t) / - (sc->acells + host_address_cells + sc->scells); - if (sc->nranges == 0) - return (0); - - sc->ranges = malloc(sc->nranges * sizeof(sc->ranges[0]), - M_DEVBUF, M_WAITOK); - base_ranges = malloc(nbase_ranges, M_DEVBUF, M_WAITOK); - OF_getencprop(node, "ranges", base_ranges, nbase_ranges); - - for (i = 0, j = 0; i < sc->nranges; i++) { - sc->ranges[i].bus = 0; - for (k = 0; k < sc->acells; k++) { - sc->ranges[i].bus <<= 32; - sc->ranges[i].bus |= base_ranges[j++]; - } - sc->ranges[i].host = 0; - for (k = 0; k < host_address_cells; k++) { - sc->ranges[i].host <<= 32; - sc->ranges[i].host |= base_ranges[j++]; - } - sc->ranges[i].size = 0; - for (k = 0; k < sc->scells; k++) { - sc->ranges[i].size <<= 32; - sc->ranges[i].size |= base_ranges[j++]; - } - } - - free(base_ranges, M_DEVBUF); - return (sc->nranges); -} - -static int -at91_pinctrl_attach(device_t dev) -{ - struct pinctrl_softc *sc; - struct pinctrl_devinfo *di; - phandle_t node; - device_t cdev; - - sc = device_get_softc(dev); - node = ofw_bus_get_node(dev); - - sc->dev = dev; - sc->node = node; - - /* - * Some important numbers - */ - sc->acells = 2; - OF_getencprop(node, "#address-cells", &sc->acells, sizeof(sc->acells)); - sc->scells = 1; - OF_getencprop(node, "#size-cells", &sc->scells, sizeof(sc->scells)); - - if (at91_pinctrl_fill_ranges(node, sc) < 0) { - device_printf(dev, "could not get ranges\n"); - return (ENXIO); - } - - for (node = OF_child(node); node > 0; node = OF_peer(node)) { - if ((di = at91_pinctrl_setup_dinfo(dev, node)) == NULL) - continue; - cdev = device_add_child(dev, NULL, -1); - if (cdev == NULL) { - device_printf(dev, "<%s>: device_add_child failed\n", - di->obdinfo.obd_name); - resource_list_free(&di->rl); - ofw_bus_gen_destroy_devinfo(&di->obdinfo); - free(di, M_DEVBUF); - continue; - } - device_set_ivars(cdev, di); - } - - fdt_pinctrl_register(dev, "atmel,pins"); - - return (bus_generic_attach(dev)); -} - -static const struct ofw_bus_devinfo * -pinctrl_get_devinfo(device_t bus __unused, device_t child) -{ - struct pinctrl_devinfo *ndi; - - ndi = device_get_ivars(child); - return (&ndi->obdinfo); -} - -static struct resource * -pinctrl_alloc_resource(device_t bus, device_t child, int type, int *rid, - u_long start, u_long end, u_long count, u_int flags) -{ - struct pinctrl_softc *sc; - struct pinctrl_devinfo *di; - struct resource_list_entry *rle; - int j; - - sc = device_get_softc(bus); - - /* - * Request for the default allocation with a given rid: use resource - * list stored in the local device info. - */ - if (RMAN_IS_DEFAULT_RANGE(start, end)) { - if ((di = device_get_ivars(child)) == NULL) - return (NULL); - - if (type == SYS_RES_IOPORT) - type = SYS_RES_MEMORY; - - rle = resource_list_find(&di->rl, type, *rid); - if (rle == NULL) { -// if (bootverbose) - device_printf(bus, "no default resources for " - "rid = %d, type = %d\n", *rid, type); - return (NULL); - } - start = rle->start; - end = rle->end; - count = rle->count; - } - - if (type == SYS_RES_MEMORY) { - /* Remap through ranges property */ - for (j = 0; j < sc->nranges; j++) { - if (start >= sc->ranges[j].bus && end < - sc->ranges[j].bus + sc->ranges[j].size) { - start -= sc->ranges[j].bus; - start += sc->ranges[j].host; - end -= sc->ranges[j].bus; - end += sc->ranges[j].host; - break; - } - } - if (j == sc->nranges && sc->nranges != 0) { -// if (bootverbose) - device_printf(bus, "Could not map resource " - "%#lx-%#lx\n", start, end); - - return (NULL); - } - } - - return (bus_generic_alloc_resource(bus, child, type, rid, start, end, - count, flags)); -} - -static int -pinctrl_print_res(struct pinctrl_devinfo *di) -{ - int rv; - - rv = 0; - rv += resource_list_print_type(&di->rl, "mem", SYS_RES_MEMORY, "%#jx"); - rv += resource_list_print_type(&di->rl, "irq", SYS_RES_IRQ, "%jd"); - return (rv); -} - -static void -pinctrl_probe_nomatch(device_t bus, device_t child) -{ - const char *name, *type, *compat; - -// if (!bootverbose) - return; - - name = ofw_bus_get_name(child); - type = ofw_bus_get_type(child); - compat = ofw_bus_get_compat(child); - - device_printf(bus, "<%s>", name != NULL ? name : "unknown"); - pinctrl_print_res(device_get_ivars(child)); - if (!ofw_bus_status_okay(child)) - printf(" disabled"); - if (type) - printf(" type %s", type); - if (compat) - printf(" compat %s", compat); - printf(" (no driver attached)\n"); -} - -static int -pinctrl_print_child(device_t bus, device_t child) -{ - int rv; - - rv = bus_print_child_header(bus, child); - rv += pinctrl_print_res(device_get_ivars(child)); - if (!ofw_bus_status_okay(child)) - rv += printf(" disabled"); - rv += bus_print_child_footer(bus, child); - return (rv); -} - -const char *periphs[] = {"gpio", "periph A", "periph B", "periph C", "periph D", "periph E" }; - -struct pincfg { - uint32_t unit; - uint32_t pin; - uint32_t periph; - uint32_t flags; -}; - -static int -pinctrl_configure_pins(device_t bus, phandle_t cfgxref) -{ - struct pinctrl_softc *sc; - struct pincfg *cfg, *cfgdata; - char name[32]; - phandle_t node; - ssize_t npins; - int i; - - sc = device_get_softc(bus); - node = OF_node_from_xref(cfgxref); - memset(name, 0, sizeof(name)); - OF_getprop(node, "name", name, sizeof(name)); - npins = OF_getencprop_alloc_multi(node, "atmel,pins", sizeof(*cfgdata), - (void **)&cfgdata); - if (npins < 0) { - printf("We're doing it wrong %s\n", name); - return (ENXIO); - } - if (npins == 0) - return (0); - for (i = 0, cfg = cfgdata; i < npins; i++, cfg++) { - uint32_t pio; - pio = (0xfffffff & sc->ranges[0].bus) + 0x200 * cfg->unit; - printf("P%c%d %s %#x\n", cfg->unit + 'A', cfg->pin, - periphs[cfg->periph], cfg->flags); - switch (cfg->periph) { - case 0: - at91_pio_use_gpio(pio, 1u << cfg->pin); - at91_pio_gpio_pullup(pio, 1u << cfg->pin, - !!(cfg->flags & 1)); - at91_pio_gpio_high_z(pio, 1u << cfg->pin, - !!(cfg->flags & 2)); - at91_pio_gpio_set_deglitch(pio, - 1u << cfg->pin, !!(cfg->flags & 4)); -// at91_pio_gpio_pulldown(pio, 1u << cfg->pin, -// !!(cfg->flags & 8)); -// at91_pio_gpio_dis_schmidt(pio, -// 1u << cfg->pin, !!(cfg->flags & 16)); - break; - case 1: - at91_pio_use_periph_a(pio, 1u << cfg->pin, cfg->flags); - break; - case 2: - at91_pio_use_periph_b(pio, 1u << cfg->pin, cfg->flags); - break; - } - } - OF_prop_free(cfgdata); - return (0); -} - -static void -pinctrl_new_pass(device_t bus) -{ - struct pinctrl_softc *sc; - - sc = device_get_softc(bus); - - bus_generic_new_pass(bus); - - if (sc->done_pinmux || bus_current_pass < BUS_PASS_PINMUX) - return; - sc->done_pinmux++; - - fdt_pinctrl_configure_tree(bus); -} - -static device_method_t at91_pinctrl_methods[] = { - DEVMETHOD(device_probe, at91_pinctrl_probe), - DEVMETHOD(device_attach, at91_pinctrl_attach), - - DEVMETHOD(bus_print_child, pinctrl_print_child), - DEVMETHOD(bus_probe_nomatch, pinctrl_probe_nomatch), - DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), - DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), - DEVMETHOD(bus_alloc_resource, pinctrl_alloc_resource), - DEVMETHOD(bus_release_resource, bus_generic_release_resource), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), - DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), - DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), - DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str), - DEVMETHOD(bus_new_pass, pinctrl_new_pass), - - /* ofw_bus interface */ - DEVMETHOD(ofw_bus_get_devinfo, pinctrl_get_devinfo), - DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), - DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), - DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), - DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), - DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), - - /* fdt_pintrl interface */ - DEVMETHOD(fdt_pinctrl_configure,pinctrl_configure_pins), - DEVMETHOD_END -}; - -static driver_t at91_pinctrl_driver = { - "at91_pinctrl", - at91_pinctrl_methods, - sizeof(struct pinctrl_softc), -}; - -static devclass_t at91_pinctrl_devclass; - -EARLY_DRIVER_MODULE(at91_pinctrl, simplebus, at91_pinctrl_driver, - at91_pinctrl_devclass, NULL, NULL, BUS_PASS_BUS); - -/* - * dummy driver to force pass BUS_PASS_PINMUX to happen. - */ -static int -at91_pingroup_probe(device_t dev) -{ - return ENXIO; -} - -static device_method_t at91_pingroup_methods[] = { - DEVMETHOD(device_probe, at91_pingroup_probe), - - DEVMETHOD_END -}; - - -static driver_t at91_pingroup_driver = { - "at91_pingroup", - at91_pingroup_methods, - 0, -}; - -static devclass_t at91_pingroup_devclass; - -EARLY_DRIVER_MODULE(at91_pingroup, at91_pinctrl, at91_pingroup_driver, - at91_pingroup_devclass, NULL, NULL, BUS_PASS_PINMUX); Index: head/sys/arm/at91/at91_pio.c =================================================================== --- head/sys/arm/at91/at91_pio.c +++ head/sys/arm/at91/at91_pio.c @@ -1,655 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2006 M. Warner Losh. - * Copyright (C) 2012 Ian Lepore. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "opt_platform.h" - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#ifdef FDT -#include -#include -#endif - -#define MAX_CHANGE 64 - -struct at91_pio_softc -{ - device_t dev; /* Myself */ - void *intrhand; /* Interrupt handle */ - struct resource *irq_res; /* IRQ resource */ - struct resource *mem_res; /* Memory resource */ - struct sx sc_mtx; /* basically a perimeter lock */ - struct cdev *cdev; - struct selinfo selp; - int buflen; - uint8_t buf[MAX_CHANGE]; - int flags; -#define OPENED 1 -}; - -static inline uint32_t -RD4(struct at91_pio_softc *sc, bus_size_t off) -{ - - return (bus_read_4(sc->mem_res, off)); -} - -static inline void -WR4(struct at91_pio_softc *sc, bus_size_t off, uint32_t val) -{ - - bus_write_4(sc->mem_res, off, val); -} - -#define AT91_PIO_LOCK(_sc) sx_xlock(&(_sc)->sc_mtx) -#define AT91_PIO_UNLOCK(_sc) sx_xunlock(&(_sc)->sc_mtx) -#define AT91_PIO_LOCK_INIT(_sc) \ - sx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev)) -#define AT91_PIO_LOCK_DESTROY(_sc) sx_destroy(&_sc->sc_mtx); -#define AT91_PIO_ASSERT_LOCKED(_sc) sx_assert(&_sc->sc_mtx, SA_XLOCKED); -#define AT91_PIO_ASSERT_UNLOCKED(_sc) sx_assert(&_sc->sc_mtx, SA_UNLOCKED); -#define CDEV2SOFTC(dev) ((dev)->si_drv1) - -static devclass_t at91_pio_devclass; - -/* bus entry points */ - -static int at91_pio_probe(device_t dev); -static int at91_pio_attach(device_t dev); -static int at91_pio_detach(device_t dev); -static void at91_pio_intr(void *); - -/* helper routines */ -static int at91_pio_activate(device_t dev); -static void at91_pio_deactivate(device_t dev); - -/* cdev routines */ -static d_open_t at91_pio_open; -static d_close_t at91_pio_close; -static d_read_t at91_pio_read; -static d_poll_t at91_pio_poll; -static d_ioctl_t at91_pio_ioctl; - -static struct cdevsw at91_pio_cdevsw = -{ - .d_version = D_VERSION, - .d_open = at91_pio_open, - .d_close = at91_pio_close, - .d_read = at91_pio_read, - .d_poll = at91_pio_poll, - .d_ioctl = at91_pio_ioctl -}; - -static int -at91_pio_probe(device_t dev) -{ - const char *name; -#ifdef FDT - if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-gpio")) - return (ENXIO); -#endif - switch (device_get_unit(dev)) { - case 0: - name = "PIOA"; - break; - case 1: - name = "PIOB"; - break; - case 2: - name = "PIOC"; - break; - case 3: - name = "PIOD"; - break; - case 4: - name = "PIOE"; - break; - case 5: - name = "PIOF"; - break; - default: - name = "PIO"; - break; - } - device_set_desc(dev, name); - return (0); -} - -static int -at91_pio_attach(device_t dev) -{ - struct at91_pio_softc *sc; - int err; - - sc = device_get_softc(dev); - sc->dev = dev; - err = at91_pio_activate(dev); - if (err) - goto out; - - if (bootverbose) - device_printf(dev, "ABSR: %#x OSR: %#x PSR:%#x ODSR: %#x\n", - RD4(sc, PIO_ABSR), RD4(sc, PIO_OSR), RD4(sc, PIO_PSR), - RD4(sc, PIO_ODSR)); - AT91_PIO_LOCK_INIT(sc); - - /* - * Activate the interrupt, but disable all interrupts in the hardware. - */ - WR4(sc, PIO_IDR, 0xffffffff); - err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC, - NULL, at91_pio_intr, sc, &sc->intrhand); - if (err) { - AT91_PIO_LOCK_DESTROY(sc); - goto out; - } - sc->cdev = make_dev(&at91_pio_cdevsw, device_get_unit(dev), UID_ROOT, - GID_WHEEL, 0600, "pio%d", device_get_unit(dev)); - if (sc->cdev == NULL) { - err = ENOMEM; - goto out; - } - sc->cdev->si_drv1 = sc; -out: - if (err) - at91_pio_deactivate(dev); - return (err); -} - -static int -at91_pio_detach(device_t dev) -{ - - return (EBUSY); /* XXX */ -} - -static int -at91_pio_activate(device_t dev) -{ - struct at91_pio_softc *sc; - int rid; - - sc = device_get_softc(dev); - rid = 0; - sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - if (sc->mem_res == NULL) - goto errout; - rid = 0; - sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_ACTIVE | RF_SHAREABLE); - if (sc->irq_res == NULL) - goto errout; - return (0); -errout: - at91_pio_deactivate(dev); - return (ENOMEM); -} - -static void -at91_pio_deactivate(device_t dev) -{ - struct at91_pio_softc *sc; - - sc = device_get_softc(dev); - if (sc->intrhand) - bus_teardown_intr(dev, sc->irq_res, sc->intrhand); - sc->intrhand = NULL; - bus_generic_detach(sc->dev); - if (sc->mem_res) - bus_release_resource(dev, SYS_RES_MEMORY, - rman_get_rid(sc->mem_res), sc->mem_res); - sc->mem_res = NULL; - if (sc->irq_res) - bus_release_resource(dev, SYS_RES_IRQ, - rman_get_rid(sc->irq_res), sc->irq_res); - sc->irq_res = NULL; -} - -static void -at91_pio_intr(void *xsc) -{ - struct at91_pio_softc *sc = xsc; - uint32_t status; - int i; - - /* Reading the status also clears the interrupt. */ - status = RD4(sc, PIO_ISR) & RD4(sc, PIO_IMR); - if (status != 0) { - AT91_PIO_LOCK(sc); - for (i = 0; status != 0 && sc->buflen < MAX_CHANGE; ++i) { - if (status & 1) - sc->buf[sc->buflen++] = (uint8_t)i; - status >>= 1; - } - AT91_PIO_UNLOCK(sc); - wakeup(sc); - selwakeup(&sc->selp); - } -} - -static int -at91_pio_open(struct cdev *dev, int oflags, int devtype, struct thread *td) -{ - struct at91_pio_softc *sc; - - sc = CDEV2SOFTC(dev); - AT91_PIO_LOCK(sc); - if (!(sc->flags & OPENED)) { - sc->flags |= OPENED; - } - AT91_PIO_UNLOCK(sc); - return (0); -} - -static int -at91_pio_close(struct cdev *dev, int fflag, int devtype, struct thread *td) -{ - struct at91_pio_softc *sc; - - sc = CDEV2SOFTC(dev); - AT91_PIO_LOCK(sc); - sc->flags &= ~OPENED; - AT91_PIO_UNLOCK(sc); - return (0); -} - -static int -at91_pio_poll(struct cdev *dev, int events, struct thread *td) -{ - struct at91_pio_softc *sc; - int revents = 0; - - sc = CDEV2SOFTC(dev); - AT91_PIO_LOCK(sc); - if (events & (POLLIN | POLLRDNORM)) { - if (sc->buflen != 0) - revents |= events & (POLLIN | POLLRDNORM); - else - selrecord(td, &sc->selp); - } - AT91_PIO_UNLOCK(sc); - - return (revents); -} - -static int -at91_pio_read(struct cdev *dev, struct uio *uio, int flag) -{ - struct at91_pio_softc *sc; - int err, ret, len; - - sc = CDEV2SOFTC(dev); - AT91_PIO_LOCK(sc); - err = 0; - ret = 0; - while (uio->uio_resid) { - while (sc->buflen == 0 && err == 0) - err = msleep(sc, &sc->sc_mtx, PCATCH | PZERO, "prd", 0); - if (err != 0) - break; - len = MIN(sc->buflen, uio->uio_resid); - err = uiomove(sc->buf, len, uio); - if (err != 0) - break; - /* - * If we read the whole thing no datacopy is needed, - * otherwise we move the data down. - */ - ret += len; - if (sc->buflen == len) - sc->buflen = 0; - else { - bcopy(sc->buf + len, sc->buf, sc->buflen - len); - sc->buflen -= len; - } - /* If there's no data left, end the read. */ - if (sc->buflen == 0) - break; - } - AT91_PIO_UNLOCK(sc); - return (err); -} - -static void -at91_pio_bang32(struct at91_pio_softc *sc, uint32_t bits, uint32_t datapin, - uint32_t clockpin) -{ - int i; - - for (i = 0; i < 32; i++) { - if (bits & 0x80000000) - WR4(sc, PIO_SODR, datapin); - else - WR4(sc, PIO_CODR, datapin); - bits <<= 1; - WR4(sc, PIO_CODR, clockpin); - WR4(sc, PIO_SODR, clockpin); - } -} - -static void -at91_pio_bang(struct at91_pio_softc *sc, uint8_t bits, uint32_t bitcount, - uint32_t datapin, uint32_t clockpin) -{ - int i; - - for (i = 0; i < bitcount; i++) { - if (bits & 0x80) - WR4(sc, PIO_SODR, datapin); - else - WR4(sc, PIO_CODR, datapin); - bits <<= 1; - WR4(sc, PIO_CODR, clockpin); - WR4(sc, PIO_SODR, clockpin); - } -} - -static int -at91_pio_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, - struct thread *td) -{ - struct at91_pio_softc *sc; - struct at91_gpio_cfg *cfg; - struct at91_gpio_info *info; - struct at91_gpio_bang *bang; - struct at91_gpio_bang_many *bangmany; - uint32_t i, num; - uint8_t many[1024], *walker; - int err; - int bitcount; - - sc = CDEV2SOFTC(dev); - switch(cmd) { - case AT91_GPIO_SET: /* turn bits on */ - WR4(sc, PIO_SODR, *(uint32_t *)data); - return (0); - case AT91_GPIO_CLR: /* turn bits off */ - WR4(sc, PIO_CODR, *(uint32_t *)data); - return (0); - case AT91_GPIO_READ: /* Get the status of input bits */ - *(uint32_t *)data = RD4(sc, PIO_PDSR); - return (0); - case AT91_GPIO_CFG: /* Configure AT91_GPIO pins */ - cfg = (struct at91_gpio_cfg *)data; - if (cfg->cfgmask & AT91_GPIO_CFG_INPUT) { - WR4(sc, PIO_OER, cfg->iomask & ~cfg->input); - WR4(sc, PIO_ODR, cfg->iomask & cfg->input); - } - if (cfg->cfgmask & AT91_GPIO_CFG_HI_Z) { - WR4(sc, PIO_MDDR, cfg->iomask & ~cfg->hi_z); - WR4(sc, PIO_MDER, cfg->iomask & cfg->hi_z); - } - if (cfg->cfgmask & AT91_GPIO_CFG_PULLUP) { - WR4(sc, PIO_PUDR, cfg->iomask & ~cfg->pullup); - WR4(sc, PIO_PUER, cfg->iomask & cfg->pullup); - } - if (cfg->cfgmask & AT91_GPIO_CFG_GLITCH) { - WR4(sc, PIO_IFDR, cfg->iomask & ~cfg->glitch); - WR4(sc, PIO_IFER, cfg->iomask & cfg->glitch); - } - if (cfg->cfgmask & AT91_GPIO_CFG_GPIO) { - WR4(sc, PIO_PDR, cfg->iomask & ~cfg->gpio); - WR4(sc, PIO_PER, cfg->iomask & cfg->gpio); - } - if (cfg->cfgmask & AT91_GPIO_CFG_PERIPH) { - WR4(sc, PIO_ASR, cfg->iomask & ~cfg->periph); - WR4(sc, PIO_BSR, cfg->iomask & cfg->periph); - } - if (cfg->cfgmask & AT91_GPIO_CFG_INTR) { - WR4(sc, PIO_IDR, cfg->iomask & ~cfg->intr); - WR4(sc, PIO_IER, cfg->iomask & cfg->intr); - } - return (0); - case AT91_GPIO_BANG: - bang = (struct at91_gpio_bang *)data; - at91_pio_bang32(sc, bang->bits, bang->datapin, bang->clockpin); - return (0); - case AT91_GPIO_BANG_MANY: - bangmany = (struct at91_gpio_bang_many *)data; - walker = (uint8_t *)bangmany->bits; - bitcount = bangmany->numbits; - while (bitcount > 0) { - num = MIN((bitcount + 7) / 8, sizeof(many)); - err = copyin(walker, many, num); - if (err) - return err; - for (i = 0; i < num && bitcount > 0; i++, bitcount -= 8) - if (bitcount >= 8) - at91_pio_bang(sc, many[i], 8, bangmany->datapin, bangmany->clockpin); - else - at91_pio_bang(sc, many[i], bitcount, bangmany->datapin, bangmany->clockpin); - walker += num; - } - return (0); - case AT91_GPIO_INFO: /* Learn about this device's AT91_GPIO bits */ - info = (struct at91_gpio_info *)data; - info->output_status = RD4(sc, PIO_ODSR); - info->input_status = RD4(sc, PIO_OSR); - info->highz_status = RD4(sc, PIO_MDSR); - info->pullup_status = RD4(sc, PIO_PUSR); - info->glitch_status = RD4(sc, PIO_IFSR); - info->enabled_status = RD4(sc, PIO_PSR); - info->periph_status = RD4(sc, PIO_ABSR); - info->intr_status = RD4(sc, PIO_IMR); - memset(info->extra_status, 0, sizeof(info->extra_status)); - return (0); - } - return (ENOTTY); -} - -/* - * The following functions are called early in the boot process, so - * don't use bus_space, as that isn't yet available when we need to use - * them. - */ - -void -at91_pio_use_periph_a(uint32_t pio, uint32_t periph_a_mask, int use_pullup) -{ - uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); - - PIO[PIO_ASR / 4] = periph_a_mask; - PIO[PIO_PDR / 4] = periph_a_mask; - if (use_pullup) - PIO[PIO_PUER / 4] = periph_a_mask; - else - PIO[PIO_PUDR / 4] = periph_a_mask; -} - -void -at91_pio_use_periph_b(uint32_t pio, uint32_t periph_b_mask, int use_pullup) -{ - uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); - - PIO[PIO_BSR / 4] = periph_b_mask; - PIO[PIO_PDR / 4] = periph_b_mask; - if (use_pullup) - PIO[PIO_PUER / 4] = periph_b_mask; - else - PIO[PIO_PUDR / 4] = periph_b_mask; -} - -void -at91_pio_use_gpio(uint32_t pio, uint32_t gpio_mask) -{ - uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); - - PIO[PIO_PER / 4] = gpio_mask; -} - -void -at91_pio_gpio_input(uint32_t pio, uint32_t input_enable_mask) -{ - uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); - - PIO[PIO_ODR / 4] = input_enable_mask; -} - -void -at91_pio_gpio_output(uint32_t pio, uint32_t output_enable_mask, int use_pullup) -{ - uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); - - PIO[PIO_OER / 4] = output_enable_mask; - if (use_pullup) - PIO[PIO_PUER / 4] = output_enable_mask; - else - PIO[PIO_PUDR / 4] = output_enable_mask; -} - -void -at91_pio_gpio_high_z(uint32_t pio, uint32_t high_z_mask, int enable) -{ - uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); - - if (enable) - PIO[PIO_MDER / 4] = high_z_mask; - else - PIO[PIO_MDDR / 4] = high_z_mask; -} - -void -at91_pio_gpio_set(uint32_t pio, uint32_t data_mask) -{ - uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); - - PIO[PIO_SODR / 4] = data_mask; -} - -void -at91_pio_gpio_clear(uint32_t pio, uint32_t data_mask) -{ - uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); - - PIO[PIO_CODR / 4] = data_mask; -} - -uint32_t -at91_pio_gpio_get(uint32_t pio, uint32_t data_mask) -{ - uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); - - return (PIO[PIO_PDSR / 4] & data_mask); -} - -void -at91_pio_gpio_set_deglitch(uint32_t pio, uint32_t data_mask, int use_deglitch) -{ - uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); - - if (use_deglitch) - PIO[PIO_IFER / 4] = data_mask; - else - PIO[PIO_IFDR / 4] = data_mask; -} - -void -at91_pio_gpio_pullup(uint32_t pio, uint32_t data_mask, int do_pullup) -{ - uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); - - if (do_pullup) - PIO[PIO_PUER / 4] = data_mask; - else - PIO[PIO_PUDR / 4] = data_mask; -} - -void -at91_pio_gpio_set_interrupt(uint32_t pio, uint32_t data_mask, - int enable_interrupt) -{ - uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); - - if (enable_interrupt) - PIO[PIO_IER / 4] = data_mask; - else - PIO[PIO_IDR / 4] = data_mask; -} - -uint32_t -at91_pio_gpio_clear_interrupt(uint32_t pio) -{ - uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); - - /* Reading this register will clear the interrupts. */ - return (PIO[PIO_ISR / 4]); -} - -static void -at91_pio_new_pass(device_t dev) -{ - - device_printf(dev, "Pass %d\n", bus_current_pass); -} - -static device_method_t at91_pio_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, at91_pio_probe), - DEVMETHOD(device_attach, at91_pio_attach), - DEVMETHOD(device_detach, at91_pio_detach), - - DEVMETHOD(bus_new_pass, at91_pio_new_pass), - - DEVMETHOD_END -}; - -static driver_t at91_pio_driver = { - "at91_pio", - at91_pio_methods, - sizeof(struct at91_pio_softc), -}; - -#ifdef FDT -EARLY_DRIVER_MODULE(at91_pio, at91_pinctrl, at91_pio_driver, at91_pio_devclass, - NULL, NULL, BUS_PASS_INTERRUPT); -#else -DRIVER_MODULE(at91_pio, atmelarm, at91_pio_driver, at91_pio_devclass, NULL, NULL); -#endif Index: head/sys/arm/at91/at91_pio_sam9g20.h =================================================================== --- head/sys/arm/at91/at91_pio_sam9g20.h +++ head/sys/arm/at91/at91_pio_sam9g20.h @@ -1,183 +0,0 @@ -/* - * Theses defines come from an atmel file that says specifically that it - * has no copyright. - * - * These defines are also usable for the AT91SAM9260 which has pin multiplexing - * that is identical to the AT91SAM9G20. - */ - -/* $FreeBSD$ */ - -#ifndef ARM_AT91_AT91_PIO_SAM9G20_H -#define ARM_AT91_AT91_PIO_SAM9G20_H - -#include - - -// ***************************************************************************** -// 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 */ Index: head/sys/arm/at91/at91_pio_sam9g45.h =================================================================== --- head/sys/arm/at91/at91_pio_sam9g45.h +++ head/sys/arm/at91/at91_pio_sam9g45.h @@ -1,274 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * ---------------------------------------------------------------------------- - * ATMEL Microcontroller Software Support - ROUSSET - - * ---------------------------------------------------------------------------- - * Copyright (c) 2009, Atmel Corporation - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the disclaimer below. - * - * Atmel's name may not be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * ---------------------------------------------------------------------------- - * - * From AT91LIB version 1.9 boards/at91sam9g45-ek/at91sam9g45/AT91SAM9G45.h - */ - -/* $FreeBSD$ */ - -#ifndef ARM_AT91_AT91_PIO_SAM9G45_H -#define ARM_AT91_AT91_PIO_SAM9G45_H - -#include - -// ***************************************************************************** -// PIO DEFINITIONS FOR AT91SAM9G45 -// ***************************************************************************** -#define AT91C_PA0_MCI0_CK (AT91C_PIO_PA0) // -#define AT91C_PA0_TCLK3 (AT91C_PIO_PA0) // -#define AT91C_PA1_MCI0_CDA (AT91C_PIO_PA1) // -#define AT91C_PA1_TIOA3 (AT91C_PIO_PA1) // -#define AT91C_PA10_ETX0 (AT91C_PIO_PA10) // Ethernet MAC Transmit Data 0 -#define AT91C_PA11_ETX1 (AT91C_PIO_PA11) // Ethernet MAC Transmit Data 1 -#define AT91C_PA12_ERX0 (AT91C_PIO_PA12) // Ethernet MAC Receive Data 0 -#define AT91C_PA13_ERX1 (AT91C_PIO_PA13) // Ethernet MAC Receive Data 1 -#define AT91C_PA14_ETXEN (AT91C_PIO_PA14) // Ethernet MAC Transmit Enable -#define AT91C_PA15_ERXDV (AT91C_PIO_PA15) // Ethernet MAC Receive Data Valid -#define AT91C_PA16_ERXER (AT91C_PIO_PA16) // Ethernet MAC Receive Error -#define AT91C_PA17_ETXCK_EREFCK (AT91C_PIO_PA17) // Ethernet MAC Transmit Clock/Reference Clock -#define AT91C_PA18_EMDC (AT91C_PIO_PA18) // Ethernet MAC Management Data Clock -#define AT91C_PA19_EMDIO (AT91C_PIO_PA19) // Ethernet MAC Management Data Input/Output -#define AT91C_PA2_MCI0_DA0 (AT91C_PIO_PA2) // -#define AT91C_PA2_TIOB3 (AT91C_PIO_PA2) // -#define AT91C_PA20_TWD0 (AT91C_PIO_PA20) // TWI Two-wire Serial Data -#define AT91C_PA21_TWCK0 (AT91C_PIO_PA21) // TWI Two-wire Serial Clock -#define AT91C_PA22_MCI1_CDA (AT91C_PIO_PA22) // -#define AT91C_PA22_SCK3 (AT91C_PIO_PA22) // -#define AT91C_PA23_MCI1_DA0 (AT91C_PIO_PA23) // -#define AT91C_PA23_RTS3 (AT91C_PIO_PA23) // -#define AT91C_PA24_MCI1_DA1 (AT91C_PIO_PA24) // -#define AT91C_PA24_CTS3 (AT91C_PIO_PA24) // -#define AT91C_PA25_MCI1_DA2 (AT91C_PIO_PA25) // -#define AT91C_PA25_PWM3 (AT91C_PIO_PA25) // -#define AT91C_PA26_MCI1_DA3 (AT91C_PIO_PA26) // -#define AT91C_PA26_TIOB2 (AT91C_PIO_PA26) // -#define AT91C_PA27_MCI1_DA4 (AT91C_PIO_PA27) // -#define AT91C_PA27_ETXER (AT91C_PIO_PA27) // Ethernet MAC Transmikt Coding Error -#define AT91C_PA28_MCI1_DA5 (AT91C_PIO_PA28) // -#define AT91C_PA28_ERXCK (AT91C_PIO_PA28) // Ethernet MAC Receive Clock -#define AT91C_PA29_MCI1_DA6 (AT91C_PIO_PA29) // -#define AT91C_PA29_ECRS (AT91C_PIO_PA29) // Ethernet MAC Carrier Sense/Carrier Sense and Data Valid -#define AT91C_PA3_MCI0_DA1 (AT91C_PIO_PA3) // -#define AT91C_PA3_TCLK4 (AT91C_PIO_PA3) // -#define AT91C_PA30_MCI1_DA7 (AT91C_PIO_PA30) // -#define AT91C_PA30_ECOL (AT91C_PIO_PA30) // Ethernet MAC Collision Detected -#define AT91C_PA31_MCI1_CK (AT91C_PIO_PA31) // -#define AT91C_PA31_PCK0 (AT91C_PIO_PA31) // -#define AT91C_PA4_MCI0_DA2 (AT91C_PIO_PA4) // -#define AT91C_PA4_TIOA4 (AT91C_PIO_PA4) // -#define AT91C_PA5_MCI0_DA3 (AT91C_PIO_PA5) // -#define AT91C_PA5_TIOB4 (AT91C_PIO_PA5) // -#define AT91C_PA6_MCI0_DA4 (AT91C_PIO_PA6) // -#define AT91C_PA6_ETX2 (AT91C_PIO_PA6) // Ethernet MAC Transmit Data 2 -#define AT91C_PA7_MCI0_DA5 (AT91C_PIO_PA7) // -#define AT91C_PA7_ETX3 (AT91C_PIO_PA7) // Ethernet MAC Transmit Data 3 -#define AT91C_PA8_MCI0_DA6 (AT91C_PIO_PA8) // -#define AT91C_PA8_ERX2 (AT91C_PIO_PA8) // Ethernet MAC Receive Data 2 -#define AT91C_PA9_MCI0_DA7 (AT91C_PIO_PA9) // -#define AT91C_PA9_ERX3 (AT91C_PIO_PA9) // Ethernet MAC Receive Data 3 -#define AT91C_PB0_SPI0_MISO (AT91C_PIO_PB0) // SPI 0 Master In Slave -#define AT91C_PB1_SPI0_MOSI (AT91C_PIO_PB1) // SPI 0 Master Out Slave -#define AT91C_PB10_TWD1 (AT91C_PIO_PB10) // -#define AT91C_PB10_ISI_D10 (AT91C_PIO_PB10) // -#define AT91C_PB11_TWCK1 (AT91C_PIO_PB11) // -#define AT91C_PB11_ISI_D11 (AT91C_PIO_PB11) // -#define AT91C_PB12_DRXD (AT91C_PIO_PB12) // -#define AT91C_PB13_DTXD (AT91C_PIO_PB13) // -#define AT91C_PB14_SPI1_MISO (AT91C_PIO_PB14) // -#define AT91C_PB15_SPI1_MOSI (AT91C_PIO_PB15) // -#define AT91C_PB15_CTS0 (AT91C_PIO_PB15) // -#define AT91C_PB16_SPI1_SPCK (AT91C_PIO_PB16) // -#define AT91C_PB16_SCK0 (AT91C_PIO_PB16) // -#define AT91C_PB17_SPI1_NPCS0 (AT91C_PIO_PB17) // -#define AT91C_PB17_RTS0 (AT91C_PIO_PB17) // -#define AT91C_PB18_RXD0 (AT91C_PIO_PB18) // -#define AT91C_PB18_SPI0_NPCS1 (AT91C_PIO_PB18) // -#define AT91C_PB19_TXD0 (AT91C_PIO_PB19) // -#define AT91C_PB19_SPI0_NPCS2 (AT91C_PIO_PB19) // -#define AT91C_PB2_SPI0_SPCK (AT91C_PIO_PB2) // SPI 0 Serial Clock -#define AT91C_PB20_ISI_D0 (AT91C_PIO_PB20) // -#define AT91C_PB21_ISI_D1 (AT91C_PIO_PB21) // -#define AT91C_PB22_ISI_D2 (AT91C_PIO_PB22) // -#define AT91C_PB23_ISI_D3 (AT91C_PIO_PB23) // -#define AT91C_PB24_ISI_D4 (AT91C_PIO_PB24) // -#define AT91C_PB25_ISI_D5 (AT91C_PIO_PB25) // -#define AT91C_PB26_ISI_D6 (AT91C_PIO_PB26) // -#define AT91C_PB27_ISI_D7 (AT91C_PIO_PB27) // -#define AT91C_PB28_ISI_PCK (AT91C_PIO_PB28) // -#define AT91C_PB29_ISI_VSYNC (AT91C_PIO_PB29) // -#define AT91C_PB3_SPI0_NPCS0 (AT91C_PIO_PB3) // SPI 0 Peripheral Chip Select 0 -#define AT91C_PB30_ISI_HSYNC (AT91C_PIO_PB30) // -#define AT91C_PB31_ (AT91C_PIO_PB31) // -#define AT91C_PB31_PCK1 (AT91C_PIO_PB31) // -#define AT91C_PB4_TXD1 (AT91C_PIO_PB4) // USART 1 Transmit Data -#define AT91C_PB5_RXD1 (AT91C_PIO_PB5) // USART 1 Receive Data -#define AT91C_PB6_TXD2 (AT91C_PIO_PB6) // USART 2 Transmit Data -#define AT91C_PB7_RXD2 (AT91C_PIO_PB7) // USART 2 Receive Data -#define AT91C_PB8_TXD3 (AT91C_PIO_PB8) // USART 3 Transmit Data -#define AT91C_PB8_ISI_D8 (AT91C_PIO_PB8) // -#define AT91C_PB9_RXD3 (AT91C_PIO_PB9) // USART 3 Receive Data -#define AT91C_PB9_ISI_D9 (AT91C_PIO_PB9) // -#define AT91C_PC0_DQM2 (AT91C_PIO_PC0) // DQM2 -#define AT91C_PC1_DQM3 (AT91C_PIO_PC1) // DQM3 -#define AT91C_PC10_NCS4_CFCS0 (AT91C_PIO_PC10) // -#define AT91C_PC10_TCLK2 (AT91C_PIO_PC10) // -#define AT91C_PC11_NCS5_CFCS1 (AT91C_PIO_PC11) // -#define AT91C_PC11_CTS2 (AT91C_PIO_PC11) // -#define AT91C_PC12_A25_CFRNW (AT91C_PIO_PC12) // -#define AT91C_PC13_NCS2 (AT91C_PIO_PC13) // -#define AT91C_PC14_NCS3_NANDCS (AT91C_PIO_PC14) // -#define AT91C_PC15_NWAIT (AT91C_PIO_PC15) // -#define AT91C_PC16_D16 (AT91C_PIO_PC16) // -#define AT91C_PC17_D17 (AT91C_PIO_PC17) // -#define AT91C_PC18_D18 (AT91C_PIO_PC18) // -#define AT91C_PC19_D19 (AT91C_PIO_PC19) // -#define AT91C_PC2_A19 (AT91C_PIO_PC2) // -#define AT91C_PC20_D20 (AT91C_PIO_PC20) // -#define AT91C_PC21_D21 (AT91C_PIO_PC21) // -#define AT91C_PC22_D22 (AT91C_PIO_PC22) // -#define AT91C_PC23_D23 (AT91C_PIO_PC23) // -#define AT91C_PC24_D24 (AT91C_PIO_PC24) // -#define AT91C_PC25_D25 (AT91C_PIO_PC25) // -#define AT91C_PC26_D26 (AT91C_PIO_PC26) // -#define AT91C_PC27_D27 (AT91C_PIO_PC27) // -#define AT91C_PC28_D28 (AT91C_PIO_PC28) // -#define AT91C_PC29_D29 (AT91C_PIO_PC29) // -#define AT91C_PC3_A20 (AT91C_PIO_PC3) // -#define AT91C_PC30_D30 (AT91C_PIO_PC30) // -#define AT91C_PC31_D31 (AT91C_PIO_PC31) // -#define AT91C_PC4_A21_NANDALE (AT91C_PIO_PC4) // -#define AT91C_PC5_A22_NANDCLE (AT91C_PIO_PC5) // -#define AT91C_PC6_A23 (AT91C_PIO_PC6) // -#define AT91C_PC7_A24 (AT91C_PIO_PC7) // -#define AT91C_PC8_CFCE1 (AT91C_PIO_PC8) // -#define AT91C_PC9_CFCE2 (AT91C_PIO_PC9) // -#define AT91C_PC9_RTS2 (AT91C_PIO_PC9) // -#define AT91C_PD0_TK0 (AT91C_PIO_PD0) // -#define AT91C_PD0_PWM3 (AT91C_PIO_PD0) // -#define AT91C_PD1_TF0 (AT91C_PIO_PD1) // -#define AT91C_PD10_TD1 (AT91C_PIO_PD10) // -#define AT91C_PD11_RD1 (AT91C_PIO_PD11) // -#define AT91C_PD12_TK1 (AT91C_PIO_PD12) // -#define AT91C_PD12_PCK0 (AT91C_PIO_PD12) // -#define AT91C_PD13_RK1 (AT91C_PIO_PD13) // -#define AT91C_PD14_TF1 (AT91C_PIO_PD14) // -#define AT91C_PD15_RF1 (AT91C_PIO_PD15) // -#define AT91C_PD16_RTS1 (AT91C_PIO_PD16) // -#define AT91C_PD17_CTS1 (AT91C_PIO_PD17) // -#define AT91C_PD18_SPI1_NPCS2 (AT91C_PIO_PD18) // -#define AT91C_PD18_IRQ (AT91C_PIO_PD18) // -#define AT91C_PD19_SPI1_NPCS3 (AT91C_PIO_PD19) // -#define AT91C_PD19_FIQ (AT91C_PIO_PD19) // -#define AT91C_PD2_TD0 (AT91C_PIO_PD2) // -#define AT91C_PD20_TIOA0 (AT91C_PIO_PD20) // -#define AT91C_PD21_TIOA1 (AT91C_PIO_PD21) // -#define AT91C_PD22_TIOA2 (AT91C_PIO_PD22) // -#define AT91C_PD23_TCLK0 (AT91C_PIO_PD23) // -#define AT91C_PD24_SPI0_NPCS1 (AT91C_PIO_PD24) // -#define AT91C_PD24_PWM0 (AT91C_PIO_PD24) // -#define AT91C_PD25_SPI0_NPCS2 (AT91C_PIO_PD25) // -#define AT91C_PD25_PWM1 (AT91C_PIO_PD25) // -#define AT91C_PD26_PCK0 (AT91C_PIO_PD26) // -#define AT91C_PD26_PWM2 (AT91C_PIO_PD26) // -#define AT91C_PD27_PCK1 (AT91C_PIO_PD27) // -#define AT91C_PD27_SPI0_NPCS3 (AT91C_PIO_PD27) // -#define AT91C_PD28_TSADTRG (AT91C_PIO_PD28) // -#define AT91C_PD28_SPI1_NPCS1 (AT91C_PIO_PD28) // -#define AT91C_PD29_TCLK1 (AT91C_PIO_PD29) // -#define AT91C_PD29_SCK1 (AT91C_PIO_PD29) // -#define AT91C_PD3_RD0 (AT91C_PIO_PD3) // -#define AT91C_PD30_TIOB0 (AT91C_PIO_PD30) // -#define AT91C_PD30_SCK2 (AT91C_PIO_PD30) // -#define AT91C_PD31_TIOB1 (AT91C_PIO_PD31) // -#define AT91C_PD31_PWM1 (AT91C_PIO_PD31) // -#define AT91C_PD4_RK0 (AT91C_PIO_PD4) // -#define AT91C_PD5_RF0 (AT91C_PIO_PD5) // -#define AT91C_PD6_AC97RX (AT91C_PIO_PD6) // -#define AT91C_PD7_AC97TX (AT91C_PIO_PD7) // -#define AT91C_PD7_TIOA5 (AT91C_PIO_PD7) // -#define AT91C_PD8_AC97FS (AT91C_PIO_PD8) // -#define AT91C_PD8_TIOB5 (AT91C_PIO_PD8) // -#define AT91C_PD9_AC97CK (AT91C_PIO_PD9) // -#define AT91C_PD9_TCLK5 (AT91C_PIO_PD9) // -#define AT91C_PE0_LCDPWR (AT91C_PIO_PE0) // -#define AT91C_PE0_PCK0 (AT91C_PIO_PE0) // -#define AT91C_PE1_LCDMOD (AT91C_PIO_PE1) // -#define AT91C_PE10_LCDD3 (AT91C_PIO_PE10) // -#define AT91C_PE10_LCDD5 (AT91C_PIO_PE10) // -#define AT91C_PE11_LCDD4 (AT91C_PIO_PE11) // -#define AT91C_PE11_LCDD6 (AT91C_PIO_PE11) // -#define AT91C_PE12_LCDD5 (AT91C_PIO_PE12) // -#define AT91C_PE12_LCDD7 (AT91C_PIO_PE12) // -#define AT91C_PE13_LCDD6 (AT91C_PIO_PE13) // -#define AT91C_PE13_LCDD10 (AT91C_PIO_PE13) // -#define AT91C_PE14_LCDD7 (AT91C_PIO_PE14) // -#define AT91C_PE14_LCDD11 (AT91C_PIO_PE14) // -#define AT91C_PE15_LCDD8 (AT91C_PIO_PE15) // -#define AT91C_PE15_LCDD12 (AT91C_PIO_PE15) // -#define AT91C_PE16_LCDD9 (AT91C_PIO_PE16) // -#define AT91C_PE16_LCDD13 (AT91C_PIO_PE16) // -#define AT91C_PE17_LCDD10 (AT91C_PIO_PE17) // -#define AT91C_PE17_LCDD14 (AT91C_PIO_PE17) // -#define AT91C_PE18_LCDD11 (AT91C_PIO_PE18) // -#define AT91C_PE18_LCDD15 (AT91C_PIO_PE18) // -#define AT91C_PE19_LCDD12 (AT91C_PIO_PE19) // -#define AT91C_PE19_LCDD18 (AT91C_PIO_PE19) // -#define AT91C_PE2_LCDCC (AT91C_PIO_PE2) // -#define AT91C_PE20_LCDD13 (AT91C_PIO_PE20) // -#define AT91C_PE20_LCDD19 (AT91C_PIO_PE20) // -#define AT91C_PE21_LCDD14 (AT91C_PIO_PE21) // -#define AT91C_PE21_LCDD20 (AT91C_PIO_PE21) // -#define AT91C_PE22_LCDD15 (AT91C_PIO_PE22) // -#define AT91C_PE22_LCDD21 (AT91C_PIO_PE22) // -#define AT91C_PE23_LCDD16 (AT91C_PIO_PE23) // -#define AT91C_PE23_LCDD22 (AT91C_PIO_PE23) // -#define AT91C_PE24_LCDD17 (AT91C_PIO_PE24) // -#define AT91C_PE24_LCDD23 (AT91C_PIO_PE24) // -#define AT91C_PE25_LCDD18 (AT91C_PIO_PE25) // -#define AT91C_PE26_LCDD19 (AT91C_PIO_PE26) // -#define AT91C_PE27_LCDD20 (AT91C_PIO_PE27) // -#define AT91C_PE28_LCDD21 (AT91C_PIO_PE28) // -#define AT91C_PE29_LCDD22 (AT91C_PIO_PE29) // -#define AT91C_PE3_LCDVSYNC (AT91C_PIO_PE3) // -#define AT91C_PE30_LCDD23 (AT91C_PIO_PE30) // -#define AT91C_PE31_PWM2 (AT91C_PIO_PE31) // -#define AT91C_PE31_PCK1 (AT91C_PIO_PE31) // -#define AT91C_PE4_LCDHSYNC (AT91C_PIO_PE4) // -#define AT91C_PE5_LCDDOTCK (AT91C_PIO_PE5) // -#define AT91C_PE6_LCDDEN (AT91C_PIO_PE6) // -#define AT91C_PE7_LCDD0 (AT91C_PIO_PE7) // -#define AT91C_PE7_LCDD2 (AT91C_PIO_PE7) // -#define AT91C_PE8_LCDD1 (AT91C_PIO_PE8) // -#define AT91C_PE8_LCDD3 (AT91C_PIO_PE8) // -#define AT91C_PE9_LCDD2 (AT91C_PIO_PE9) // -#define AT91C_PE9_LCDD4 (AT91C_PIO_PE9) // - -#endif /* ARM_AT91_AT91_PIO_SAM9G45_H */ Index: head/sys/arm/at91/at91_pioreg.h =================================================================== --- head/sys/arm/at91/at91_pioreg.h +++ head/sys/arm/at91/at91_pioreg.h @@ -1,234 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2006 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef ARM_AT91_AT91_PIOREG_H -#define ARM_AT91_AT91_PIOREG_H - -#ifndef ATMEL_ENV -/* Registers */ -#define PIO_PER 0x00 /* PIO Enable Register */ -#define PIO_PDR 0x04 /* PIO Disable Register */ -#define PIO_PSR 0x08 /* PIO Status Register */ - /* 0x0c reserved */ -#define PIO_OER 0x10 /* PIO Output Enable Register */ -#define PIO_ODR 0x14 /* PIO Output Disable Register */ -#define PIO_OSR 0x18 /* PIO Output Status Register */ - /* 0x1c reserved */ -#define PIO_IFER 0x20 /* PIO Glitch Input Enable Register */ -#define PIO_IFDR 0x24 /* PIO Glitch Input Disable Register */ -#define PIO_IFSR 0x28 /* PIO Glitch Input Status Register */ - /* 0x2c reserved */ -#define PIO_SODR 0x30 /* PIO Set Output Data Register */ -#define PIO_CODR 0x34 /* PIO Clear Output Data Register */ -#define PIO_ODSR 0x38 /* PIO Output Data Status Register */ -#define PIO_PDSR 0x3c /* PIO Pin Data Status Register */ -#define PIO_IER 0x40 /* PIO Interrupt Enable Register */ -#define PIO_IDR 0x44 /* PIO Interrupt Disable Register */ -#define PIO_IMR 0x48 /* PIO Interrupt Mask Register */ -#define PIO_ISR 0x4c /* PIO Interrupt Status Register */ -#define PIO_MDER 0x50 /* PIO Multi-Driver Enable Register */ -#define PIO_MDDR 0x54 /* PIO Multi-Driver Disable Register */ -#define PIO_MDSR 0x58 /* PIO Multi-Driver Status Register */ - /* 0x5c reserved */ -#define PIO_PUDR 0x60 /* PIO Pull-up Disable Register */ -#define PIO_PUER 0x64 /* PIO Pull-up Enable Register */ -#define PIO_PUSR 0x68 /* PIO Pull-up Status Register */ - /* 0x6c reserved */ -#define PIO_ASR 0x70 /* PIO Peripheral A Select Register */ -#define PIO_BSR 0x74 /* PIO Peripheral B Select Register */ -#define PIO_ABSR 0x78 /* PIO AB Status Register */ - /* 0x7c-0x9c reserved */ -#define PIO_OWER 0xa0 /* PIO Output Write Enable Register */ -#define PIO_OWDR 0xa4 /* PIO Output Write Disable Register */ -#define PIO_OWSR 0xa8 /* PIO Output Write Status Register */ - /* 0xac reserved */ -#endif - -#define AT91C_PIO_PA0 ((unsigned int) 1 << 0) // Pin Controlled by PA0 -#define AT91C_PIO_PA1 ((unsigned int) 1 << 1) // Pin Controlled by PA1 -#define AT91C_PIO_PA2 ((unsigned int) 1 << 2) // Pin Controlled by PA2 -#define AT91C_PIO_PA3 ((unsigned int) 1 << 3) // Pin Controlled by PA3 -#define AT91C_PIO_PA4 ((unsigned int) 1 << 4) // Pin Controlled by PA4 -#define AT91C_PIO_PA5 ((unsigned int) 1 << 5) // Pin Controlled by PA5 -#define AT91C_PIO_PA6 ((unsigned int) 1 << 6) // Pin Controlled by PA6 -#define AT91C_PIO_PA7 ((unsigned int) 1 << 7) // Pin Controlled by PA7 -#define AT91C_PIO_PA8 ((unsigned int) 1 << 8) // Pin Controlled by PA8 -#define AT91C_PIO_PA9 ((unsigned int) 1 << 9) // Pin Controlled by PA9 -#define AT91C_PIO_PA10 ((unsigned int) 1 << 10) // Pin Controlled by PA10 -#define AT91C_PIO_PA11 ((unsigned int) 1 << 11) // Pin Controlled by PA11 -#define AT91C_PIO_PA12 ((unsigned int) 1 << 12) // Pin Controlled by PA12 -#define AT91C_PIO_PA13 ((unsigned int) 1 << 13) // Pin Controlled by PA13 -#define AT91C_PIO_PA14 ((unsigned int) 1 << 14) // Pin Controlled by PA14 -#define AT91C_PIO_PA15 ((unsigned int) 1 << 15) // Pin Controlled by PA15 -#define AT91C_PIO_PA16 ((unsigned int) 1 << 16) // Pin Controlled by PA16 -#define AT91C_PIO_PA17 ((unsigned int) 1 << 17) // Pin Controlled by PA17 -#define AT91C_PIO_PA18 ((unsigned int) 1 << 18) // Pin Controlled by PA18 -#define AT91C_PIO_PA19 ((unsigned int) 1 << 19) // Pin Controlled by PA19 -#define AT91C_PIO_PA20 ((unsigned int) 1 << 20) // Pin Controlled by PA20 -#define AT91C_PIO_PA21 ((unsigned int) 1 << 21) // Pin Controlled by PA21 -#define AT91C_PIO_PA22 ((unsigned int) 1 << 22) // Pin Controlled by PA22 -#define AT91C_PIO_PA23 ((unsigned int) 1 << 23) // Pin Controlled by PA23 -#define AT91C_PIO_PA24 ((unsigned int) 1 << 24) // Pin Controlled by PA24 -#define AT91C_PIO_PA25 ((unsigned int) 1 << 25) // Pin Controlled by PA25 -#define AT91C_PIO_PA26 ((unsigned int) 1 << 26) // Pin Controlled by PA26 -#define AT91C_PIO_PA27 ((unsigned int) 1 << 27) // Pin Controlled by PA27 -#define AT91C_PIO_PA28 ((unsigned int) 1 << 28) // Pin Controlled by PA28 -#define AT91C_PIO_PA29 ((unsigned int) 1 << 29) // Pin Controlled by PA29 -#define AT91C_PIO_PA30 ((unsigned int) 1 << 30) // Pin Controlled by PA30 -#define AT91C_PIO_PA31 ((unsigned int) 1 << 31) // Pin Controlled by PA31 -#define AT91C_PIO_PB0 ((unsigned int) 1 << 0) // Pin Controlled by PB0 -#define AT91C_PIO_PB1 ((unsigned int) 1 << 1) // Pin Controlled by PB1 -#define AT91C_PIO_PB2 ((unsigned int) 1 << 2) // Pin Controlled by PB2 -#define AT91C_PIO_PB3 ((unsigned int) 1 << 3) // Pin Controlled by PB3 -#define AT91C_PIO_PB4 ((unsigned int) 1 << 4) // Pin Controlled by PB4 -#define AT91C_PIO_PB5 ((unsigned int) 1 << 5) // Pin Controlled by PB5 -#define AT91C_PIO_PB6 ((unsigned int) 1 << 6) // Pin Controlled by PB6 -#define AT91C_PIO_PB7 ((unsigned int) 1 << 7) // Pin Controlled by PB7 -#define AT91C_PIO_PB8 ((unsigned int) 1 << 8) // Pin Controlled by PB8 -#define AT91C_PIO_PB9 ((unsigned int) 1 << 9) // Pin Controlled by PB9 -#define AT91C_PIO_PB10 ((unsigned int) 1 << 10) // Pin Controlled by PB10 -#define AT91C_PIO_PB11 ((unsigned int) 1 << 11) // Pin Controlled by PB11 -#define AT91C_PIO_PB12 ((unsigned int) 1 << 12) // Pin Controlled by PB12 -#define AT91C_PIO_PB13 ((unsigned int) 1 << 13) // Pin Controlled by PB13 -#define AT91C_PIO_PB14 ((unsigned int) 1 << 14) // Pin Controlled by PB14 -#define AT91C_PIO_PB15 ((unsigned int) 1 << 15) // Pin Controlled by PB15 -#define AT91C_PIO_PB16 ((unsigned int) 1 << 16) // Pin Controlled by PB16 -#define AT91C_PIO_PB17 ((unsigned int) 1 << 17) // Pin Controlled by PB17 -#define AT91C_PIO_PB18 ((unsigned int) 1 << 18) // Pin Controlled by PB18 -#define AT91C_PIO_PB19 ((unsigned int) 1 << 19) // Pin Controlled by PB19 -#define AT91C_PIO_PB20 ((unsigned int) 1 << 20) // Pin Controlled by PB20 -#define AT91C_PIO_PB21 ((unsigned int) 1 << 21) // Pin Controlled by PB21 -#define AT91C_PIO_PB22 ((unsigned int) 1 << 22) // Pin Controlled by PB22 -#define AT91C_PIO_PB23 ((unsigned int) 1 << 23) // Pin Controlled by PB23 -#define AT91C_PIO_PB24 ((unsigned int) 1 << 24) // Pin Controlled by PB24 -#define AT91C_PIO_PB25 ((unsigned int) 1 << 25) // Pin Controlled by PB25 -#define AT91C_PIO_PB26 ((unsigned int) 1 << 26) // Pin Controlled by PB26 -#define AT91C_PIO_PB27 ((unsigned int) 1 << 27) // Pin Controlled by PB27 -#define AT91C_PIO_PB28 ((unsigned int) 1 << 28) // Pin Controlled by PB28 -#define AT91C_PIO_PB29 ((unsigned int) 1 << 29) // Pin Controlled by PB29 -#define AT91C_PIO_PB30 ((unsigned int) 1 << 30) // Pin Controlled by PB30 -#define AT91C_PIO_PB31 ((unsigned int) 1 << 31) // Pin Controlled by PB31 -#define AT91C_PIO_PC0 ((unsigned int) 1 << 0) // Pin Controlled by PC0 -#define AT91C_PIO_PC1 ((unsigned int) 1 << 1) // Pin Controlled by PC1 -#define AT91C_PIO_PC2 ((unsigned int) 1 << 2) // Pin Controlled by PC2 -#define AT91C_PIO_PC3 ((unsigned int) 1 << 3) // Pin Controlled by PC3 -#define AT91C_PIO_PC4 ((unsigned int) 1 << 4) // Pin Controlled by PC4 -#define AT91C_PIO_PC5 ((unsigned int) 1 << 5) // Pin Controlled by PC5 -#define AT91C_PIO_PC6 ((unsigned int) 1 << 6) // Pin Controlled by PC6 -#define AT91C_PIO_PC7 ((unsigned int) 1 << 7) // Pin Controlled by PC7 -#define AT91C_PIO_PC8 ((unsigned int) 1 << 8) // Pin Controlled by PC8 -#define AT91C_PIO_PC9 ((unsigned int) 1 << 9) // Pin Controlled by PC9 -#define AT91C_PIO_PC10 ((unsigned int) 1 << 10) // Pin Controlled by PC10 -#define AT91C_PIO_PC11 ((unsigned int) 1 << 11) // Pin Controlled by PC11 -#define AT91C_PIO_PC12 ((unsigned int) 1 << 12) // Pin Controlled by PC12 -#define AT91C_PIO_PC13 ((unsigned int) 1 << 13) // Pin Controlled by PC13 -#define AT91C_PIO_PC14 ((unsigned int) 1 << 14) // Pin Controlled by PC14 -#define AT91C_PIO_PC15 ((unsigned int) 1 << 15) // Pin Controlled by PC15 -#define AT91C_PIO_PC16 ((unsigned int) 1 << 16) // Pin Controlled by PC16 -#define AT91C_PIO_PC17 ((unsigned int) 1 << 17) // Pin Controlled by PC17 -#define AT91C_PIO_PC18 ((unsigned int) 1 << 18) // Pin Controlled by PC18 -#define AT91C_PIO_PC19 ((unsigned int) 1 << 19) // Pin Controlled by PC19 -#define AT91C_PIO_PC20 ((unsigned int) 1 << 20) // Pin Controlled by PC20 -#define AT91C_PIO_PC21 ((unsigned int) 1 << 21) // Pin Controlled by PC21 -#define AT91C_PIO_PC22 ((unsigned int) 1 << 22) // Pin Controlled by PC22 -#define AT91C_PIO_PC23 ((unsigned int) 1 << 23) // Pin Controlled by PC23 -#define AT91C_PIO_PC24 ((unsigned int) 1 << 24) // Pin Controlled by PC24 -#define AT91C_PIO_PC25 ((unsigned int) 1 << 25) // Pin Controlled by PC25 -#define AT91C_PIO_PC26 ((unsigned int) 1 << 26) // Pin Controlled by PC26 -#define AT91C_PIO_PC27 ((unsigned int) 1 << 27) // Pin Controlled by PC27 -#define AT91C_PIO_PC28 ((unsigned int) 1 << 28) // Pin Controlled by PC28 -#define AT91C_PIO_PC29 ((unsigned int) 1 << 29) // Pin Controlled by PC29 -#define AT91C_PIO_PC30 ((unsigned int) 1 << 30) // Pin Controlled by PC30 -#define AT91C_PIO_PC31 ((unsigned int) 1 << 31) // Pin Controlled by PC31 -#define AT91C_PIO_PD0 ((unsigned int) 1 << 0) // Pin Controlled by PD0 -#define AT91C_PIO_PD1 ((unsigned int) 1 << 1) // Pin Controlled by PD1 -#define AT91C_PIO_PD2 ((unsigned int) 1 << 2) // Pin Controlled by PD2 -#define AT91C_PIO_PD3 ((unsigned int) 1 << 3) // Pin Controlled by PD3 -#define AT91C_PIO_PD4 ((unsigned int) 1 << 4) // Pin Controlled by PD4 -#define AT91C_PIO_PD5 ((unsigned int) 1 << 5) // Pin Controlled by PD5 -#define AT91C_PIO_PD6 ((unsigned int) 1 << 6) // Pin Controlled by PD6 -#define AT91C_PIO_PD7 ((unsigned int) 1 << 7) // Pin Controlled by PD7 -#define AT91C_PIO_PD8 ((unsigned int) 1 << 8) // Pin Controlled by PD8 -#define AT91C_PIO_PD9 ((unsigned int) 1 << 9) // Pin Controlled by PD9 -#define AT91C_PIO_PD10 ((unsigned int) 1 << 10) // Pin Controlled by PD10 -#define AT91C_PIO_PD11 ((unsigned int) 1 << 11) // Pin Controlled by PD11 -#define AT91C_PIO_PD12 ((unsigned int) 1 << 12) // Pin Controlled by PD12 -#define AT91C_PIO_PD13 ((unsigned int) 1 << 13) // Pin Controlled by PD13 -#define AT91C_PIO_PD14 ((unsigned int) 1 << 14) // Pin Controlled by PD14 -#define AT91C_PIO_PD15 ((unsigned int) 1 << 15) // Pin Controlled by PD15 -#define AT91C_PIO_PD16 ((unsigned int) 1 << 16) // Pin Controlled by PD16 -#define AT91C_PIO_PD17 ((unsigned int) 1 << 17) // Pin Controlled by PD17 -#define AT91C_PIO_PD18 ((unsigned int) 1 << 18) // Pin Controlled by PD18 -#define AT91C_PIO_PD19 ((unsigned int) 1 << 19) // Pin Controlled by PD19 -#define AT91C_PIO_PD20 ((unsigned int) 1 << 20) // Pin Controlled by PD20 -#define AT91C_PIO_PD21 ((unsigned int) 1 << 21) // Pin Controlled by PD21 -#define AT91C_PIO_PD22 ((unsigned int) 1 << 22) // Pin Controlled by PD22 -#define AT91C_PIO_PD23 ((unsigned int) 1 << 23) // Pin Controlled by PD23 -#define AT91C_PIO_PD24 ((unsigned int) 1 << 24) // Pin Controlled by PD24 -#define AT91C_PIO_PD25 ((unsigned int) 1 << 25) // Pin Controlled by PD25 -#define AT91C_PIO_PD26 ((unsigned int) 1 << 26) // Pin Controlled by PD26 -#define AT91C_PIO_PD27 ((unsigned int) 1 << 27) // Pin Controlled by PD27 -#define AT91C_PIO_PD28 ((unsigned int) 1 << 28) // Pin Controlled by PD28 -#define AT91C_PIO_PD29 ((unsigned int) 1 << 29) // Pin Controlled by PD29 -#define AT91C_PIO_PD30 ((unsigned int) 1 << 30) // Pin Controlled by PD30 -#define AT91C_PIO_PD31 ((unsigned int) 1 << 31) // Pin Controlled by PD31 -#define AT91C_PIO_PE0 ((unsigned int) 1 << 0) // Pin Controlled by PE0 -#define AT91C_PIO_PE1 ((unsigned int) 1 << 1) // Pin Controlled by PE1 -#define AT91C_PIO_PE2 ((unsigned int) 1 << 2) // Pin Controlled by PE2 -#define AT91C_PIO_PE3 ((unsigned int) 1 << 3) // Pin Controlled by PE3 -#define AT91C_PIO_PE4 ((unsigned int) 1 << 4) // Pin Controlled by PE4 -#define AT91C_PIO_PE5 ((unsigned int) 1 << 5) // Pin Controlled by PE5 -#define AT91C_PIO_PE6 ((unsigned int) 1 << 6) // Pin Controlled by PE6 -#define AT91C_PIO_PE7 ((unsigned int) 1 << 7) // Pin Controlled by PE7 -#define AT91C_PIO_PE8 ((unsigned int) 1 << 8) // Pin Controlled by PE8 -#define AT91C_PIO_PE9 ((unsigned int) 1 << 9) // Pin Controlled by PE9 -#define AT91C_PIO_PE10 ((unsigned int) 1 << 10) // Pin Controlled by PE10 -#define AT91C_PIO_PE11 ((unsigned int) 1 << 11) // Pin Controlled by PE11 -#define AT91C_PIO_PE12 ((unsigned int) 1 << 12) // Pin Controlled by PE12 -#define AT91C_PIO_PE13 ((unsigned int) 1 << 13) // Pin Controlled by PE13 -#define AT91C_PIO_PE14 ((unsigned int) 1 << 14) // Pin Controlled by PE14 -#define AT91C_PIO_PE15 ((unsigned int) 1 << 15) // Pin Controlled by PE15 -#define AT91C_PIO_PE16 ((unsigned int) 1 << 16) // Pin Controlled by PE16 -#define AT91C_PIO_PE17 ((unsigned int) 1 << 17) // Pin Controlled by PE17 -#define AT91C_PIO_PE18 ((unsigned int) 1 << 18) // Pin Controlled by PE18 -#define AT91C_PIO_PE19 ((unsigned int) 1 << 19) // Pin Controlled by PE19 -#define AT91C_PIO_PE20 ((unsigned int) 1 << 20) // Pin Controlled by PE20 -#define AT91C_PIO_PE21 ((unsigned int) 1 << 21) // Pin Controlled by PE21 -#define AT91C_PIO_PE22 ((unsigned int) 1 << 22) // Pin Controlled by PE22 -#define AT91C_PIO_PE23 ((unsigned int) 1 << 23) // Pin Controlled by PE23 -#define AT91C_PIO_PE24 ((unsigned int) 1 << 24) // Pin Controlled by PE24 -#define AT91C_PIO_PE25 ((unsigned int) 1 << 25) // Pin Controlled by PE25 -#define AT91C_PIO_PE26 ((unsigned int) 1 << 26) // Pin Controlled by PE26 -#define AT91C_PIO_PE27 ((unsigned int) 1 << 27) // Pin Controlled by PE27 -#define AT91C_PIO_PE28 ((unsigned int) 1 << 28) // Pin Controlled by PE28 -#define AT91C_PIO_PE29 ((unsigned int) 1 << 29) // Pin Controlled by PE29 -#define AT91C_PIO_PE30 ((unsigned int) 1 << 30) // Pin Controlled by PE30 -#define AT91C_PIO_PE31 ((unsigned int) 1 << 31) // Pin Controlled by PE31 - -#endif /* ARM_AT91_AT91_PIOREG_H */ Index: head/sys/arm/at91/at91_piovar.h =================================================================== --- head/sys/arm/at91/at91_piovar.h +++ head/sys/arm/at91/at91_piovar.h @@ -1,52 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2006 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef ARM_AT91_AT91_PIOVAR_H -#define ARM_AT91_AT91_PIOVAR_H - -void at91_pio_use_periph_a(uint32_t pio, uint32_t periph_a_mask, - int use_pullup); -void at91_pio_use_periph_b(uint32_t pio, uint32_t periph_b_mask, - int use_pullup); -void at91_pio_use_gpio(uint32_t pio, uint32_t gpio_mask); -void at91_pio_gpio_input(uint32_t pio, uint32_t input_enable_mask); -void at91_pio_gpio_output(uint32_t pio, uint32_t output_enable_mask, - int use_pullup); -void at91_pio_gpio_high_z(uint32_t pio, uint32_t high_z_mask, int enable); -void at91_pio_gpio_set(uint32_t pio, uint32_t data_mask); -void at91_pio_gpio_clear(uint32_t pio, uint32_t data_mask); -uint32_t at91_pio_gpio_get(uint32_t pio, uint32_t data_mask); -void at91_pio_gpio_set_deglitch(uint32_t pio, uint32_t data_mask, - int use_deglitch); -void at91_pio_gpio_set_interrupt(uint32_t pio, uint32_t data_mask, - int enable_interrupt); -uint32_t at91_pio_gpio_clear_interrupt(uint32_t pio); -void at91_pio_gpio_pullup(uint32_t pio, uint32_t data_mask, int do_pullup); - -#endif /* ARM_AT91_AT91_PIOVAR_H */ Index: head/sys/arm/at91/at91_pit.c =================================================================== --- head/sys/arm/at91/at91_pit.c +++ head/sys/arm/at91/at91_pit.c @@ -1,222 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2009 Gallon Sylvestre. All rights reserved. - * Copyright (c) 2010 Greg Ansley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "opt_platform.h" - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#ifdef FDT -#include -#include -#endif - -#ifndef PIT_PRESCALE -#define PIT_PRESCALE (16) -#endif - -static struct pit_softc { - struct resource *mem_res; /* Memory resource */ - void *intrhand; /* Interrupt handle */ - device_t sc_dev; -} *sc; - -static uint32_t timecount = 0; -static unsigned at91_pit_get_timecount(struct timecounter *tc); -static int pit_intr(void *arg); - -static inline uint32_t -RD4(struct pit_softc *sc, bus_size_t off) -{ - - return (bus_read_4(sc->mem_res, off)); -} - -static inline void -WR4(struct pit_softc *sc, bus_size_t off, uint32_t val) -{ - - bus_write_4(sc->mem_res, off, val); -} - -void -at91_pit_delay(int us) -{ - int32_t cnt, last, piv; - uint64_t pit_freq; - const uint64_t mhz = 1E6; - - if (sc == NULL) - return; - - last = PIT_PIV(RD4(sc, PIT_PIIR)); - - /* Max delay ~= 260s. @ 133Mhz */ - pit_freq = at91_master_clock / PIT_PRESCALE; - cnt = howmany(pit_freq * us, mhz); - cnt = (cnt <= 0) ? 1 : cnt; - - while (cnt > 0) { - piv = PIT_PIV(RD4(sc, PIT_PIIR)); - cnt -= piv - last ; - if (piv < last) - cnt -= PIT_PIV(~0u) - last; - last = piv; - } -} - -static struct timecounter at91_pit_timecounter = { - at91_pit_get_timecount, /* get_timecount */ - NULL, /* no poll_pps */ - 0xffffffff, /* counter mask */ - 0 / PIT_PRESCALE, /* frequency */ - "AT91SAM9 timer", /* name */ - 1000 /* quality */ -}; - -static int -at91_pit_probe(device_t dev) -{ -#ifdef FDT - if (!ofw_bus_is_compatible(dev, "atmel,at91sam9260-pit")) - return (ENXIO); -#endif - device_set_desc(dev, "AT91SAM9 PIT"); - return (0); -} - -static int -at91_pit_attach(device_t dev) -{ - void *ih; - int rid, err = 0; - struct resource *irq; - - sc = device_get_softc(dev); - sc->sc_dev = dev; - - rid = 0; - sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - - if (sc->mem_res == NULL) - panic("couldn't allocate register resources"); - - rid = 0; - irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 1, 1, 1, - RF_ACTIVE | RF_SHAREABLE); - if (!irq) { - device_printf(dev, "could not allocate interrupt resources.\n"); - err = ENOMEM; - goto out; - } - - /* Activate the interrupt. */ - err = bus_setup_intr(dev, irq, INTR_TYPE_CLK, pit_intr, NULL, NULL, - &ih); - - at91_pit_timecounter.tc_frequency = at91_master_clock / PIT_PRESCALE; - tc_init(&at91_pit_timecounter); - - /* Enable the PIT here. */ - WR4(sc, PIT_MR, PIT_PIV(at91_master_clock / PIT_PRESCALE / hz) | - PIT_EN | PIT_IEN); -out: - return (err); -} - - -static int -pit_intr(void *arg) -{ - struct trapframe *fp = arg; - uint32_t icnt; - - if (RD4(sc, PIT_SR) & PIT_PITS_DONE) { - icnt = RD4(sc, PIT_PIVR) >> 20; - - /* Just add in the overflows we just read */ - timecount += PIT_PIV(RD4(sc, PIT_MR)) * icnt; - - hardclock(TRAPF_USERMODE(fp), TRAPF_PC(fp)); - return (FILTER_HANDLED); - } - return (FILTER_STRAY); -} - -static unsigned -at91_pit_get_timecount(struct timecounter *tc) -{ - uint32_t piir, icnt; - - piir = RD4(sc, PIT_PIIR); /* Current count | over flows */ - icnt = piir >> 20; /* Overflows */ - return (timecount + PIT_PIV(piir) + PIT_PIV(RD4(sc, PIT_MR)) * icnt); -} - -static device_method_t at91_pit_methods[] = { - DEVMETHOD(device_probe, at91_pit_probe), - DEVMETHOD(device_attach, at91_pit_attach), - DEVMETHOD_END -}; - -static driver_t at91_pit_driver = { - "at91_pit", - at91_pit_methods, - sizeof(struct pit_softc), -}; - -static devclass_t at91_pit_devclass; - -#ifdef FDT -EARLY_DRIVER_MODULE(at91_pit, simplebus, at91_pit_driver, at91_pit_devclass, - NULL, NULL, BUS_PASS_TIMER); -#else -EARLY_DRIVER_MODULE(at91_pit, atmelarm, at91_pit_driver, at91_pit_devclass, - NULL, NULL, BUS_PASS_TIMER); -#endif Index: head/sys/arm/at91/at91_pitreg.h =================================================================== --- head/sys/arm/at91/at91_pitreg.h +++ head/sys/arm/at91/at91_pitreg.h @@ -1,49 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2009 Sylvestre Gallon. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef ARM_AT91_AT91_PITREG_H -#define ARM_AT91_AT91_PITREG_H - -#define PIT_MR 0x0 -#define PIT_SR 0x4 -#define PIT_PIVR 0x8 -#define PIT_PIIR 0xc - -/* PIT_MR */ -#define PIT_PIV(x) (x & 0xfffff) /* periodic interval value */ -#define PIT_CNT(x) ((x >>20) & 0xfff) /* periodic interval counter */ -#define PIT_EN (1 << 24) /* pit enable */ -#define PIT_IEN (1 << 25) /* pit interrupt enable */ - -/* PIT_SR */ -#define PIT_PITS_DONE 1 /* interrupt done */ - -void at91_pit_delay(int us); - -#endif /* ARM_AT91_AT91_PITREG_H */ Index: head/sys/arm/at91/at91_pmc.c =================================================================== --- head/sys/arm/at91/at91_pmc.c +++ head/sys/arm/at91/at91_pmc.c @@ -1,719 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2006 M. Warner Losh. - * Copyright (c) 2010 Greg Ansley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "opt_platform.h" - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#ifdef FDT -#include -#include -#endif - -static struct at91_pmc_softc { - bus_space_tag_t sc_st; - bus_space_handle_t sc_sh; - struct resource *mem_res; /* Memory resource */ - device_t dev; -} *pmc_softc; - -static uint32_t pllb_init; - -MALLOC_DECLARE(M_PMC_CLK); -MALLOC_DEFINE(M_PMC_CLK, "at91_pmc_clocks", "AT91 PMC Clock descriptors"); - -#define AT91_PMC_BASE 0xffffc00 - -static void at91_pmc_set_pllb_mode(struct at91_pmc_clock *, int); -static void at91_pmc_set_upll_mode(struct at91_pmc_clock *, int); -static void at91_pmc_set_sys_mode(struct at91_pmc_clock *, int); -static void at91_pmc_set_periph_mode(struct at91_pmc_clock *, int); -static void at91_pmc_clock_alias(const char *name, const char *alias); - -static struct at91_pmc_clock slck = { - .name = "slck", /* 32,768 Hz slow clock */ - .hz = 32768, - .refcnt = 1, - .id = 0, - .primary = 1, -}; - -/* - * NOTE: Clocks for "ordinary peripheral" devices e.g. spi0, udp0, uhp0 etc. - * are now created automatically. Only "system" clocks need be defined here. - */ -static struct at91_pmc_clock main_ck = { - .name = "main", /* Main clock */ - .refcnt = 0, - .id = 1, - .primary = 1, - .pmc_mask = PMC_IER_MOSCS, -}; - -static struct at91_pmc_clock plla = { - .name = "plla", /* PLLA Clock, used for CPU clocking */ - .parent = &main_ck, - .refcnt = 1, - .id = 0, - .primary = 1, - .pll = 1, - .pmc_mask = PMC_IER_LOCKA, -}; - -static struct at91_pmc_clock pllb = { - .name = "pllb", /* PLLB Clock, used for USB functions */ - .parent = &main_ck, - .refcnt = 0, - .id = 0, - .primary = 1, - .pll = 1, - .pmc_mask = PMC_IER_LOCKB, - .set_mode = &at91_pmc_set_pllb_mode, -}; - -/* Used by USB on at91sam9g45 */ -static struct at91_pmc_clock upll = { - .name = "upll", /* UTMI PLL, used for USB functions on 9G45 family */ - .parent = &main_ck, - .refcnt = 0, - .id = 0, - .primary = 1, - .pll = 1, - .pmc_mask = (1 << 6), - .set_mode = &at91_pmc_set_upll_mode, -}; - -static struct at91_pmc_clock udpck = { - .name = "udpck", - .parent = &pllb, - .pmc_mask = PMC_SCER_UDP, - .set_mode = at91_pmc_set_sys_mode -}; - -static struct at91_pmc_clock uhpck = { - .name = "uhpck", - .parent = &pllb, - .pmc_mask = PMC_SCER_UHP, - .set_mode = at91_pmc_set_sys_mode -}; - -static struct at91_pmc_clock mck = { - .name = "mck", /* Master (Peripheral) Clock */ - .pmc_mask = PMC_IER_MCKRDY, - .refcnt = 0, -}; - -static struct at91_pmc_clock cpu = { - .name = "cpu", /* CPU Clock */ - .parent = &plla, - .pmc_mask = PMC_SCER_PCK, - .refcnt = 0, -}; - -/* "+32" or the automatic peripheral clocks */ -static struct at91_pmc_clock *clock_list[16+32] = { - &slck, - &main_ck, - &plla, - &pllb, - &upll, - &udpck, - &uhpck, - &mck, - &cpu -}; - -static inline uint32_t -RD4(struct at91_pmc_softc *sc, bus_size_t off) -{ - - if (sc == NULL) { - uint32_t *p = (uint32_t *)(AT91_BASE + AT91_PMC_BASE + off); - - return *p; - } - return (bus_read_4(sc->mem_res, off)); -} - -static inline void -WR4(struct at91_pmc_softc *sc, bus_size_t off, uint32_t val) -{ - - if (sc == NULL) { - uint32_t *p = (uint32_t *)(AT91_BASE + AT91_PMC_BASE + off); - - *p = val; - } else - bus_write_4(sc->mem_res, off, val); -} - -/* - * The following is unused currently since we don't ever set the PLLA - * frequency of the device. If we did, we'd have to also pay attention - * to the ICPLLA bit in the PMC_PLLICPR register for frequencies lower - * than ~600MHz, which the PMC code doesn't do right now. - */ -uint32_t -at91_pmc_800mhz_plla_outb(int freq) -{ - uint32_t outa; - - /* - * Set OUTA, per the data sheet. See Table 46-16 titled - * PLLA Frequency Regarding ICPLLA and OUTA in the SAM9X25 doc, - * Table 46-17 in the SAM9G20 doc, or Table 46-16 in the SAM9G45 doc. - * Note: the frequencies overlap by 5MHz, so we add 3 here to - * center shoot the transition. - */ - - freq /= 1000000; /* MHz */ - if (freq >= 800) - freq = 800; - freq += 3; /* Allow for overlap. */ - outa = 3 - ((freq / 50) & 3); /* 750 / 50 = 7, see table */ - return (1 << 29)| (outa << 14); -} - -uint32_t -at91_pmc_800mhz_pllb_outb(int freq) -{ - - return (0); -} - -void -at91_pmc_set_pllb_mode(struct at91_pmc_clock *clk, int on) -{ - struct at91_pmc_softc *sc = pmc_softc; - uint32_t value; - - value = on ? pllb_init : 0; - - /* - * Only write to the register if the value is changing. Besides being - * good common sense, this works around RM9200 Errata #26 (CKGR_PLL[AB]R - * must not be written with the same value currently in the register). - */ - if (RD4(sc, CKGR_PLLBR) != value) { - WR4(sc, CKGR_PLLBR, value); - while (on && (RD4(sc, PMC_SR) & PMC_IER_LOCKB) != PMC_IER_LOCKB) - continue; - } -} - -static void -at91_pmc_set_upll_mode(struct at91_pmc_clock *clk, int on) -{ - struct at91_pmc_softc *sc = pmc_softc; - uint32_t value; - - if (on) { - on = PMC_IER_LOCKU; - value = CKGR_UCKR_UPLLEN | CKGR_UCKR_BIASEN; - } else - value = 0; - - WR4(sc, CKGR_UCKR, RD4(sc, CKGR_UCKR) | value); - while ((RD4(sc, PMC_SR) & PMC_IER_LOCKU) != on) - continue; - - WR4(sc, PMC_USB, PMC_USB_USBDIV(9) | PMC_USB_USBS); - WR4(sc, PMC_SCER, PMC_SCER_UHP_SAM9); -} - -static void -at91_pmc_set_sys_mode(struct at91_pmc_clock *clk, int on) -{ - struct at91_pmc_softc *sc = pmc_softc; - - WR4(sc, on ? PMC_SCER : PMC_SCDR, clk->pmc_mask); - if (on) - while ((RD4(sc, PMC_SCSR) & clk->pmc_mask) != clk->pmc_mask) - continue; - else - while ((RD4(sc, PMC_SCSR) & clk->pmc_mask) == clk->pmc_mask) - continue; -} - -static void -at91_pmc_set_periph_mode(struct at91_pmc_clock *clk, int on) -{ - struct at91_pmc_softc *sc = pmc_softc; - - WR4(sc, on ? PMC_PCER : PMC_PCDR, clk->pmc_mask); - if (on) - while ((RD4(sc, PMC_PCSR) & clk->pmc_mask) != clk->pmc_mask) - continue; - else - while ((RD4(sc, PMC_PCSR) & clk->pmc_mask) == clk->pmc_mask) - continue; -} - -struct at91_pmc_clock * -at91_pmc_clock_add(const char *name, uint32_t irq, - struct at91_pmc_clock *parent) -{ - struct at91_pmc_clock *clk; - int i, buflen; - - clk = malloc(sizeof(*clk), M_PMC_CLK, M_NOWAIT | M_ZERO); - if (clk == NULL) - goto err; - - buflen = strlen(name) + 1; - clk->name = malloc(buflen, M_PMC_CLK, M_NOWAIT); - if (clk->name == NULL) - goto err; - - strlcpy(clk->name, name, buflen); - clk->pmc_mask = 1 << irq; - clk->set_mode = &at91_pmc_set_periph_mode; - if (parent == NULL) - clk->parent = &mck; - else - clk->parent = parent; - - for (i = 0; i < nitems(clock_list); i++) { - if (clock_list[i] == NULL) { - clock_list[i] = clk; - return (clk); - } - } -err: - if (clk != NULL) { - if (clk->name != NULL) - free(clk->name, M_PMC_CLK); - free(clk, M_PMC_CLK); - } - - panic("could not allocate pmc clock '%s'", name); - return (NULL); -} - -static void -at91_pmc_clock_alias(const char *name, const char *alias) -{ - struct at91_pmc_clock *clk, *alias_clk; - - clk = at91_pmc_clock_ref(name); - if (clk) - alias_clk = at91_pmc_clock_add(alias, 0, clk->parent); - - if (clk && alias_clk) { - alias_clk->hz = clk->hz; - alias_clk->pmc_mask = clk->pmc_mask; - alias_clk->set_mode = clk->set_mode; - } -} - -struct at91_pmc_clock * -at91_pmc_clock_ref(const char *name) -{ - int i; - - for (i = 0; i < nitems(clock_list); i++) { - if (clock_list[i] == NULL) - break; - if (strcmp(name, clock_list[i]->name) == 0) - return (clock_list[i]); - } - - return (NULL); -} - -void -at91_pmc_clock_deref(struct at91_pmc_clock *clk) -{ - if (clk == NULL) - return; -} - -void -at91_pmc_clock_enable(struct at91_pmc_clock *clk) -{ - if (clk == NULL) - return; - - /* XXX LOCKING? XXX */ - if (clk->parent) - at91_pmc_clock_enable(clk->parent); - if (clk->refcnt++ == 0 && clk->set_mode) - clk->set_mode(clk, 1); -} - -void -at91_pmc_clock_disable(struct at91_pmc_clock *clk) -{ - if (clk == NULL) - return; - - /* XXX LOCKING? XXX */ - if (--clk->refcnt == 0 && clk->set_mode) - clk->set_mode(clk, 0); - if (clk->parent) - at91_pmc_clock_disable(clk->parent); -} - -static int -at91_pmc_pll_rate(struct at91_pmc_clock *clk, uint32_t reg) -{ - uint32_t mul, div, freq; - - freq = clk->parent->hz; - div = (reg >> clk->pll_div_shift) & clk->pll_div_mask; - mul = (reg >> clk->pll_mul_shift) & clk->pll_mul_mask; - -#if 0 - printf("pll = (%d / %d) * %d = %d\n", - freq, div, mul + 1, (freq/div) * (mul+1)); -#endif - - if (div != 0 && mul != 0) { - freq /= div; - freq *= mul + 1; - } else - freq = 0; - clk->hz = freq; - - return (freq); -} - -static uint32_t -at91_pmc_pll_calc(struct at91_pmc_clock *clk, uint32_t out_freq) -{ - uint32_t i, div = 0, mul = 0, diff = 1 << 30; - - unsigned ret = 0x3e00; - - if (out_freq > clk->pll_max_out) - goto fail; - - for (i = 1; i < 256; i++) { - int32_t diff1; - uint32_t input, mul1; - - input = clk->parent->hz / i; - if (input < clk->pll_min_in) - break; - if (input > clk->pll_max_in) - continue; - - mul1 = out_freq / input; - if (mul1 > (clk->pll_mul_mask + 1)) - continue; - if (mul1 == 0) - break; - - diff1 = out_freq - input * mul1; - if (diff1 < 0) - diff1 = -diff1; - if (diff > diff1) { - diff = diff1; - div = i; - mul = mul1; - if (diff == 0) - break; - } - } - if (diff > (out_freq >> PMC_PLL_SHIFT_TOL)) - goto fail; - - if (clk->set_outb != NULL) - ret |= clk->set_outb(out_freq); - - return (ret | - ((mul - 1) << clk->pll_mul_shift) | - (div << clk->pll_div_shift)); -fail: - return (0); -} - -#if !defined(AT91C_MAIN_CLOCK) -static const unsigned int at91_main_clock_tbl[] = { - 3000000, 3276800, 3686400, 3840000, 4000000, - 4433619, 4915200, 5000000, 5242880, 6000000, - 6144000, 6400000, 6553600, 7159090, 7372800, - 7864320, 8000000, 9830400, 10000000, 11059200, - 12000000, 12288000, 13560000, 14318180, 14745600, - 16000000, 17344700, 18432000, 20000000 -}; -#define MAIN_CLOCK_TBL_LEN nitems(at91_main_clock_tbl) -#endif - -static unsigned int -at91_pmc_sense_main_clock(void) -{ -#if !defined(AT91C_MAIN_CLOCK) - unsigned int ckgr_val; - unsigned int diff, matchdiff, freq; - int i; - - ckgr_val = (RD4(NULL, CKGR_MCFR) & CKGR_MCFR_MAINF_MASK) << 11; - - /* - * Clocks up to 50MHz can be connected to some models. If - * the frequency is >= 21MHz, assume that the slow clock can - * measure it correctly, and that any error can be adequately - * compensated for by roudning to the nearest 500Hz. Users - * with fast, or odd-ball clocks will need to set - * AT91C_MAIN_CLOCK in the kernel config file. - */ - if (ckgr_val >= 21000000) - return (rounddown(ckgr_val + 250, 500)); - - /* - * Try to find the standard frequency that match best. - */ - freq = at91_main_clock_tbl[0]; - matchdiff = abs(ckgr_val - at91_main_clock_tbl[0]); - for (i = 1; i < MAIN_CLOCK_TBL_LEN; i++) { - diff = abs(ckgr_val - at91_main_clock_tbl[i]); - if (diff < matchdiff) { - freq = at91_main_clock_tbl[i]; - matchdiff = diff; - } - } - return (freq); -#else - return (AT91C_MAIN_CLOCK); -#endif -} - -void -at91_pmc_init_clock(void) -{ - struct at91_pmc_softc *sc = NULL; - unsigned int main_clock; - uint32_t mckr; - uint32_t mdiv; - - soc_info.soc_data->soc_clock_init(); - - main_clock = at91_pmc_sense_main_clock(); - - if (at91_is_sam9() || at91_is_sam9xe()) { - uhpck.pmc_mask = PMC_SCER_UHP_SAM9; - udpck.pmc_mask = PMC_SCER_UDP_SAM9; - } - - /* There is no pllb on AT91SAM9G45 */ - if (at91_cpu_is(AT91_T_SAM9G45)) { - uhpck.parent = &upll; - uhpck.pmc_mask = PMC_SCER_UHP_SAM9; - } - - mckr = RD4(sc, PMC_MCKR); - main_ck.hz = main_clock; - - /* - * Note: this means outa calc code for plla never used since - * we never change it. If we did, we'd also have to mind - * ICPLLA to get the charge pump current right. - */ - at91_pmc_pll_rate(&plla, RD4(sc, CKGR_PLLAR)); - - if (at91_cpu_is(AT91_T_SAM9G45) && (mckr & PMC_MCKR_PLLADIV2)) - plla.hz /= 2; - - /* - * Initialize the usb clock. This sets up pllb, but disables the - * actual clock. XXX except for the if 0 :( - */ - if (!at91_cpu_is(AT91_T_SAM9G45)) { - pllb_init = at91_pmc_pll_calc(&pllb, 48000000 * 2) | 0x10000000; - at91_pmc_pll_rate(&pllb, pllb_init); -#if 0 - /* Turn off USB clocks */ - at91_pmc_set_periph_mode(&ohci_clk, 0); - at91_pmc_set_periph_mode(&udc_clk, 0); -#endif - } - - if (at91_is_rm92()) { - WR4(sc, PMC_SCDR, PMC_SCER_UHP | PMC_SCER_UDP); - WR4(sc, PMC_SCER, PMC_SCER_MCKUDP); - } else - WR4(sc, PMC_SCDR, PMC_SCER_UHP_SAM9 | PMC_SCER_UDP_SAM9); - - /* - * MCK and PCU derive from one of the primary clocks. Initialize - * this relationship. - */ - mck.parent = clock_list[mckr & 0x3]; - mck.parent->refcnt++; - - cpu.hz = mck.hz = mck.parent->hz / - (1 << ((mckr & PMC_MCKR_PRES_MASK) >> 2)); - - mdiv = (mckr & PMC_MCKR_MDIV_MASK) >> 8; - if (at91_is_sam9() || at91_is_sam9xe()) { - /* - * On AT91SAM9G45 when mdiv == 3 we need to divide - * MCK by 3 but not, for example, on 9g20. - */ - if (!at91_cpu_is(AT91_T_SAM9G45) || mdiv <= 2) - mdiv *= 2; - if (mdiv > 0) - mck.hz /= mdiv; - } else - mck.hz /= (1 + mdiv); - - /* Only found on SAM9G20 */ - if (at91_cpu_is(AT91_T_SAM9G20)) - cpu.hz /= (mckr & PMC_MCKR_PDIV) ? 2 : 1; - - at91_master_clock = mck.hz; - - /* These clocks refrenced by "special" names */ - at91_pmc_clock_alias("ohci0", "ohci_clk"); - at91_pmc_clock_alias("udp0", "udp_clk"); - - /* Turn off "Progamable" clocks */ - WR4(sc, PMC_SCDR, PMC_SCER_PCK0 | PMC_SCER_PCK1 | PMC_SCER_PCK2 | - PMC_SCER_PCK3); - - /* XXX kludge, turn on all peripherals */ - WR4(sc, PMC_PCER, 0xffffffff); - - /* Disable all interrupts for PMC */ - WR4(sc, PMC_IDR, 0xffffffff); -} - -static void -at91_pmc_deactivate(device_t dev) -{ - struct at91_pmc_softc *sc; - - sc = device_get_softc(dev); - bus_generic_detach(sc->dev); - if (sc->mem_res) - bus_release_resource(dev, SYS_RES_IOPORT, - rman_get_rid(sc->mem_res), sc->mem_res); - sc->mem_res = NULL; -} - -static int -at91_pmc_activate(device_t dev) -{ - struct at91_pmc_softc *sc; - int rid; - - sc = device_get_softc(dev); - rid = 0; - sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - if (sc->mem_res == NULL) - goto errout; - return (0); -errout: - at91_pmc_deactivate(dev); - return (ENOMEM); -} - -static int -at91_pmc_probe(device_t dev) -{ -#ifdef FDT - if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-pmc") && - !ofw_bus_is_compatible(dev, "atmel,at91sam9260-pmc") && - !ofw_bus_is_compatible(dev, "atmel,at91sam9g45-pmc") && - !ofw_bus_is_compatible(dev, "atmel,at91sam9x5-pmc")) - return (ENXIO); -#endif - device_set_desc(dev, "PMC"); - return (0); -} - -static int -at91_pmc_attach(device_t dev) -{ - int err; - - pmc_softc = device_get_softc(dev); - pmc_softc->dev = dev; - if ((err = at91_pmc_activate(dev)) != 0) - return (err); - - /* - * Configure main clock frequency. - */ - at91_pmc_init_clock(); - - /* - * Display info about clocks previously computed - */ - device_printf(dev, - "Primary: %d Hz PLLA: %d MHz CPU: %d MHz MCK: %d MHz\n", - main_ck.hz, - plla.hz / 1000000, - cpu.hz / 1000000, mck.hz / 1000000); - - return (0); -} - -static device_method_t at91_pmc_methods[] = { - DEVMETHOD(device_probe, at91_pmc_probe), - DEVMETHOD(device_attach, at91_pmc_attach), - DEVMETHOD_END -}; - -static driver_t at91_pmc_driver = { - "at91_pmc", - at91_pmc_methods, - sizeof(struct at91_pmc_softc), -}; -static devclass_t at91_pmc_devclass; - -#ifdef FDT -EARLY_DRIVER_MODULE(at91_pmc, simplebus, at91_pmc_driver, at91_pmc_devclass, - NULL, NULL, BUS_PASS_CPU); -#else -EARLY_DRIVER_MODULE(at91_pmc, atmelarm, at91_pmc_driver, at91_pmc_devclass, - NULL, NULL, BUS_PASS_CPU); -#endif Index: head/sys/arm/at91/at91_pmcreg.h =================================================================== --- head/sys/arm/at91/at91_pmcreg.h +++ head/sys/arm/at91/at91_pmcreg.h @@ -1,146 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2005 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef ARM_AT91_AT91_PMCREG_H -#define ARM_AT91_AT91_PMCREG_H - -/* Registers */ -#define PMC_SCER 0x00 /* System Clock Enable Register */ -#define PMC_SCDR 0x04 /* System Clock Disable Register */ -#define PMC_SCSR 0x08 /* System Clock Status Register */ - /* 0x0c reserved */ -#define PMC_PCER 0x10 /* Peripheral Clock Enable Register */ -#define PMC_PCDR 0x14 /* Peripheral Clock Disable Register */ -#define PMC_PCSR 0x18 /* Peripheral Clock Status Register */ -#define CKGR_UCKR 0x1c /* UTMI Clock Configuration Register */ -#define CKGR_MOR 0x20 /* Main Oscillator Register */ -#define CKGR_MCFR 0x24 /* Main Clock Frequency Register */ -#define CKGR_PLLAR 0x28 /* PLL A Register */ -#define CKGR_PLLBR 0x2c /* PLL B Register */ -#define PMC_MCKR 0x30 /* Master Clock Register */ - /* 0x34 reserved */ -#define PMC_USB 0x38 /* USB Clock Register */ - /* 0x3c reserved */ -#define PMC_PCK0 0x40 /* Programmable Clock 0 Register */ -#define PMC_PCK1 0x44 /* Programmable Clock 1 Register */ -#define PMC_PCK2 0x48 /* Programmable Clock 2 Register */ -#define PMC_PCK3 0x4c /* Programmable Clock 3 Register */ - /* 0x50 reserved */ - /* 0x54 reserved */ - /* 0x58 reserved */ - /* 0x5c reserved */ -#define PMC_IER 0x60 /* Interrupt Enable Register */ -#define PMC_IDR 0x64 /* Interrupt Disable Register */ -#define PMC_SR 0x68 /* Status Register */ -#define PMC_IMR 0x6c /* Interrupt Mask Register */ - /* 0x70 reserved */ - /* 0x74 reserved */ - /* 0x78 reserved */ - /* 0x7c reserved */ -#define PMC_PLLICPR 0x80 /* PLL Charge Pump Current Register */ - -/* PMC System Clock Enable Register */ -/* PMC System Clock Disable Register */ -/* PMC System Clock StatusRegister */ -#define PMC_SCER_PCK (1UL << 0) /* PCK: Processor Clock Enable */ -#define PMC_SCER_UDP (1UL << 1) /* UDP: USB Device Port Clock Enable */ -#define PMC_SCER_MCKUDP (1UL << 2) /* MCKUDP: Master disable susp/res */ -#define PMC_SCER_UHP (1UL << 4) /* UHP: USB Host Port Clock Enable */ -#define PMC_SCER_PCK0 (1UL << 8) /* PCK0: Programmable Clock out en */ -#define PMC_SCER_PCK1 (1UL << 9) /* PCK1: Programmable Clock out en */ -#define PMC_SCER_PCK2 (1UL << 10) /* PCK2: Programmable Clock out en */ -#define PMC_SCER_PCK3 (1UL << 11) /* PCK3: Programmable Clock out en */ -#define PMC_SCER_UHP_SAM9 (1UL << 6) /* UHP: USB Host Port Clock Enable */ -#define PMC_SCER_UDP_SAM9 (1UL << 7) /* UDP: USB Device Port Clock Enable */ - -/* PMC Peripheral Clock Enable Register */ -/* PMC Peripheral Clock Disable Register */ -/* PMC Peripheral Clock Status Register */ -/* Each bit here is 1 << peripheral number to enable/disable/status */ - -/* PMC UTMI Clock Configuration Register */ -#define CKGR_UCKR_BIASEN (1UL << 24) -#define CKGR_UCKR_UPLLEN (1UL << 16) - -/* PMC Clock Generator Main Oscillator Register */ -#define CKGR_MOR_MOSCEN (1UL << 0) /* MOSCEN: Main Oscillator Enable */ -#define CKGR_MOR_OSCBYPASS (1UL << 1) /* Oscillator Bypass */ -#define CKGR_MOR_OSCOUNT(x) (x << 8) /* Main Oscillator Start-up Time */ - -/* PMC Clock Generator Main Clock Frequency Register */ -#define CKGR_MCFR_MAINRDY (1UL << 16) /* Main Clock Ready */ -#define CKGR_MCFR_MAINF_MASK 0xfffful /* Main Clock Frequency */ - -/* PMC Clock Generator Master Clock Register */ -#define PMC_MCKR_PDIV (1 << 12) /* SAM9G20 Only */ -#define PMC_MCKR_PLLADIV2 (1 << 12) /* SAM9G45 Only */ -#define PMC_MCKR_CSS_MASK (3 << 0) -#define PMC_MCKR_MDIV_MASK (3 << 8) -#define PMC_MCKR_PRES_MASK (7 << 2) - -/* PMC USB Clock Register */ -#define PMC_USB_USBDIV(n) (((n) & 0x0F) << 8) -#define PMC_USB_USBS (1 << 0) - -/* PMC Interrupt Enable Register */ -/* PMC Interrupt Disable Register */ -/* PMC Status Register */ -/* PMC Interrupt Mask Register */ -#define PMC_IER_MOSCS (1UL << 0) /* Main Oscillator Status */ -#define PMC_IER_LOCKA (1UL << 1) /* PLL A Locked */ -#define PMC_IER_LOCKB (1UL << 2) /* PLL B Locked */ -#define PMC_IER_MCKRDY (1UL << 3) /* Master Clock Status */ -#define PMC_IER_LOCKU (1UL << 6) /* UPLL Locked */ -#define PMC_IER_PCK0RDY (1UL << 8) /* Programmable Clock 0 Ready */ -#define PMC_IER_PCK1RDY (1UL << 9) /* Programmable Clock 1 Ready */ -#define PMC_IER_PCK2RDY (1UL << 10) /* Programmable Clock 2 Ready */ -#define PMC_IER_PCK3RDY (1UL << 11) /* Programmable Clock 3 Ready */ - -/* - * PLL input frequency spec sheet says it must be between 1MHz and 32MHz, - * but it works down as low as 100kHz, a frequency necessary for some - * output frequencies to work. - */ -#define PMC_PLL_MIN_IN_FREQ 100000 -#define PMC_PLL_MAX_IN_FREQ 32000000 - -/* - * PLL Max output frequency is 240MHz. The errata says 180MHz is the max - * for some revisions of this part. Be more permissive and optimistic. - */ -#define PMC_PLL_MAX_OUT_FREQ 240000000 - -#define PMC_PLL_MULT_MIN 2 -#define PMC_PLL_MULT_MAX 2048 - -#define PMC_PLL_SHIFT_TOL 5 /* Allow errors 1 part in 32 */ - -#define PMC_PLL_FAST_THRESH 155000000 - -#endif /* ARM_AT91_AT91_PMCREG_H */ Index: head/sys/arm/at91/at91_pmcvar.h =================================================================== --- head/sys/arm/at91/at91_pmcvar.h +++ head/sys/arm/at91/at91_pmcvar.h @@ -1,69 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2005 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef ARM_AT91_AT91_PMCVAR_H -#define ARM_AT91_AT91_PMCVAR_H - -struct at91_pmc_clock -{ - char *name; - uint32_t hz; - struct at91_pmc_clock *parent; - uint32_t pmc_mask; - void (*set_mode)(struct at91_pmc_clock *, int); - uint32_t refcnt; - unsigned id:2; - unsigned primary:1; - unsigned pll:1; - unsigned programmable:1; - - /* PLL Params */ - uint32_t pll_min_in; - uint32_t pll_max_in; - uint32_t pll_min_out; - uint32_t pll_max_out; - - uint32_t pll_div_shift; - uint32_t pll_div_mask; - uint32_t pll_mul_shift; - uint32_t pll_mul_mask; - - uint32_t (*set_outb)(int); -}; - -struct at91_pmc_clock *at91_pmc_clock_add(const char *name, uint32_t irq, - struct at91_pmc_clock *parent); -struct at91_pmc_clock *at91_pmc_clock_ref(const char *name); -void at91_pmc_clock_deref(struct at91_pmc_clock *); -void at91_pmc_clock_enable(struct at91_pmc_clock *); -void at91_pmc_clock_disable(struct at91_pmc_clock *); - -uint32_t at91_pmc_800mhz_plla_outb(int freq); -uint32_t at91_pmc_800mhz_pllb_outb(int freq); -#endif /* ARM_AT91_AT91_PMCVAR_H */ Index: head/sys/arm/at91/at91_reset.S =================================================================== --- head/sys/arm/at91/at91_reset.S +++ head/sys/arm/at91/at91_reset.S @@ -1,57 +0,0 @@ -#include -#include -#include -#include -__FBSDID("$FreeBSD$"); - -#define SDRAM_TR (AT91_BASE + \ - AT91SAM9G20_SDRAMC_BASE + AT91SAM9G20_SDRAMC_TR) -#define SDRAM_LPR (AT91_BASE + \ - AT91SAM9G20_SDRAMC_BASE + AT91SAM9G20_SDRAMC_LPR) -#define RSTC_RCR (AT91_BASE + \ - AT91SAM9G20_RSTC_BASE + RST_CR) - -/* - * From AT91SAM9G20 Datasheet errata 44:3.5: - * - * When User Reset occurs during SDRAM read access, the SDRAM clock is turned - * off while data are ready to be read on the data bus. The SDRAM maintains - * the data until the clock restarts. - * - * If the User reset is programed to assert a general reset, the data - * maintained by the SDRAM leads to a data bus conflict and adversly affects - * the boot memories connected to the EBI: - * + NAND Flash boot functionality, if the system boots out of internal ROM. - * + NOR Flash boot, if the system boots on an external memory connected to - * the EBI CS0. - * - * Assembly code is mandatory for the following sequnce as ARM - * instructions need to be piplined. - * - */ - -ENTRY(cpu_reset_sam9g20) - - /* Disable IRQs */ - mrs r0, cpsr - orr r0, r0, #0x80 - msr cpsr_c, r0 - - /* Change Refresh to block all data access */ - ldr r0, =SDRAM_TR - ldr r1, =1 - str r1, [r0] - - /* Prepare power down command */ - ldr r0, =SDRAM_LPR - ldr r1, =2 - - /* Prepare proc_reset and periph reset */ - ldr r2, =RSTC_RCR - ldr r3, =0xA5000005 - - /* perform power down command */ - str r1, [r0] - - /* Perfom proc_reset and periph reset (in the ARM pipeline) */ - str r3, [r2] Index: head/sys/arm/at91/at91_rst.c =================================================================== --- head/sys/arm/at91/at91_rst.c +++ head/sys/arm/at91/at91_rst.c @@ -1,236 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010 Greg Ansley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "opt_platform.h" - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#ifdef FDT -#include -#include -#define FDT_HACKS 1 -#endif - -#define RST_TIMEOUT (5) /* Seconds to hold NRST for hard reset */ -#define RST_TICK (20) /* sample NRST at hz/RST_TICK intervals */ - -#ifndef FDT -static int at91_rst_intr(void *arg); -#endif - -static struct at91_rst_softc { - struct resource *mem_res; /* Memory resource */ - struct resource *irq_res; /* IRQ resource */ - void *intrhand; /* Interrupt handle */ - struct callout tick_ch; /* Tick callout */ - device_t sc_dev; - u_int shutdown; /* Shutdown in progress */ -} *at91_rst_sc; - -static inline uint32_t -RD4(struct at91_rst_softc *sc, bus_size_t off) -{ - - return (bus_read_4(sc->mem_res, off)); -} - -static inline void -WR4(struct at91_rst_softc *sc, bus_size_t off, uint32_t val) -{ - - bus_write_4(sc->mem_res, off, val); -} - -void cpu_reset_sam9g20(void) __attribute__((weak)); -void cpu_reset_sam9g20(void) {} - -void -at91_rst_cpu_reset(void) -{ - - if (at91_rst_sc) { - cpu_reset_sam9g20(); /* May be null */ - - WR4(at91_rst_sc, RST_MR, - RST_MR_ERSTL(0xd) | RST_MR_URSTEN | RST_MR_KEY); - - WR4(at91_rst_sc, RST_CR, - RST_CR_PROCRST | - RST_CR_PERRST | - RST_CR_EXTRST | - RST_CR_KEY); - } - while(1) - continue; -} - -static int -at91_rst_probe(device_t dev) -{ -#ifdef FDT - if (!ofw_bus_is_compatible(dev, "atmel,at91sam9260-rstc")) - return (ENXIO); -#endif - - device_set_desc(dev, "AT91SAM9 Reset Controller"); - return (0); -} - -static int -at91_rst_attach(device_t dev) -{ - struct at91_rst_softc *sc; - const char *cause; - int rid, err = 0; - - at91_rst_sc = sc = device_get_softc(dev); - sc->sc_dev = dev; - - callout_init(&sc->tick_ch, 1); - - rid = 0; - sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - if (sc->mem_res == NULL) { - device_printf(dev, "could not allocate memory resources.\n"); - err = ENOMEM; - goto out; - } - -#ifndef FDT_HACKS - rid = 0; - sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_ACTIVE | RF_SHAREABLE); - if (sc->irq_res == NULL) { - device_printf(dev, "could not allocate interrupt resources.\n"); - err = ENOMEM; - goto out; - } - - /* Activate the interrupt. */ - err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, - at91_rst_intr, NULL, sc, &sc->intrhand); - if (err) - device_printf(dev, "could not establish interrupt handler.\n"); -#endif - - WR4(at91_rst_sc, RST_MR, RST_MR_ERSTL(0xd) | RST_MR_URSIEN | RST_MR_KEY); - - switch (RD4(sc, RST_SR) & RST_SR_RST_MASK) { - case RST_SR_RST_POW: - cause = "Power On"; - break; - case RST_SR_RST_WAKE: - cause = "Wake Up"; - break; - case RST_SR_RST_WDT: - cause = "Watchdog"; - break; - case RST_SR_RST_SOFT: - cause = "Software Request"; - break; - case RST_SR_RST_USR: - cause = "External (User)"; - break; - default: - cause = "Unknown"; - break; - } - - device_printf(dev, "Reset cause: %s.\n", cause); -out: - return (err); -} - -#ifndef FDT_HACKS -static void -at91_rst_tick(void *argp) -{ - struct at91_rst_softc *sc = argp; - - if (sc->shutdown++ >= RST_TIMEOUT * RST_TICK) { - /* User released the button in morre than RST_TIMEOUT */ - cpu_reset(); - } else if ((RD4(sc, RST_SR) & RST_SR_NRSTL)) { - /* User released the button in less than RST_TIMEOUT */ - sc->shutdown = 0; - device_printf(sc->sc_dev, "shutting down...\n"); - shutdown_nice(0); - } else { - callout_reset(&sc->tick_ch, hz/RST_TICK, at91_rst_tick, sc); - } -} - -static int -at91_rst_intr(void *argp) -{ - struct at91_rst_softc *sc = argp; - - if (RD4(sc, RST_SR) & RST_SR_URSTS) { - if (sc->shutdown == 0) - callout_reset(&sc->tick_ch, hz/RST_TICK, at91_rst_tick, sc); - return (FILTER_HANDLED); - } - return (FILTER_STRAY); -} -#endif - -static device_method_t at91_rst_methods[] = { - DEVMETHOD(device_probe, at91_rst_probe), - DEVMETHOD(device_attach, at91_rst_attach), - DEVMETHOD_END -}; - -static driver_t at91_rst_driver = { - "at91_rst", - at91_rst_methods, - sizeof(struct at91_rst_softc), -}; - -static devclass_t at91_rst_devclass; - -#ifdef FDT -DRIVER_MODULE(at91_rst, simplebus, at91_rst_driver, at91_rst_devclass, NULL, - NULL); -#else -DRIVER_MODULE(at91_rst, atmelarm, at91_rst_driver, at91_rst_devclass, NULL, - NULL); -#endif Index: head/sys/arm/at91/at91_rstreg.h =================================================================== --- head/sys/arm/at91/at91_rstreg.h +++ head/sys/arm/at91/at91_rstreg.h @@ -1,65 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2009 Greg Ansley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef ARM_AT91_AT91_RSTREG_H -#define ARM_AT91_AT91_RSTREG_H - -#define RST_CR 0x0 /* Control Register */ -#define RST_SR 0x4 /* Status Register */ -#define RST_MR 0x8 /* Mode Register */ - -/* RST_CR */ -#define RST_CR_PROCRST (1<<0) -#define RST_CR_PERRST (1<<2) -#define RST_CR_EXTRST (1<<3) -#define RST_CR_KEY (0xa5<<24) - -/* RST_SR */ -#define RST_SR_SRCMP (1<<17) /* Software Reset in progress */ -#define RST_SR_NRSTL (1<<16) /* NRST pin level at MCK */ -#define RST_SR_URSTS (1<<0) /* NRST pin has been active */ - -#define RST_SR_RST_POW (0<<8) /* General (Power On) reset */ -#define RST_SR_RST_WAKE (1<<8) /* Wake-up reset */ -#define RST_SR_RST_WDT (2<<8) /* Watchdog reset */ -#define RST_SR_RST_SOFT (3<<8) /* Software reset */ -#define RST_SR_RST_USR (4<<8) /* User (External) reset */ -#define RST_SR_RST_MASK (7<<8) /* User (External) reset */ - -/* RST_MR */ -#define RST_MR_URSTEN (1<<0) /* User reset enable */ -#define RST_MR_URSIEN (1<<4) /* User interrupt enable */ -#define RST_MR_ERSTL(x) ((x)<<8) /* External reset length */ -#define RST_MR_KEY (0xa5<<24) - -#ifndef __ASSEMBLER__ -void at91_rst_cpu_reset(void); -#endif - -#endif /* ARM_AT91_AT91_RSTREG_H */ Index: head/sys/arm/at91/at91_rtc.c =================================================================== --- head/sys/arm/at91/at91_rtc.c +++ head/sys/arm/at91/at91_rtc.c @@ -1,366 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2006 M. Warner Losh. - * Copyright (c) 2012 Ian Lepore. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Driver for the at91 on-chip realtime clock. - * - * This driver does not currently support alarms, just date and time. - * - * The RTC on the AT91RM9200 resets when the core rests, so it is useless as a - * source of time (except when the CPU clock is powered down to save power, - * which we don't currently do). On AT91SAM9 chips, the RTC survives chip - * reset, and there's provisions for it to keep time via battery backup if the - * system loses power. On those systems, we use it as a RTC. We tell the two - * apart because the century field is 19 on AT91RM9200 on reset, or on AT91SAM9 - * chips that haven't had their time properly set. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "clock_if.h" - -/* - * The driver has all the infrastructure to use interrupts but doesn't actually - * have any need to do so right now. There's a non-zero cost for installing the - * handler because the RTC shares the system interrupt (IRQ 1), and thus will - * get called a lot for no reason at all. - */ -#define AT91_RTC_USE_INTERRUPTS_NOT - -struct at91_rtc_softc -{ - device_t dev; /* Myself */ - void *intrhand; /* Interrupt handle */ - struct resource *irq_res; /* IRQ resource */ - struct resource *mem_res; /* Memory resource */ - struct mtx sc_mtx; /* basically a perimeter lock */ -}; - -static inline uint32_t -RD4(struct at91_rtc_softc *sc, bus_size_t off) -{ - return bus_read_4(sc->mem_res, off); -} - -static inline void -WR4(struct at91_rtc_softc *sc, bus_size_t off, uint32_t val) -{ - bus_write_4(sc->mem_res, off, val); -} - -#define AT91_RTC_LOCK(_sc) mtx_lock_spin(&(_sc)->sc_mtx) -#define AT91_RTC_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->sc_mtx) -#define AT91_RTC_LOCK_INIT(_sc) \ - mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \ - "rtc", MTX_SPIN) -#define AT91_RTC_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); -#define AT91_RTC_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED); -#define AT91_RTC_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); - -static devclass_t at91_rtc_devclass; - -/* bus entry points */ - -static int at91_rtc_probe(device_t dev); -static int at91_rtc_attach(device_t dev); -static int at91_rtc_detach(device_t dev); - -/* helper routines */ -static int at91_rtc_activate(device_t dev); -static void at91_rtc_deactivate(device_t dev); - -#ifdef AT91_RTC_USE_INTERRUPTS -static int -at91_rtc_intr(void *xsc) -{ - struct at91_rtc_softc *sc; - uint32_t status; - - sc = xsc; - /* Must clear the status bits after reading them to re-arm. */ - status = RD4(sc, RTC_SR); - WR4(sc, RTC_SCCR, status); - if (status == 0) - return; - AT91_RTC_LOCK(sc); - /* Do something here */ - AT91_RTC_UNLOCK(sc); - wakeup(sc); - return (FILTER_HANDLED); -} -#endif - -static int -at91_rtc_probe(device_t dev) -{ - device_set_desc(dev, "RTC"); - return (0); -} - -static int -at91_rtc_attach(device_t dev) -{ - struct at91_rtc_softc *sc = device_get_softc(dev); - int err; - - sc->dev = dev; - err = at91_rtc_activate(dev); - if (err) - goto out; - - AT91_RTC_LOCK_INIT(sc); - - /* - * Disable all interrupts in the hardware. - * Clear all bits in the status register. - * Set 24-hour-clock mode. - */ - WR4(sc, RTC_IDR, 0xffffffff); - WR4(sc, RTC_SCCR, 0x1f); - WR4(sc, RTC_MR, 0); - -#ifdef AT91_RTC_USE_INTERRUPTS - err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC, - at91_rtc_intr, NULL, sc, &sc->intrhand); - if (err) { - AT91_RTC_LOCK_DESTROY(sc); - goto out; - } -#endif - - /* - * Read the calendar register. If the century is 19 then the clock has - * never been set. Try to store an invalid value into the register, - * which will turn on the error bit in RTC_VER, and our getclock code - * knows to return EINVAL if any error bits are on. - */ - if (RTC_CALR_CEN(RD4(sc, RTC_CALR)) == 19) - WR4(sc, RTC_CALR, 0); - - /* - * Register as a time of day clock with 1-second resolution. - */ - clock_register(dev, 1000000); -out: - if (err) - at91_rtc_deactivate(dev); - return (err); -} - -/* - * Cannot support detach, since there's no clock_unregister function. - */ -static int -at91_rtc_detach(device_t dev) -{ - return (EBUSY); -} - -static int -at91_rtc_activate(device_t dev) -{ - struct at91_rtc_softc *sc; - int rid; - - sc = device_get_softc(dev); - rid = 0; - sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - if (sc->mem_res == NULL) - goto errout; -#ifdef AT91_RTC_USE_INTERRUPTS - rid = 0; - sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_ACTIVE | RF_SHAREABLE); - if (sc->irq_res == NULL) - goto errout; -#endif - return (0); -errout: - at91_rtc_deactivate(dev); - return (ENOMEM); -} - -static void -at91_rtc_deactivate(device_t dev) -{ - struct at91_rtc_softc *sc; - - sc = device_get_softc(dev); -#ifdef AT91_RTC_USE_INTERRUPTS - WR4(sc, RTC_IDR, 0xffffffff); - if (sc->intrhand) - bus_teardown_intr(dev, sc->irq_res, sc->intrhand); - sc->intrhand = NULL; -#endif - bus_generic_detach(sc->dev); - if (sc->mem_res) - bus_release_resource(dev, SYS_RES_MEMORY, - rman_get_rid(sc->mem_res), sc->mem_res); - sc->mem_res = NULL; -#ifdef AT91_RTC_USE_INTERRUPTS - if (sc->irq_res) - bus_release_resource(dev, SYS_RES_IRQ, - rman_get_rid(sc->irq_res), sc->irq_res); - sc->irq_res = NULL; -#endif - return; -} - -/* - * Get the time of day clock and return it in ts. - * Return 0 on success, an error number otherwise. - */ -static int -at91_rtc_gettime(device_t dev, struct timespec *ts) -{ - struct clocktime ct; - uint32_t calr, calr2, timr, timr2; - struct at91_rtc_softc *sc; - - sc = device_get_softc(dev); - - /* If the error bits are set we can't return useful values. */ - - if (RD4(sc, RTC_VER) & (RTC_VER_NVTIM | RTC_VER_NVCAL)) - return EINVAL; - - /* - * The RTC hardware can update registers while the CPU is reading them. - * The manual advises reading until you obtain the same values twice. - * Interleaving the reads (rather than timr, timr2, calr, calr2 order) - * also ensures we don't miss a midnight rollover/carry between reads. - */ - do { - timr = RD4(sc, RTC_TIMR); - calr = RD4(sc, RTC_CALR); - timr2 = RD4(sc, RTC_TIMR); - calr2 = RD4(sc, RTC_CALR); - } while (timr != timr2 || calr != calr2); - - ct.nsec = 0; - ct.sec = RTC_TIMR_SEC(timr); - ct.min = RTC_TIMR_MIN(timr); - ct.hour = RTC_TIMR_HR(timr); - ct.year = RTC_CALR_CEN(calr) * 100 + RTC_CALR_YEAR(calr); - ct.mon = RTC_CALR_MON(calr); - ct.day = RTC_CALR_DAY(calr); - ct.dow = -1; - return clock_ct_to_ts(&ct, ts); -} - -/* - * Set the time of day clock based on the value of the struct timespec arg. - * Return 0 on success, an error number otherwise. - */ -static int -at91_rtc_settime(device_t dev, struct timespec *ts) -{ - struct at91_rtc_softc *sc; - struct clocktime ct; - int rv; - - sc = device_get_softc(dev); - clock_ts_to_ct(ts, &ct); - - /* - * Can't set the clock unless a second has elapsed since we last did so. - */ - while ((RD4(sc, RTC_SR) & RTC_SR_SECEV) == 0) - cpu_spinwait(); - - /* - * Stop the clocks for an update; wait until hardware is ready. - * Clear the update-ready status after it gets asserted (the manual says - * to do this before updating the value registers). - */ - WR4(sc, RTC_CR, RTC_CR_UPDCAL | RTC_CR_UPDTIM); - while ((RD4(sc, RTC_SR) & RTC_SR_ACKUPD) == 0) - cpu_spinwait(); - WR4(sc, RTC_SCCR, RTC_SR_ACKUPD); - - /* - * Set the values in the hardware, then check whether the hardware was - * happy with them so we can return the correct status. - */ - WR4(sc, RTC_TIMR, RTC_TIMR_MK(ct.hour, ct.min, ct.sec)); - WR4(sc, RTC_CALR, RTC_CALR_MK(ct.year, ct.mon, ct.day, ct.dow+1)); - - if (RD4(sc, RTC_VER) & (RTC_VER_NVTIM | RTC_VER_NVCAL)) - rv = EINVAL; - else - rv = 0; - - /* - * Restart the clocks (turn off the update bits). - * Clear the second-event bit (because the manual says to). - */ - WR4(sc, RTC_CR, RD4(sc, RTC_CR) & ~(RTC_CR_UPDCAL | RTC_CR_UPDTIM)); - WR4(sc, RTC_SCCR, RTC_SR_SECEV); - - return (0); -} - -static device_method_t at91_rtc_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, at91_rtc_probe), - DEVMETHOD(device_attach, at91_rtc_attach), - DEVMETHOD(device_detach, at91_rtc_detach), - - /* clock interface */ - DEVMETHOD(clock_gettime, at91_rtc_gettime), - DEVMETHOD(clock_settime, at91_rtc_settime), - - DEVMETHOD_END -}; - -static driver_t at91_rtc_driver = { - "at91_rtc", - at91_rtc_methods, - sizeof(struct at91_rtc_softc), -}; - -DRIVER_MODULE(at91_rtc, atmelarm, at91_rtc_driver, at91_rtc_devclass, 0, 0); Index: head/sys/arm/at91/at91_rtcreg.h =================================================================== --- head/sys/arm/at91/at91_rtcreg.h +++ head/sys/arm/at91/at91_rtcreg.h @@ -1,105 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2006 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef ARM_AT91_AT91_RTCREG_H -#define ARM_AT91_AT91_RTCREG_H - -/* Registers */ -#define RTC_CR 0x00 /* RTC Control Register */ -#define RTC_MR 0x04 /* RTC Mode Register */ -#define RTC_TIMR 0x08 /* RTC Time Register */ -#define RTC_CALR 0x0c /* RTC Calendar Register */ -#define RTC_TIMALR 0x10 /* RTC Time Alarm Register */ -#define RTC_CALALR 0x14 /* RTC Calendar Alarm Register */ -#define RTC_SR 0x18 /* RTC Status Register */ -#define RTC_SCCR 0x1c /* RTC Status Command Clear Register */ -#define RTC_IER 0x20 /* RTC Interrupt Enable Register */ -#define RTC_IDR 0x24 /* RTC Interrupt Disable Register */ -#define RTC_IMR 0x28 /* RTC Interrupt Mask Register */ -#define RTC_VER 0x2c /* RTC Valid Entry Register */ - -/* CR */ -#define RTC_CR_UPDTIM (0x1u << 0) /* Request update of time register */ -#define RTC_CR_UPDCAL (0x1u << 1) /* Request update of calendar reg. */ - -/* TIMR */ -#define RTC_TIMR_SEC_M 0x7fUL -#define RTC_TIMR_SEC_S 0 -#define RTC_TIMR_SEC(x) FROMBCD(((x) & RTC_TIMR_SEC_M) >> RTC_TIMR_SEC_S) -#define RTC_TIMR_MIN_M 0x7f00UL -#define RTC_TIMR_MIN_S 8 -#define RTC_TIMR_MIN(x) FROMBCD(((x) & RTC_TIMR_MIN_M) >> RTC_TIMR_MIN_S) -#define RTC_TIMR_HR_M 0x3f0000UL -#define RTC_TIMR_HR_S 16 -#define RTC_TIMR_HR(x) FROMBCD(((x) & RTC_TIMR_HR_M) >> RTC_TIMR_HR_S) -#define RTC_TIMR_MK(hr, min, sec) \ - ((TOBCD(hr) << RTC_TIMR_HR_S) | \ - (TOBCD(min) << RTC_TIMR_MIN_S) | \ - (TOBCD(sec) << RTC_TIMR_SEC_S)) -#define RTC_TIMR_PM (1UL << 22) - -/* CALR */ -#define RTC_CALR_CEN_M 0x0000007fUL -#define RTC_CALR_CEN_S 0 -#define RTC_CALR_CEN(x) FROMBCD(((x) & RTC_CALR_CEN_M) >> RTC_CALR_CEN_S) -#define RTC_CALR_YEAR_M 0x0000ff00UL -#define RTC_CALR_YEAR_S 8 -#define RTC_CALR_YEAR(x) FROMBCD(((x) & RTC_CALR_YEAR_M) >> RTC_CALR_YEAR_S) -#define RTC_CALR_MON_M 0x001f0000UL -#define RTC_CALR_MON_S 16 -#define RTC_CALR_MON(x) FROMBCD(((x) & RTC_CALR_MON_M) >> RTC_CALR_MON_S) -#define RTC_CALR_DOW_M 0x00d0000UL -#define RTC_CALR_DOW_S 21 -#define RTC_CALR_DOW(x) FROMBCD(((x) & RTC_CALR_DOW_M) >> RTC_CALR_DOW_S) -#define RTC_CALR_DAY_M 0x3f000000UL -#define RTC_CALR_DAY_S 24 -#define RTC_CALR_DAY(x) FROMBCD(((x) & RTC_CALR_DAY_M) >> RTC_CALR_DAY_S) -#define RTC_CALR_MK(yr, mon, day, dow) \ - ((TOBCD((yr) / 100) << RTC_CALR_CEN_S) | \ - (TOBCD((yr) % 100) << RTC_CALR_YEAR_S) | \ - (TOBCD(mon) << RTC_CALR_MON_S) | \ - (TOBCD(dow) << RTC_CALR_DOW_S) | \ - (TOBCD(day) << RTC_CALR_DAY_S)) - -/* SR */ - -#define RTC_SR_ACKUPD (0x1u << 0) /* Acknowledge for Update */ -#define RTC_SR_ALARM (0x1u << 1) /* Alarm Flag */ -#define RTC_SR_SECEV (0x1u << 2) /* Second Event */ -#define RTC_SR_TIMEV (0x1u << 3) /* Time Event */ -#define RTC_SR_CALEV (0x1u << 4) /* Calendar event */ - -/* VER */ - -#define RTC_VER_NVTIM (0x1 << 0) /* Non-valid time */ -#define RTC_VER_NVCAL (0x1 << 1) /* Non-valid calendar */ -#define RTC_VER_NVTIMALR (0x1 << 2) /* Non-valid time alarm */ -#define RTC_VER_NVCALALR (0x1 << 3) /* Non-valid calendar alarm */ - -#endif /* ARM_AT91_AT91_RTCREG_H */ Index: head/sys/arm/at91/at91_sdramc.c =================================================================== --- head/sys/arm/at91/at91_sdramc.c +++ head/sys/arm/at91/at91_sdramc.c @@ -1,106 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2014 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "opt_platform.h" - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#ifdef FDT -#include -#include -#endif - -struct sdramc_softc { - struct resource *mem_res; /* Memory resource */ - device_t sc_dev; -}; - -static int -at91_sdramc_probe(device_t dev) -{ -#ifdef FDT - if (!ofw_bus_is_compatible(dev, "atmel,at91sam9260-sdramc")) - return (ENXIO); -#endif - device_set_desc(dev, "SDRAMC"); - return (0); -} - -static int -at91_sdramc_attach(device_t dev) -{ - int rid, err = 0; - struct sdramc_softc *sc; - - sc = device_get_softc(dev); - sc->sc_dev = dev; - - rid = 0; - sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - - if (sc->mem_res == NULL) - panic("couldn't allocate register resources"); - - return (err); -} - -static device_method_t at91_sdramc_methods[] = { - DEVMETHOD(device_probe, at91_sdramc_probe), - DEVMETHOD(device_attach, at91_sdramc_attach), - DEVMETHOD_END -}; - -static driver_t at91_sdramc_driver = { - "at91_sdramc", - at91_sdramc_methods, - sizeof(struct sdramc_softc), -}; - -static devclass_t at91_sdramc_devclass; - -#ifdef FDT -DRIVER_MODULE(at91_sdramc, simplebus, at91_sdramc_driver, at91_sdramc_devclass, NULL, - NULL); -#else -DRIVER_MODULE(at91_sdramc, atmelarm, at91_sdramc_driver, at91_sdramc_devclass, NULL, - NULL); -#endif Index: head/sys/arm/at91/at91_shdwc.c =================================================================== --- head/sys/arm/at91/at91_shdwc.c +++ head/sys/arm/at91/at91_shdwc.c @@ -1,106 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2014 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "opt_platform.h" - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#ifdef FDT -#include -#include -#endif - -struct shdwc_softc { - struct resource *mem_res; /* Memory resource */ - device_t sc_dev; -}; - -static int -at91_shdwc_probe(device_t dev) -{ -#ifdef FDT - if (!ofw_bus_is_compatible(dev, "atmel,at91sam9260-shdwc")) - return (ENXIO); -#endif - device_set_desc(dev, "SHDWC"); - return (0); -} - -static int -at91_shdwc_attach(device_t dev) -{ - int rid, err = 0; - struct shdwc_softc *sc; - - sc = device_get_softc(dev); - sc->sc_dev = dev; - - rid = 0; - sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - - if (sc->mem_res == NULL) - panic("couldn't allocate register resources"); - - return (err); -} - -static device_method_t at91_shdwc_methods[] = { - DEVMETHOD(device_probe, at91_shdwc_probe), - DEVMETHOD(device_attach, at91_shdwc_attach), - DEVMETHOD_END -}; - -static driver_t at91_shdwc_driver = { - "at91_shdwc", - at91_shdwc_methods, - sizeof(struct shdwc_softc), -}; - -static devclass_t at91_shdwc_devclass; - -#ifdef FDT -DRIVER_MODULE(at91_shdwc, simplebus, at91_shdwc_driver, at91_shdwc_devclass, NULL, - NULL); -#else -DRIVER_MODULE(at91_shdwc, atmelarm, at91_shdwc_driver, at91_shdwc_devclass, NULL, - NULL); -#endif Index: head/sys/arm/at91/at91_smc.h =================================================================== --- head/sys/arm/at91/at91_smc.h +++ head/sys/arm/at91/at91_smc.h @@ -1,118 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2014 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef ARM_AT91_AT91_SMC_H -#define ARM_AT91_AT91_SMC_H - -/* Registers */ -#define SMC_SETUP 0x00 -#define SMC_PULSE 0x04 -#define SMC_CYCLE 0x08 -#define SMC_MODE 0x0C - -#define SMC_CS_OFF(cs) (0x10 * (cs)) - -/* Setup */ -#define SMC_SETUP_NCS_RD_SETUP(x) ((x) << 24) -#define SMC_SETUP_NRD_SETUP(x) ((x) << 16) -#define SMC_SETUP_NCS_WR_SETUP(x) ((x) << 8) -#define SMC_SETUP_NWE_SETUP(x) (x) - -/* Pulse */ -#define SMC_PULSE_NCS_RD_PULSE(x) ((x) << 24) -#define SMC_PULSE_NRD_PULSE(x) ((x) << 16) -#define SMC_PULSE_NCS_WR_PULSE(x) ((x) << 8) -#define SMC_PULSE_NWE_PULSE(x) (x) - -/* Cycle */ -#define SMC_CYCLE_NRD_CYCLE(x) ((x) << 16) -#define SMC_CYCLE_NWE_CYCLE(x) (x) - -/* Mode */ -#define SMC_MODE_READ (1 << 0) -#define SMC_MODE_WRITE (1 << 1) -#define SMC_MODE_EXNW_DISABLED (0 << 4) -#define SMC_MODE_EXNW_FROZEN_MODE (2 << 4) -#define SMC_MODE_EXNW_READY_MODE (3 << 4) -#define SMC_MODE_BAT (1 << 8) -#define SMC_MODE_DBW_8BIT (0 << 12) -#define SMC_MODE_DBW_16BIT (1 << 12) -#define SMC_MODE_DBW_32_BIT (2 << 12) -#define SMC_MODE_TDF_CYCLES(x) ((x) << 16) -#define SMC_MODE_TDF_MODE (1 << 20) -#define SMC_MODE_PMEN (1 << 24) -#define SMC_PS_4BYTE (0 << 28) -#define SMC_PS_8BYTE (1 << 28) -#define SMC_PS_16BYTE (2 << 28) -#define SMC_PS_32BYTE (3 << 28) - -/* - * structure to ease init. See the SMC chapter in the datasheet for - * the appropriate SoC you are using for details. - */ -struct at91_smc_init -{ - /* Setup register */ - uint8_t ncs_rd_setup; - uint8_t nrd_setup; - uint8_t ncs_wr_setup; - uint8_t nwe_setup; - - /* Pulse register */ - uint8_t ncs_rd_pulse; - uint8_t nrd_pulse; - uint8_t ncs_wr_pulse; - uint8_t nwe_pulse; - - /* Cycle register */ - uint16_t nrd_cycle; - uint16_t nwe_cycle; - - /* Mode register */ - uint8_t mode; /* Combo of READ/WRITE/EXNW fields */ - uint8_t bat; - uint8_t dwb; - uint8_t tdf_cycles; - uint8_t tdf_mode; - uint8_t pmen; - uint8_t ps; -}; - -/* - * Convenience routine to fill in SMC registers for a given chip select. - */ -void at91_smc_setup(int id, int cs, const struct at91_smc_init *smc); - -/* - * Disable/Enable different External Bus Interfaces (EBI) - */ -void at91_ebi_enable(int cs); -void at91_ebi_disable(int cs); - -#endif /* ARM_AT91_AT91_SMC_H */ Index: head/sys/arm/at91/at91_smc.c =================================================================== --- head/sys/arm/at91/at91_smc.c +++ head/sys/arm/at91/at91_smc.c @@ -1,93 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2014 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include - -#include -#include -#include - -/* - * RD4HW()/WR4HW() read and write at91 hardware register space directly. They - * serve the same purpose as the RD4()/WR4() idiom you see in many drivers, - * except that those translate to bus_space calls, but in this code we need to - * access some devices before bus_space is ready to use. Of course for this to - * work the appropriate static device mappings need to be made in machdep.c. - */ -static inline uint32_t -RD4HW(uint32_t devbase, uint32_t regoff) -{ - - return *(volatile uint32_t *)(AT91_BASE + devbase + regoff); -} - - -static inline void -WR4HW(uint32_t devbase, uint32_t regoff, uint32_t val) -{ - - *(volatile uint32_t *)(AT91_BASE + devbase + regoff) = val; -} - - -void -at91_smc_setup(int id, int cs, const struct at91_smc_init *smc) -{ - // Need a generic way to get this address for all SoCs... Assume 9260 for now... - uint32_t base = AT91SAM9260_SMC_BASE + SMC_CS_OFF(cs); - - WR4HW(base, SMC_SETUP, SMC_SETUP_NCS_RD_SETUP(smc->ncs_rd_setup) | - SMC_SETUP_NRD_SETUP(smc->nrd_setup) | - SMC_SETUP_NCS_WR_SETUP(smc->ncs_wr_setup) | - SMC_SETUP_NWE_SETUP(smc->nwe_setup)); - WR4HW(base, SMC_PULSE, SMC_PULSE_NCS_RD_PULSE(smc->ncs_rd_pulse) | - SMC_PULSE_NRD_PULSE(smc->nrd_pulse) | - SMC_PULSE_NCS_WR_PULSE(smc->ncs_wr_pulse) | - SMC_PULSE_NWE_PULSE(smc->nwe_pulse)); - WR4HW(base, SMC_CYCLE, SMC_CYCLE_NRD_CYCLE(smc->nrd_cycle) | - SMC_CYCLE_NWE_CYCLE(smc->nwe_cycle)); - WR4HW(base, SMC_MODE, smc->mode | SMC_MODE_TDF_CYCLES(smc->tdf_cycles)); -} - -void -at91_ebi_enable(int bank) -{ - - WR4HW(AT91SAM9260_MATRIX_BASE, AT91SAM9260_EBICSA, (1 << bank) | - RD4HW(AT91SAM9260_MATRIX_BASE, AT91SAM9260_EBICSA)); -} - -void -at91_ebi_disable(int bank) -{ - - WR4HW(AT91SAM9260_MATRIX_BASE, AT91SAM9260_EBICSA, ~(1 << bank) & - RD4HW(AT91SAM9260_MATRIX_BASE, AT91SAM9260_EBICSA)); -} Index: head/sys/arm/at91/at91_spi.c =================================================================== --- head/sys/arm/at91/at91_spi.c +++ head/sys/arm/at91/at91_spi.c @@ -1,461 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2006 M. Warner Losh. - * Copyright (c) 2011-2012 Ian Lepore. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "opt_platform.h" - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include - -#ifdef FDT -#include -#include -#endif - -#include "spibus_if.h" - -struct at91_spi_softc -{ - device_t dev; /* Myself */ - void *intrhand; /* Interrupt handle */ - struct resource *irq_res; /* IRQ resource */ - struct resource *mem_res; /* Memory resource */ - bus_dma_tag_t dmatag; /* bus dma tag for transfers */ - bus_dmamap_t map[4]; /* Maps for the transaction */ - struct sx xfer_mtx; /* Enforce one transfer at a time */ - uint32_t xfer_done; /* interrupt<->mainthread signaling */ -}; - -#define CS_TO_MR(cs) ((~(1 << (cs)) & 0x0f) << 16) - -static inline uint32_t -RD4(struct at91_spi_softc *sc, bus_size_t off) -{ - - return (bus_read_4(sc->mem_res, off)); -} - -static inline void -WR4(struct at91_spi_softc *sc, bus_size_t off, uint32_t val) -{ - - bus_write_4(sc->mem_res, off, val); -} - -/* bus entry points */ -static int at91_spi_attach(device_t dev); -static int at91_spi_detach(device_t dev); -static int at91_spi_probe(device_t dev); -static int at91_spi_transfer(device_t dev, device_t child, - struct spi_command *cmd); - -/* helper routines */ -static void at91_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, - int error); -static int at91_spi_activate(device_t dev); -static void at91_spi_deactivate(device_t dev); -static void at91_spi_intr(void *arg); - -static int -at91_spi_probe(device_t dev) -{ -#ifdef FDT - if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-spi")) - return (ENXIO); -#endif - device_set_desc(dev, "AT91 SPI"); - return (0); -} - -static int -at91_spi_attach(device_t dev) -{ - struct at91_spi_softc *sc; - int err; - uint32_t csr; - - sc = device_get_softc(dev); - - sc->dev = dev; - sx_init(&sc->xfer_mtx, device_get_nameunit(dev)); - - /* - * Allocate resources. - */ - err = at91_spi_activate(dev); - if (err) - goto out; - -#ifdef FDT - /* - * Disable devices need to hold their resources, so return now and not attach - * the spibus, setup interrupt handlers, etc. - */ - if (!ofw_bus_status_okay(dev)) - return 0; -#endif - - /* - * Set up the hardware. - */ - - WR4(sc, SPI_CR, SPI_CR_SWRST); - /* "Software Reset must be Written Twice" erratum */ - WR4(sc, SPI_CR, SPI_CR_SWRST); - WR4(sc, SPI_IDR, 0xffffffff); - - WR4(sc, SPI_MR, (0xf << 24) | SPI_MR_MSTR | SPI_MR_MODFDIS | - CS_TO_MR(0)); - - /* - * For now, run the bus at the slowest speed possible as otherwise we - * may encounter data corruption on transmit as seen with ETHERNUT5 - * and AT45DB321D even though both board and slave device can take - * more. - * This also serves as a work-around for the "NPCSx rises if no data - * data is to be transmitted" erratum. The ideal workaround for the - * latter is to take the chip select control away from the peripheral - * and manage it directly as a GPIO line. The easy solution is to - * slow down the bus so dramatically that it just never gets starved - * as may be seen when the OCHI controller is running and consuming - * memory and APB bandwidth. - * Also, currently we lack a way for lettting both the board and the - * slave devices take their maximum supported SPI clocks into account. - * Also, we hard-wire SPI mode to 3. - */ - csr = SPI_CSR_CPOL | (4 << 16) | (0xff << 8); - WR4(sc, SPI_CSR0, csr); - WR4(sc, SPI_CSR1, csr); - WR4(sc, SPI_CSR2, csr); - WR4(sc, SPI_CSR3, csr); - - WR4(sc, SPI_CR, SPI_CR_SPIEN); - - WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS); - WR4(sc, PDC_PTCR, PDC_PTCR_RXTDIS); - WR4(sc, PDC_RNPR, 0); - WR4(sc, PDC_RNCR, 0); - WR4(sc, PDC_TNPR, 0); - WR4(sc, PDC_TNCR, 0); - WR4(sc, PDC_RPR, 0); - WR4(sc, PDC_RCR, 0); - WR4(sc, PDC_TPR, 0); - WR4(sc, PDC_TCR, 0); - RD4(sc, SPI_RDR); - RD4(sc, SPI_SR); - - device_add_child(dev, "spibus", -1); - bus_generic_attach(dev); -out: - if (err) - at91_spi_deactivate(dev); - return (err); -} - -static int -at91_spi_detach(device_t dev) -{ - - return (EBUSY); /* XXX */ -} - -static int -at91_spi_activate(device_t dev) -{ - struct at91_spi_softc *sc; - int err, i, rid; - - sc = device_get_softc(dev); - err = ENOMEM; - - rid = 0; - sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - if (sc->mem_res == NULL) - goto out; - - rid = 0; - sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_ACTIVE); - if (sc->irq_res == NULL) - goto out; - err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, - NULL, at91_spi_intr, sc, &sc->intrhand); - if (err != 0) - goto out; - - err = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0, - BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, 2048, 1, - 2048, BUS_DMA_ALLOCNOW, NULL, NULL, &sc->dmatag); - if (err != 0) - goto out; - - for (i = 0; i < 4; i++) { - err = bus_dmamap_create(sc->dmatag, 0, &sc->map[i]); - if (err != 0) - goto out; - } -out: - if (err != 0) - at91_spi_deactivate(dev); - return (err); -} - -static void -at91_spi_deactivate(device_t dev) -{ - struct at91_spi_softc *sc; - int i; - - sc = device_get_softc(dev); - bus_generic_detach(dev); - - for (i = 0; i < 4; i++) - if (sc->map[i]) - bus_dmamap_destroy(sc->dmatag, sc->map[i]); - - if (sc->dmatag) - bus_dma_tag_destroy(sc->dmatag); - - if (sc->intrhand) - bus_teardown_intr(dev, sc->irq_res, sc->intrhand); - sc->intrhand = NULL; - if (sc->irq_res) - bus_release_resource(dev, SYS_RES_IRQ, - rman_get_rid(sc->irq_res), sc->irq_res); - sc->irq_res = NULL; - - if (sc->mem_res) - bus_release_resource(dev, SYS_RES_MEMORY, - rman_get_rid(sc->mem_res), sc->mem_res); - sc->mem_res = NULL; -} - -static void -at91_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs __unused, - int error) -{ - - if (error != 0) - return; - *(bus_addr_t *)arg = segs[0].ds_addr; -} - -static int -at91_spi_transfer(device_t dev, device_t child, struct spi_command *cmd) -{ - struct at91_spi_softc *sc; - bus_addr_t addr; - int err, i, j, mode[4]; - uint32_t cs; - - KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz, - ("%s: TX/RX command sizes should be equal", __func__)); - KASSERT(cmd->tx_data_sz == cmd->rx_data_sz, - ("%s: TX/RX data sizes should be equal", __func__)); - - /* get the proper chip select */ - spibus_get_cs(child, &cs); - - cs &= ~SPIBUS_CS_HIGH; - - sc = device_get_softc(dev); - i = 0; - - sx_xlock(&sc->xfer_mtx); - - /* - * Disable transfers while we set things up. - */ - WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS); - - /* - * PSCDEC = 0 has a range of 0..3 for chip select. We - * don't support PSCDEC = 1 which has a range of 0..15. - */ - if (cs > 3) { - device_printf(dev, - "Invalid chip select %d requested by %s\n", cs, - device_get_nameunit(child)); - err = EINVAL; - goto out; - } - -#ifdef SPI_CHIP_SELECT_HIGH_SUPPORT - /* - * The AT91RM9200 couldn't do CS high for CS 0. Other chips can, but we - * don't support that yet, or other spi modes. - */ - if (at91_is_rm92() && cs == 0 && - (cmd->flags & SPI_CHIP_SELECT_HIGH) != 0) { - device_printf(dev, - "Invalid chip select high requested by %s for cs 0.\n", - device_get_nameunit(child)); - err = EINVAL; - goto out; - } -#endif - err = (RD4(sc, SPI_MR) & ~0x000f0000) | CS_TO_MR(cs); - WR4(sc, SPI_MR, err); - - /* - * Set up the TX side of the transfer. - */ - if ((err = bus_dmamap_load(sc->dmatag, sc->map[i], cmd->tx_cmd, - cmd->tx_cmd_sz, at91_getaddr, &addr, 0)) != 0) - goto out; - WR4(sc, PDC_TPR, addr); - WR4(sc, PDC_TCR, cmd->tx_cmd_sz); - bus_dmamap_sync(sc->dmatag, sc->map[i], BUS_DMASYNC_PREWRITE); - mode[i++] = BUS_DMASYNC_POSTWRITE; - if (cmd->tx_data_sz > 0) { - if ((err = bus_dmamap_load(sc->dmatag, sc->map[i], - cmd->tx_data, cmd->tx_data_sz, at91_getaddr, &addr, 0)) != - 0) - goto out; - WR4(sc, PDC_TNPR, addr); - WR4(sc, PDC_TNCR, cmd->tx_data_sz); - bus_dmamap_sync(sc->dmatag, sc->map[i], BUS_DMASYNC_PREWRITE); - mode[i++] = BUS_DMASYNC_POSTWRITE; - } - - /* - * Set up the RX side of the transfer. - */ - if ((err = bus_dmamap_load(sc->dmatag, sc->map[i], cmd->rx_cmd, - cmd->rx_cmd_sz, at91_getaddr, &addr, 0)) != 0) - goto out; - WR4(sc, PDC_RPR, addr); - WR4(sc, PDC_RCR, cmd->rx_cmd_sz); - bus_dmamap_sync(sc->dmatag, sc->map[i], BUS_DMASYNC_PREREAD); - mode[i++] = BUS_DMASYNC_POSTREAD; - if (cmd->rx_data_sz > 0) { - if ((err = bus_dmamap_load(sc->dmatag, sc->map[i], - cmd->rx_data, cmd->rx_data_sz, at91_getaddr, &addr, 0)) != - 0) - goto out; - WR4(sc, PDC_RNPR, addr); - WR4(sc, PDC_RNCR, cmd->rx_data_sz); - bus_dmamap_sync(sc->dmatag, sc->map[i], BUS_DMASYNC_PREREAD); - mode[i++] = BUS_DMASYNC_POSTREAD; - } - - /* - * Start the transfer, wait for it to complete. - */ - sc->xfer_done = 0; - WR4(sc, SPI_IER, SPI_SR_RXBUFF); - WR4(sc, PDC_PTCR, PDC_PTCR_TXTEN | PDC_PTCR_RXTEN); - do - err = tsleep(&sc->xfer_done, PCATCH | PZERO, "at91_spi", hz); - while (sc->xfer_done == 0 && err != EINTR); - - /* - * Stop the transfer and clean things up. - */ - WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS); - if (err == 0) - for (j = 0; j < i; j++) - bus_dmamap_sync(sc->dmatag, sc->map[j], mode[j]); -out: - for (j = 0; j < i; j++) - bus_dmamap_unload(sc->dmatag, sc->map[j]); - - sx_xunlock(&sc->xfer_mtx); - - return (err); -} - -static void -at91_spi_intr(void *arg) -{ - struct at91_spi_softc *sc; - uint32_t sr; - - sc = (struct at91_spi_softc*)arg; - - sr = RD4(sc, SPI_SR) & RD4(sc, SPI_IMR); - if ((sr & SPI_SR_RXBUFF) != 0) { - sc->xfer_done = 1; - WR4(sc, SPI_IDR, SPI_SR_RXBUFF); - wakeup(&sc->xfer_done); - } - if ((sr & ~SPI_SR_RXBUFF) != 0) { - device_printf(sc->dev, "Unexpected ISR %#x\n", sr); - WR4(sc, SPI_IDR, sr & ~SPI_SR_RXBUFF); - } -} - -static devclass_t at91_spi_devclass; - -static device_method_t at91_spi_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, at91_spi_probe), - DEVMETHOD(device_attach, at91_spi_attach), - DEVMETHOD(device_detach, at91_spi_detach), - - /* spibus interface */ - DEVMETHOD(spibus_transfer, at91_spi_transfer), - - DEVMETHOD_END -}; - -static driver_t at91_spi_driver = { - "spi", - at91_spi_methods, - sizeof(struct at91_spi_softc), -}; - -#ifdef FDT -DRIVER_MODULE(at91_spi, simplebus, at91_spi_driver, at91_spi_devclass, NULL, - NULL); -#else -DRIVER_MODULE(at91_spi, atmelarm, at91_spi_driver, at91_spi_devclass, NULL, - NULL); -#endif Index: head/sys/arm/at91/at91_spireg.h =================================================================== --- head/sys/arm/at91/at91_spireg.h +++ head/sys/arm/at91/at91_spireg.h @@ -1,71 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2006 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef ARM_AT91_AT91_SPIREG_H -#define ARM_AT91_AT91_SPIREG_H - -#define SPI_CR 0x00 /* CR: Control Register */ -#define SPI_CR_SPIEN 0x1 -#define SPI_CR_SPIDIS 0x2 -#define SPI_CR_SWRST 0x8 -#define SPI_MR 0x04 /* MR: Mode Register */ -#define SPI_MR_MSTR 0x01 -#define SPI_MR_PS 0x02 -#define SPI_MR_PCSDEC 0x04 -#define SPI_MR_DIV32 0x08 -#define SPI_MR_MODFDIS 0x10 -#define SPI_MR_LLB 0x80 -#define SPI_MR_PSC_CS0 0xe0000 -#define SPI_MR_PSC_CS1 0xd0000 -#define SPI_MR_PSC_CS2 0xb0000 -#define SPI_MR_PSC_CS3 0x70000 -#define SPI_RDR 0x08 /* RDR: Receive Data Register */ -#define SPI_TDR 0x0c /* TDR: Transmit Data Register */ -#define SPI_SR 0x10 /* SR: Status Register */ -#define SPI_SR_RDRF 0x00001 -#define SPI_SR_TDRE 0x00002 -#define SPI_SR_MODF 0x00004 -#define SPI_SR_OVRES 0x00008 -#define SPI_SR_ENDRX 0x00010 -#define SPI_SR_ENDTX 0x00020 -#define SPI_SR_RXBUFF 0x00040 -#define SPI_SR_TXBUFE 0x00080 -#define SPI_SR_NSSR 0x00100 -#define SPI_SR_TXEMPTY 0x00200 -#define SPI_SR_SPIENS 0x10000 -#define SPI_IER 0x14 /* IER: Interrupt Enable Regsiter */ -#define SPI_IDR 0x18 /* IDR: Interrupt Disable Regsiter */ -#define SPI_IMR 0x1c /* IMR: Interrupt Mask Regsiter */ -#define SPI_CSR0 0x30 /* CS0: Chip Select 0 */ -#define SPI_CSR_CPOL 0x01 -#define SPI_CSR1 0x34 /* CS1: Chip Select 1 */ -#define SPI_CSR2 0x38 /* CS2: Chip Select 2 */ -#define SPI_CSR3 0x3c /* CS3: Chip Select 3 */ - -#endif /* ARM_AT91_AT91_SPIREG_H */ Index: head/sys/arm/at91/at91_ssc.c =================================================================== --- head/sys/arm/at91/at91_ssc.c +++ head/sys/arm/at91/at91_ssc.c @@ -1,272 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2006 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -struct at91_ssc_softc -{ - device_t dev; /* Myself */ - void *intrhand; /* Interrupt handle */ - struct resource *irq_res; /* IRQ resource */ - struct resource *mem_res; /* Memory resource */ - struct mtx sc_mtx; /* basically a perimeter lock */ - struct cdev *cdev; - int flags; -#define OPENED 1 -}; - -static inline uint32_t -RD4(struct at91_ssc_softc *sc, bus_size_t off) -{ - return bus_read_4(sc->mem_res, off); -} - -static inline void -WR4(struct at91_ssc_softc *sc, bus_size_t off, uint32_t val) -{ - bus_write_4(sc->mem_res, off, val); -} - -#define AT91_SSC_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) -#define AT91_SSC_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) -#define AT91_SSC_LOCK_INIT(_sc) \ - mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->dev), \ - "ssc", MTX_DEF) -#define AT91_SSC_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx); -#define AT91_SSC_ASSERT_LOCKED(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED); -#define AT91_SSC_ASSERT_UNLOCKED(_sc) mtx_assert(&(_sc)->sc_mtx, MA_NOTOWNED); -#define CDEV2SOFTC(dev) ((dev)->si_drv1) - -static devclass_t at91_ssc_devclass; - -/* bus entry points */ - -static int at91_ssc_probe(device_t dev); -static int at91_ssc_attach(device_t dev); -static int at91_ssc_detach(device_t dev); -static void at91_ssc_intr(void *); - -/* helper routines */ -static int at91_ssc_activate(device_t dev); -static void at91_ssc_deactivate(device_t dev); - -/* cdev routines */ -static d_open_t at91_ssc_open; -static d_close_t at91_ssc_close; -static d_read_t at91_ssc_read; -static d_write_t at91_ssc_write; - -static struct cdevsw at91_ssc_cdevsw = -{ - .d_version = D_VERSION, - .d_open = at91_ssc_open, - .d_close = at91_ssc_close, - .d_read = at91_ssc_read, - .d_write = at91_ssc_write, -}; - -static int -at91_ssc_probe(device_t dev) -{ - device_set_desc(dev, "SSC"); - return (0); -} - -static int -at91_ssc_attach(device_t dev) -{ - struct at91_ssc_softc *sc = device_get_softc(dev); - int err; - - sc->dev = dev; - err = at91_ssc_activate(dev); - if (err) - goto out; - - AT91_SSC_LOCK_INIT(sc); - - /* - * Activate the interrupt - */ - err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, - NULL, at91_ssc_intr, sc, &sc->intrhand); - if (err) { - AT91_SSC_LOCK_DESTROY(sc); - goto out; - } - sc->cdev = make_dev(&at91_ssc_cdevsw, device_get_unit(dev), UID_ROOT, - GID_WHEEL, 0600, "ssc%d", device_get_unit(dev)); - if (sc->cdev == NULL) { - err = ENOMEM; - goto out; - } - sc->cdev->si_drv1 = sc; - - // Init for TSC needs - WR4(sc, SSC_CR, SSC_CR_SWRST); - WR4(sc, SSC_CMR, 0); // clock divider unused - WR4(sc, SSC_RCMR, - SSC_RCMR_CKS_RK | SSC_RCMR_CKO_NONE | SSC_RCMR_START_FALL_EDGE_RF); - WR4(sc, SSC_RFMR, - 0x1f | SSC_RFMR_MSFBF | SSC_RFMR_FSOS_NONE); - WR4(sc, SSC_TCMR, - SSC_TCMR_CKS_TK | SSC_TCMR_CKO_NONE | SSC_RCMR_START_CONT); - WR4(sc, SSC_TFMR, - 0x1f | SSC_TFMR_DATDEF | SSC_TFMR_MSFBF | SSC_TFMR_FSOS_NEG_PULSE); - -out: - if (err) - at91_ssc_deactivate(dev); - return (err); -} - -static int -at91_ssc_detach(device_t dev) -{ - return (EBUSY); /* XXX */ -} - -static int -at91_ssc_activate(device_t dev) -{ - struct at91_ssc_softc *sc; - int rid; - - sc = device_get_softc(dev); - rid = 0; - sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - if (sc->mem_res == NULL) - goto errout; - rid = 0; - sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_ACTIVE); - if (sc->irq_res == NULL) - goto errout; - return (0); -errout: - at91_ssc_deactivate(dev); - return (ENOMEM); -} - -static void -at91_ssc_deactivate(device_t dev) -{ - struct at91_ssc_softc *sc; - - sc = device_get_softc(dev); - if (sc->intrhand) - bus_teardown_intr(dev, sc->irq_res, sc->intrhand); - sc->intrhand = NULL; - bus_generic_detach(sc->dev); - if (sc->mem_res) - bus_release_resource(dev, SYS_RES_IOPORT, - rman_get_rid(sc->mem_res), sc->mem_res); - sc->mem_res = NULL; - if (sc->irq_res) - bus_release_resource(dev, SYS_RES_IRQ, - rman_get_rid(sc->irq_res), sc->irq_res); - sc->irq_res = NULL; - return; -} - -static void -at91_ssc_intr(void *xsc) -{ - struct at91_ssc_softc *sc = xsc; - wakeup(sc); - return; -} - -static int -at91_ssc_open(struct cdev *dev, int oflags, int devtype, struct thread *td) -{ - struct at91_ssc_softc *sc; - - sc = CDEV2SOFTC(dev); - AT91_SSC_LOCK(sc); - if (!(sc->flags & OPENED)) { - sc->flags |= OPENED; - } - AT91_SSC_UNLOCK(sc); - return (0); -} - -static int -at91_ssc_close(struct cdev *dev, int fflag, int devtype, struct thread *td) -{ - struct at91_ssc_softc *sc; - - sc = CDEV2SOFTC(dev); - AT91_SSC_LOCK(sc); - sc->flags &= ~OPENED; - AT91_SSC_UNLOCK(sc); - return (0); -} - -static int -at91_ssc_read(struct cdev *dev, struct uio *uio, int flag) -{ - return EIO; -} - -static int -at91_ssc_write(struct cdev *dev, struct uio *uio, int flag) -{ - return EIO; -} - -static device_method_t at91_ssc_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, at91_ssc_probe), - DEVMETHOD(device_attach, at91_ssc_attach), - DEVMETHOD(device_detach, at91_ssc_detach), - - { 0, 0 } -}; - -static driver_t at91_ssc_driver = { - "at91_ssc", - at91_ssc_methods, - sizeof(struct at91_ssc_softc), -}; - -DRIVER_MODULE(at91_ssc, atmelarm, at91_ssc_driver, at91_ssc_devclass, 0, 0); Index: head/sys/arm/at91/at91_sscreg.h =================================================================== --- head/sys/arm/at91/at91_sscreg.h +++ head/sys/arm/at91/at91_sscreg.h @@ -1,152 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2006 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef ARM_AT91_AT91_SSCREG_H -#define ARM_AT91_AT91_SSCREG_H - -/* Registers */ -#define SSC_CR 0x00 /* Control Register */ -#define SSC_CMR 0x04 /* Clock Mode Register */ - /* 0x08 Reserved */ - /* 0x0c Reserved */ -#define SSC_RCMR 0x10 /* Receive Clock Mode Register */ -#define SSC_RFMR 0x14 /* Receive Frame Mode Register */ -#define SSC_TCMR 0x18 /* Transmit Clock Mode Register */ -#define SSC_TFMR 0x1c /* Transmit Frame Mode register */ -#define SSC_RHR 0x20 /* Receive Holding Register */ -#define SSC_THR 0x24 /* Transmit Holding Register */ - /* 0x28 Reserved */ - /* 0x2c Reserved */ -#define SSC_RSHR 0x30 /* Receive Sync Holding Register */ -#define SSC_TSHR 0x34 /* Transmit Sync Holding Register */ - /* 0x38 Reserved */ - /* 0x3c Reserved */ -#define SSC_SR 0x40 /* Status Register */ -#define SSC_IER 0x44 /* Interrupt Enable Register */ -#define SSC_IDR 0x48 /* Interrupt Disable Register */ -#define SSC_IMR 0x4c /* Interrupt Mask Register */ -/* And PDC registers */ - -/* SSC_CR */ -#define SSC_CR_RXEN (1u << 0) /* RXEN: Receive Enable */ -#define SSC_CR_RXDIS (1u << 1) /* RXDIS: Receive Disable */ -#define SSC_CR_TXEN (1u << 8) /* TXEN: Transmit Enable */ -#define SSC_CR_TXDIS (1u << 9) /* TXDIS: Transmit Disable */ -#define SSC_CR_SWRST (1u << 15) /* SWRST: Software Reset */ - -/* SSC_CMR */ -#define SSC_CMR_DIV 0xfffu /* DIV: Clock Divider mask */ - -/* SSC_RCMR */ -#define SSC_RCMR_PERIOD (0xffu << 24) /* PERIOD: Receive Period Divider sel*/ -#define SSC_RCMR_STTDLY (0xffu << 16) /* STTDLY: Receive Start Delay */ -#define SSC_RCMR_START (0xfu << 8) /* START: Receive Start Sel */ -#define SSC_RCMR_START_CONT (0u << 8) -#define SSC_RCMR_START_TX_START (1u << 8) -#define SSC_RCMR_START_LOW_RF (2u << 8) -#define SSC_RCMR_START_HIGH_RF (3u << 8) -#define SSC_RCMR_START_FALL_EDGE_RF (4u << 8) -#define SSC_RCMR_START_RISE_EDGE_RF (5u << 8) -#define SSC_RCMR_START_LEVEL_CHANGE_RF (6u << 8) -#define SSC_RCMR_START_ANY_EDGE_RF (7u << 8) -#define SSC_RCMR_CKI (1u << 5) /* CKI: Receive Clock Inversion */ -#define SSC_RCMR_CKO (7u << 2) /* CKO: Receive Clock Output Mode Sel*/ -#define SSC_RCMR_CKO_NONE (0u << 2) -#define SSC_RCMR_CKO_CONTINUOUS (1u << 2) -#define SSC_RCMR_CKS (3u) /* CKS: Receive Clock Selection */ -#define SSC_RCMR_CKS_DIVIDED (0) -#define SSC_RCMR_CKS_TK_CLOCK (1) -#define SSC_RCMR_CKS_RK (2) - -/* SSC_RFMR */ -#define SSC_RFMR_FSEDGE (1u << 24) /* FSEDGE: Frame Sync Edge Detection */ -#define SSC_RFMR_FSOS (7u << 20) /* FSOS: Receive frame Sync Out sel */ -#define SSC_RFMR_FSOS_NONE (0u << 20) -#define SSC_RFMR_FSOS_NEG_PULSE (1u << 20) -#define SSC_RFMR_FSOS_POS_PULSE (2u << 20) -#define SSC_RFMR_FSOS_LOW (3u << 20) -#define SSC_RFMR_FSOS_HIGH (4u << 20) -#define SSC_RFMR_FSOS_TOGGLE (5u << 20) -#define SSC_RFMR_FSLEN (0xfu << 16) /* FSLEN: Receive Frame Sync Length */ -#define SSC_RFMR_DATNB (0xfu << 8) /* DATNB: Data Number per Frame */ -#define SSC_RFMR_MSFBF (1u << 7) /* MSBF: Most Significant Bit First */ -#define SSC_RFMR_LOOP (1u << 5) /* LOOP: Loop Mode */ -#define SSC_RFMR_DATLEN (0x1fu << 0) /* DATLEN: Data Length */ - -/* SSC_TCMR */ -#define SSC_TCMR_PERIOD (0xffu << 24) /* PERIOD: Receive Period Divider sel*/ -#define SSC_TCMR_STTDLY (0xffu << 16) /* STTDLY: Receive Start Delay */ -#define SSC_TCMR_START (0xfu << 8) /* START: Receive Start Sel */ -#define SSC_TCMR_START_CONT (0u << 8) -#define SSC_TCMR_START_RX_START (1u << 8) -#define SSC_TCMR_START_LOW_RF (2u << 8) -#define SSC_TCMR_START_HIGH_RF (3u << 8) -#define SSC_TCMR_START_FALL_EDGE_RF (4u << 8) -#define SSC_TCMR_START_RISE_EDGE_RF (5u << 8) -#define SSC_TCMR_START_LEVEL_CHANGE_RF (6u << 8) -#define SSC_TCMR_START_ANY_EDGE_RF (7u << 8) -#define SSC_TCMR_CKI (1u << 5) /* CKI: Receive Clock Inversion */ -#define SSC_TCMR_CKO (7u << 2) /* CKO: Receive Clock Output Mode Sel*/ -#define SSC_TCMR_CKO_NONE (0u << 2) -#define SSC_TCMR_CKO_CONTINUOUS (1u << 2) -#define SSC_TCMR_CKS (3u) /* CKS: Receive Clock Selection */ -#define SSC_TCMR_CKS_DIVIDED (0) -#define SSC_TCMR_CKS_RK_CLOCK (1) -#define SSC_TCMR_CKS_TK (2) - -/* SSC_TFMR */ -#define SSC_TFMR_FSEDGE (1u << 24) /* FSEDGE: Frame Sync Edge Detection */ -#define SSC_TFMR_FSOS (7u << 20) /* FSOS: Receive frame Sync Out sel */ -#define SSC_TFMR_FSOS_NONE (0u << 20) -#define SSC_TFMR_FSOS_NEG_PULSE (1u << 20) -#define SSC_TFMR_FSOS_POS_PULSE (2u << 20) -#define SSC_TFMR_FSOS_LOW (3u << 20) -#define SSC_TFMR_FSOS_HIGH (4u << 20) -#define SSC_TFMR_FSOS_TOGGLE (5u << 20) -#define SSC_TFMR_FSLEN (0xfu << 16) /* FSLEN: Receive Frame Sync Length */ -#define SSC_TFMR_DATNB (0xfu << 8) /* DATNB: Data Number per Frame */ -#define SSC_TFMR_MSFBF (1u << 7) /* MSBF: Most Significant Bit First */ -#define SSC_TFMR_DATDEF (1u << 5) /* DATDEF: Data Default Value */ -#define SSC_TFMR_DATLEN (0x1fu << 0) /* DATLEN: Data Length */ - -/* SSC_SR */ -#define SSC_SR_TXRDY (1u << 0) -#define SSC_SR_TXEMPTY (1u << 1) -#define SSC_SR_ENDTX (1u << 2) -#define SSC_SR_TXBUFE (1u << 3) -#define SSC_SR_RXRDY (1u << 4) -#define SSC_SR_OVRUN (1u << 5) -#define SSC_SR_ENDRX (1u << 6) -#define SSC_SR_RXBUFF (1u << 7) -#define SSC_SR_TXSYN (1u << 10) -#define SSC_SR_RSSYN (1u << 11) -#define SSC_SR_TXEN (1u << 16) -#define SSC_SR_RXEN (1u << 17) - -#endif /* ARM_AT91_AT91_SSCREG_H */ Index: head/sys/arm/at91/at91_st.c =================================================================== --- head/sys/arm/at91/at91_st.c +++ head/sys/arm/at91/at91_st.c @@ -1,314 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2005 Olivier Houchard. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -static struct at91_st_softc { - struct resource * sc_irq_res; - struct resource * sc_mem_res; - void * sc_intrhand; - eventhandler_tag sc_wet; /* watchdog event handler tag */ -} *timer_softc; - -static inline uint32_t -RD4(bus_size_t off) -{ - - if (timer_softc == NULL) { - uint32_t *p = (uint32_t *)(AT91_BASE + AT91RM92_ST_BASE + off); - - return *p; - } - - return (bus_read_4(timer_softc->sc_mem_res, off)); -} - -static inline void -WR4(bus_size_t off, uint32_t val) -{ - - if (timer_softc == NULL) { - uint32_t *p = (uint32_t *)(AT91_BASE + AT91RM92_ST_BASE + off); - - *p = val; - } - else - bus_write_4(timer_softc->sc_mem_res, off, val); -} - -static void at91_st_watchdog(void *, u_int, int *); -static void at91_st_initclocks(device_t , struct at91_st_softc *); - -static inline int -st_crtr(void) -{ - int cur1, cur2; - do { - cur1 = RD4(ST_CRTR); - cur2 = RD4(ST_CRTR); - } while (cur1 != cur2); - return (cur1); -} - -static unsigned at91_st_get_timecount(struct timecounter *tc); - -static struct timecounter at91_st_timecounter = { - at91_st_get_timecount, /* get_timecount */ - NULL, /* no poll_pps */ - 0xfffffu, /* counter_mask */ - 32768, /* frequency */ - "AT91RM9200 timer", /* name */ - 1000 /* quality */ -}; - -static int -clock_intr(void *arg) -{ - struct trapframe *fp = arg; - - /* The interrupt is shared, so we have to make sure it's for us. */ - if (RD4(ST_SR) & ST_SR_PITS) { - hardclock(TRAPF_USERMODE(fp), TRAPF_PC(fp)); - return (FILTER_HANDLED); - } - return (FILTER_STRAY); -} - -void -at91_st_delay(int n) -{ - uint32_t start, end, cur; - - start = st_crtr(); - n = (n * 1000) / 32768; - if (n <= 0) - n = 1; - end = (start + n) & ST_CRTR_MASK; - cur = start; - if (start > end) { - while (cur >= start || cur < end) - cur = st_crtr(); - } else { - while (cur < end) - cur = st_crtr(); - } -} - -void -at91_st_cpu_reset(void) -{ - /* - * Reset the CPU by programmig the watchdog timer to reset the - * CPU after 128 'slow' clocks, or about ~4ms. Loop until - * the reset happens for safety. - */ - WR4(ST_WDMR, ST_WDMR_RSTEN | 2); - WR4(ST_CR, ST_CR_WDRST); - while (1) - continue; -} - -static int -at91_st_probe(device_t dev) -{ - - device_set_desc(dev, "ST"); - return (0); -} - -static void -at91_st_deactivate(device_t dev) -{ - struct at91_st_softc *sc = timer_softc; - - if (sc->sc_intrhand) - bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand); - sc->sc_intrhand = NULL; - - if (sc->sc_irq_res) - bus_release_resource(dev, SYS_RES_IRQ, - rman_get_rid(sc->sc_irq_res), sc->sc_irq_res); - sc->sc_irq_res = NULL; - - if (sc->sc_mem_res) - bus_release_resource(dev, SYS_RES_MEMORY, - rman_get_rid(sc->sc_mem_res), sc->sc_mem_res); - sc->sc_mem_res = NULL; -} - -static int -at91_st_activate(device_t dev) -{ - int rid; - int err; - struct at91_st_softc *sc = timer_softc; - - rid = 0; - sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - err = ENOMEM; - if (sc->sc_mem_res == NULL) - goto out; - /* Disable all interrupts */ - WR4(ST_IDR, 0xffffffff); - - /* The system timer shares the system irq (1) */ - rid = 0; - sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_ACTIVE | RF_SHAREABLE); - if (sc->sc_irq_res == NULL) { - printf("Unable to allocate irq for the system timer"); - goto out; - } - err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_CLK, clock_intr, - NULL, NULL, &sc->sc_intrhand); -out: - if (err != 0) - at91_st_deactivate(dev); - return (err); -} - -static int -at91_st_attach(device_t dev) -{ - int err; - - timer_softc = device_get_softc(dev); - err = at91_st_activate(dev); - if (err) - return err; - - timer_softc->sc_wet = EVENTHANDLER_REGISTER(watchdog_list, - at91_st_watchdog, dev, 0); - - device_printf(dev, - "watchdog registered, timeout intervall max. 64 sec\n"); - - at91_st_initclocks(dev, timer_softc); - return (0); -} - -static device_method_t at91_st_methods[] = { - DEVMETHOD(device_probe, at91_st_probe), - DEVMETHOD(device_attach, at91_st_attach), - {0, 0}, -}; - -static driver_t at91_st_driver = { - "at91_st", - at91_st_methods, - sizeof(struct at91_st_softc), -}; -static devclass_t at91_st_devclass; - -DRIVER_MODULE(at91_st, atmelarm, at91_st_driver, at91_st_devclass, 0, 0); - -static unsigned -at91_st_get_timecount(struct timecounter *tc) -{ - return (st_crtr()); -} - -/* - * t below is in a weird unit. The watchdog is set to 2^t - * nanoseconds. Since our watchdog timer can't really do that too - * well, we approximate it by assuming that the timeout interval for - * the lsb is 2^22 ns, which is 4.194ms. This is an overestimation of - * the actual time (3.906ms), but close enough for watchdogging. - * These approximations, though a violation of the spec, improve the - * performance of the application which typically specifies things as - * WD_TO_32SEC. In that last case, we'd wait 32s before the wdog - * reset. The spec says we should wait closer to 34s, but given how - * it is likely to be used, and the extremely coarse nature time - * interval, I think this is the best solution. - */ -static void -at91_st_watchdog(void *argp, u_int cmd, int *error) -{ - uint32_t wdog; - int t; - - t = cmd & WD_INTERVAL; - if (t >= 22 && t <= 37) { - wdog = (1 << (t - 22)) | ST_WDMR_RSTEN; - *error = 0; - } else { - wdog = 0; - } - WR4(ST_WDMR, wdog); - WR4(ST_CR, ST_CR_WDRST); -} - -static void -at91_st_initclocks(device_t dev, struct at91_st_softc *sc) -{ - int rel_value; - - /* - * Real time counter increments every clock cycle, need to set before - * initializing clocks so that DELAY works. - */ - WR4(ST_RTMR, 1); - /* disable watchdog timer */ - WR4(ST_WDMR, 0); - - rel_value = 32768 / hz; - if (rel_value < 1) - rel_value = 1; - if (32768 % hz) { - device_printf(dev, "Cannot get %d Hz clock; using %dHz\n", hz, - 32768 / rel_value); - hz = 32768 / rel_value; - tick = 1000000 / hz; - } - WR4(ST_PIMR, rel_value); - - /* Enable PITS interrupts. */ - WR4(ST_IER, ST_SR_PITS); - tc_init(&at91_st_timecounter); -} Index: head/sys/arm/at91/at91_streg.h =================================================================== --- head/sys/arm/at91/at91_streg.h +++ head/sys/arm/at91/at91_streg.h @@ -1,63 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2005 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef ARM_AT91_AT91STREG_H -#define ARM_AT91_AT91STREG_H - -#define ST_CR 0x00 /* Control register */ -#define ST_PIMR 0x04 /* Period interval mode register */ -#define ST_WDMR 0x08 /* Watchdog mode register */ -#define ST_RTMR 0x0c /* Real-time mode register */ -#define ST_SR 0x10 /* Status register */ -#define ST_IER 0x14 /* Interrupt enable register */ -#define ST_IDR 0x18 /* Interrupt disable register */ -#define ST_IMR 0x1c /* Interrupt mask register */ -#define ST_RTAR 0x20 /* Real-time alarm register */ -#define ST_CRTR 0x24 /* Current real-time register */ - -/* ST_CR */ -#define ST_CR_WDRST (1U << 0) /* WDRST: Watchdog Timer Restart */ - -/* ST_WDMR */ -#define ST_WDMR_EXTEN (1U << 17) /* EXTEN: External Signal Assert Enable */ -#define ST_WDMR_RSTEN (1U << 16) /* RSTEN: Reset Enable */ - -/* ST_SR, ST_IER, ST_IDR, ST_IMR */ -#define ST_SR_PITS (1U << 0) /* PITS: Period Interval Timer Status */ -#define ST_SR_WDOVF (1U << 1) /* WDOVF: Watchdog Overflow */ -#define ST_SR_RTTINC (1U << 2) /* RTTINC: Real-time Timer Increment */ -#define ST_SR_ALMS (1U << 3) /* ALMS: Alarm Status */ - -/* ST_CRTR */ -#define ST_CRTR_MASK 0xfffff /* 20-bit counter */ - -void at91_st_delay(int n); -void at91_st_cpu_reset(void); - -#endif /* ARM_AT91_AT91STREG_H */ Index: head/sys/arm/at91/at91_tcb.c =================================================================== --- head/sys/arm/at91/at91_tcb.c +++ head/sys/arm/at91/at91_tcb.c @@ -1,106 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2014 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "opt_platform.h" - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#ifdef FDT -#include -#include -#endif - -struct tcb_softc { - struct resource *mem_res; /* Memory resource */ - device_t sc_dev; -}; - -static int -at91_tcb_probe(device_t dev) -{ -#ifdef FDT - if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-tcb")) - return (ENXIO); -#endif - device_set_desc(dev, "TCB"); - return (0); -} - -static int -at91_tcb_attach(device_t dev) -{ - int rid, err = 0; - struct tcb_softc *sc; - - sc = device_get_softc(dev); - sc->sc_dev = dev; - - rid = 0; - sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - - if (sc->mem_res == NULL) - panic("couldn't allocate register resources"); - - return (err); -} - -static device_method_t at91_tcb_methods[] = { - DEVMETHOD(device_probe, at91_tcb_probe), - DEVMETHOD(device_attach, at91_tcb_attach), - DEVMETHOD_END -}; - -static driver_t at91_tcb_driver = { - "at91_tcb", - at91_tcb_methods, - sizeof(struct tcb_softc), -}; - -static devclass_t at91_tcb_devclass; - -#ifdef FDT -DRIVER_MODULE(at91_tcb, simplebus, at91_tcb_driver, at91_tcb_devclass, NULL, - NULL); -#else -DRIVER_MODULE(at91_tcb, atmelarm, at91_tcb_driver, at91_tcb_devclass, NULL, - NULL); -#endif Index: head/sys/arm/at91/at91_twi.c =================================================================== --- head/sys/arm/at91/at91_twi.c +++ head/sys/arm/at91/at91_twi.c @@ -1,430 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2006 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "opt_platform.h" - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include "iicbus_if.h" - -#ifdef FDT -#include -#include -#endif - -#define TWI_SLOW_CLOCK 1500 -#define TWI_FAST_CLOCK 45000 -#define TWI_FASTEST_CLOCK 90000 - -struct at91_twi_softc -{ - device_t dev; /* Myself */ - void *intrhand; /* Interrupt handle */ - struct resource *irq_res; /* IRQ resource */ - struct resource *mem_res; /* Memory resource */ - struct mtx sc_mtx; /* basically a perimeter lock */ - volatile uint32_t flags; - uint32_t cwgr; - int sc_started; - int twi_addr; - device_t iicbus; -}; - -static inline uint32_t -RD4(struct at91_twi_softc *sc, bus_size_t off) -{ - - return bus_read_4(sc->mem_res, off); -} - -static inline void -WR4(struct at91_twi_softc *sc, bus_size_t off, uint32_t val) -{ - - bus_write_4(sc->mem_res, off, val); -} - -#define AT91_TWI_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) -#define AT91_TWI_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) -#define AT91_TWI_LOCK_INIT(_sc) \ - mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \ - "twi", MTX_DEF) -#define AT91_TWI_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); -#define AT91_TWI_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED); -#define AT91_TWI_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); -#define TWI_DEF_CLK 100000 - -static devclass_t at91_twi_devclass; - -/* bus entry points */ - -static int at91_twi_probe(device_t dev); -static int at91_twi_attach(device_t dev); -static int at91_twi_detach(device_t dev); -static void at91_twi_intr(void *); - -/* helper routines */ -static int at91_twi_activate(device_t dev); -static void at91_twi_deactivate(device_t dev); - -static int -at91_twi_probe(device_t dev) -{ -#ifdef FDT - /* XXXX need a whole list, since there's at least 4 different ones */ - if (!ofw_bus_is_compatible(dev, "atmel,at91sam9g20-i2c")) - return (ENXIO); -#endif - device_set_desc(dev, "TWI"); - return (0); -} - -static int -at91_twi_attach(device_t dev) -{ - struct at91_twi_softc *sc = device_get_softc(dev); - int err; - - sc->dev = dev; - err = at91_twi_activate(dev); - if (err) - goto out; - - AT91_TWI_LOCK_INIT(sc); - -#ifdef FDT - /* - * Disable devices need to hold their resources, so return now and not attach - * the iicbus, setup interrupt handlers, etc. - */ - if (!ofw_bus_status_okay(dev)) - return 0; -#endif - - /* - * Activate the interrupt - */ - err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, - NULL, at91_twi_intr, sc, &sc->intrhand); - if (err) { - AT91_TWI_LOCK_DESTROY(sc); - goto out; - } - sc->cwgr = TWI_CWGR_CKDIV(8 * at91_master_clock / TWI_FASTEST_CLOCK) | - TWI_CWGR_CHDIV(TWI_CWGR_DIV(TWI_DEF_CLK)) | - TWI_CWGR_CLDIV(TWI_CWGR_DIV(TWI_DEF_CLK)); - WR4(sc, TWI_CR, TWI_CR_SWRST); - WR4(sc, TWI_CR, TWI_CR_MSEN | TWI_CR_SVDIS); - WR4(sc, TWI_CWGR, sc->cwgr); - - if ((sc->iicbus = device_add_child(dev, "iicbus", -1)) == NULL) - device_printf(dev, "could not allocate iicbus instance\n"); - /* Probe and attach the iicbus when interrupts are available. */ - config_intrhook_oneshot((ich_func_t)bus_generic_attach, dev); -out: - if (err) - at91_twi_deactivate(dev); - return (err); -} - -static int -at91_twi_detach(device_t dev) -{ - struct at91_twi_softc *sc; - int rv; - - sc = device_get_softc(dev); - at91_twi_deactivate(dev); - if (sc->iicbus && (rv = device_delete_child(dev, sc->iicbus)) != 0) - return (rv); - - AT91_TWI_LOCK_DESTROY(sc); - - return (0); -} - -static int -at91_twi_activate(device_t dev) -{ - struct at91_twi_softc *sc; - int rid; - - sc = device_get_softc(dev); - rid = 0; - sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - if (sc->mem_res == NULL) - goto errout; - rid = 0; - sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_ACTIVE); - if (sc->irq_res == NULL) - goto errout; - return (0); -errout: - at91_twi_deactivate(dev); - return (ENOMEM); -} - -static void -at91_twi_deactivate(device_t dev) -{ - struct at91_twi_softc *sc; - - sc = device_get_softc(dev); - if (sc->intrhand) - bus_teardown_intr(dev, sc->irq_res, sc->intrhand); - sc->intrhand = NULL; - bus_generic_detach(sc->dev); - if (sc->mem_res) - bus_release_resource(dev, SYS_RES_MEMORY, - rman_get_rid(sc->mem_res), sc->mem_res); - sc->mem_res = NULL; - if (sc->irq_res) - bus_release_resource(dev, SYS_RES_IRQ, - rman_get_rid(sc->irq_res), sc->irq_res); - sc->irq_res = NULL; - return; -} - -static void -at91_twi_intr(void *xsc) -{ - struct at91_twi_softc *sc = xsc; - uint32_t status; - - status = RD4(sc, TWI_SR); - if (status == 0) - return; - AT91_TWI_LOCK(sc); - sc->flags |= status & (TWI_SR_OVRE | TWI_SR_UNRE | TWI_SR_NACK); - if (status & TWI_SR_RXRDY) - sc->flags |= TWI_SR_RXRDY; - if (status & TWI_SR_TXRDY) - sc->flags |= TWI_SR_TXRDY; - if (status & TWI_SR_TXCOMP) - sc->flags |= TWI_SR_TXCOMP; - WR4(sc, TWI_IDR, status); - wakeup(sc); - AT91_TWI_UNLOCK(sc); - return; -} - -static int -at91_twi_wait(struct at91_twi_softc *sc, uint32_t bit) -{ - int err = 0; - int counter = 100000; - uint32_t sr; - - AT91_TWI_ASSERT_LOCKED(sc); - while (!((sr = RD4(sc, TWI_SR)) & bit) && counter-- > 0 && - !(sr & TWI_SR_NACK)) - continue; - if (counter <= 0) - err = EBUSY; - else if (sr & TWI_SR_NACK) - err = ENXIO; // iic nack convention - return (err); -} - -static int -at91_twi_rst_card(device_t dev, u_char speed, u_char addr, u_char *oldaddr) -{ - struct at91_twi_softc *sc; - int clk; - - sc = device_get_softc(dev); - AT91_TWI_LOCK(sc); - if (oldaddr) - *oldaddr = sc->twi_addr; - sc->twi_addr = addr; - - /* - * speeds are for 1.5kb/s, 45kb/s and 90kb/s. - */ - switch (speed) { - case IIC_SLOW: - clk = TWI_SLOW_CLOCK; - break; - - case IIC_FAST: - clk = TWI_FAST_CLOCK; - break; - - case IIC_UNKNOWN: - case IIC_FASTEST: - default: - clk = TWI_FASTEST_CLOCK; - break; - } - sc->cwgr = TWI_CWGR_CKDIV(1) | TWI_CWGR_CHDIV(TWI_CWGR_DIV(clk)) | - TWI_CWGR_CLDIV(TWI_CWGR_DIV(clk)); - WR4(sc, TWI_CR, TWI_CR_SWRST); - WR4(sc, TWI_CR, TWI_CR_MSEN | TWI_CR_SVDIS); - WR4(sc, TWI_CWGR, sc->cwgr); - AT91_TWI_UNLOCK(sc); - - return 0; -} - -static int -at91_twi_callback(device_t dev, int index, caddr_t data) -{ - int error = 0; - - switch (index) { - case IIC_REQUEST_BUS: - break; - - case IIC_RELEASE_BUS: - break; - - default: - error = EINVAL; - } - - return (error); -} - -static int -at91_twi_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) -{ - struct at91_twi_softc *sc; - int i, len, err; - uint32_t rdwr; - uint8_t *buf; - uint32_t sr; - - sc = device_get_softc(dev); - err = 0; - AT91_TWI_LOCK(sc); - for (i = 0; i < nmsgs; i++) { - /* - * The linux atmel driver doesn't use the internal device - * address feature of twi. A separate i2c message needs to - * be written to use this. - * See http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2004-September/024411.html - * for details. Upon reflection, we could use this as an - * optimization, but it is unclear the code bloat will - * result in faster/better operations. - */ - rdwr = (msgs[i].flags & IIC_M_RD) ? TWI_MMR_MREAD : 0; - WR4(sc, TWI_MMR, TWI_MMR_DADR(msgs[i].slave) | rdwr); - len = msgs[i].len; - buf = msgs[i].buf; - /* zero byte transfers aren't allowed */ - if (len == 0 || buf == NULL) { - err = EINVAL; - goto out; - } - if (len == 1 && msgs[i].flags & IIC_M_RD) - WR4(sc, TWI_CR, TWI_CR_START | TWI_CR_STOP); - else - WR4(sc, TWI_CR, TWI_CR_START); - if (msgs[i].flags & IIC_M_RD) { - sr = RD4(sc, TWI_SR); - while (!(sr & TWI_SR_TXCOMP)) { - if ((sr = RD4(sc, TWI_SR)) & TWI_SR_RXRDY) { - len--; - *buf++ = RD4(sc, TWI_RHR) & 0xff; - if (len == 1) - WR4(sc, TWI_CR, TWI_CR_STOP); - } - } - if (len > 0 || (sr & TWI_SR_NACK)) { - err = ENXIO; // iic nack convention - goto out; - } - } else { - while (len--) { - if ((err = at91_twi_wait(sc, TWI_SR_TXRDY))) - goto out; - WR4(sc, TWI_THR, *buf++); - } - WR4(sc, TWI_CR, TWI_CR_STOP); - } - if ((err = at91_twi_wait(sc, TWI_SR_TXCOMP))) - break; - } -out: - if (err) { - WR4(sc, TWI_CR, TWI_CR_SWRST); - WR4(sc, TWI_CR, TWI_CR_MSEN | TWI_CR_SVDIS); - WR4(sc, TWI_CWGR, sc->cwgr); - } - AT91_TWI_UNLOCK(sc); - return (err); -} - -static device_method_t at91_twi_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, at91_twi_probe), - DEVMETHOD(device_attach, at91_twi_attach), - DEVMETHOD(device_detach, at91_twi_detach), - - /* iicbus interface */ - DEVMETHOD(iicbus_callback, at91_twi_callback), - DEVMETHOD(iicbus_reset, at91_twi_rst_card), - DEVMETHOD(iicbus_transfer, at91_twi_transfer), - DEVMETHOD_END -}; - -static driver_t at91_twi_driver = { - "at91_twi", - at91_twi_methods, - sizeof(struct at91_twi_softc), -}; - -#ifdef FDT -DRIVER_MODULE(at91_twi, simplebus, at91_twi_driver, at91_twi_devclass, NULL, - NULL); -#else -DRIVER_MODULE(at91_twi, atmelarm, at91_twi_driver, at91_twi_devclass, NULL, - NULL); -#endif -DRIVER_MODULE(iicbus, at91_twi, iicbus_driver, iicbus_devclass, NULL, NULL); -MODULE_DEPEND(at91_twi, iicbus, 1, 1, 1); Index: head/sys/arm/at91/at91_twiio.h =================================================================== --- head/sys/arm/at91/at91_twiio.h +++ head/sys/arm/at91/at91_twiio.h @@ -1,64 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2006 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _ARM_AT91_AT91_TWIIO_H -#define _ARM_AT91_AT91_TWIIO_H - -#include - -struct at91_twi_io -{ - int dadr; /* Device address */ - int type; /* read/write */ -#define TWI_IO_READ_MASTER 1 -#define TWI_IO_WRITE_MASTER 2 - int iadrsz; /* Internal addr size */ - uint32_t iadr; /* Interbak addr */ - size_t xfer_len; /* Size to transfer */ - caddr_t xfer_buf; /* buffer for xfer */ -}; - -struct at91_twi_clock -{ - int ckdiv; /* Clock divider */ - int high_rate; /* rate of clock high period */ - int low_rate; /* rate of clock low period */ -}; - -/** TWIIOCXFER: Do a two-wire transfer - */ -#define TWIIOCXFER _IOW('x', 1, struct at91_twi_io) - -/** TWIIOCSETCLOCK: Sets the clocking parameters for this operation. - */ -#define TWIIOCSETCLOCK _IOW('x', 2, struct at91_twi_clock) - -#endif /* !_ARM_AT91_AT91_TWIIO_H */ - - Index: head/sys/arm/at91/at91_twireg.h =================================================================== --- head/sys/arm/at91/at91_twireg.h +++ head/sys/arm/at91/at91_twireg.h @@ -1,88 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2006 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef ARM_AT91_AT91_TWIREG_H -#define ARM_AT91_AT91_TWIREG_H - -#define TWI_CR 0x00 /* TWI Control Register */ -#define TWI_MMR 0x04 /* TWI Master Mode Register */ -#define TWI_SMR 0x08 /* TWI Master Mode Register */ -#define TWI_IADR 0x0c /* TWI Internal Address Register */ -#define TWI_CWGR 0x10 /* TWI Clock Waveform Generator Reg */ - /* 0x14 reserved */ - /* 0x18 reserved */ - /* 0x1c reserved */ -#define TWI_SR 0x20 /* TWI Status Register */ -#define TWI_IER 0x24 /* TWI Interrupt Enable Register */ -#define TWI_IDR 0x28 /* TWI Interrupt Disable Register */ -#define TWI_IMR 0x2c /* TWI Interrupt Mask Register */ -#define TWI_RHR 0x30 /* TWI Receiver Holding Register */ -#define TWI_THR 0x34 /* TWI Transmit Holding Register */ - -/* TWI_CR */ -#define TWI_CR_START (1U << 0) /* Send a start */ -#define TWI_CR_STOP (1U << 1) /* Send a stop */ -#define TWI_CR_MSEN (1U << 2) /* Master Transfer Enable */ -#define TWI_CR_MSDIS (1U << 3) /* Master Transfer Disable */ -#define TWI_CR_SVEN (1U << 4) /* Slave Transfer Enable */ -#define TWI_CR_SVDIS (1U << 5) /* Slave Transfer Disable */ -#define TWI_CR_SWRST (1U << 7) /* Software Reset */ - -/* TWI_MMR */ -/* TWI_SMR */ -#define TWI_MMR_IADRSZ(n) ((n) << 8) /* Set size of transfer */ -#define TWI_MMR_MWRITE 0U /* Master Read Direction */ -#define TWI_MMR_MREAD (1U << 12) /* Master Read Direction */ -#define TWI_MMR_DADR(n) ((n) << 15) /* Device Address */ - -/* TWI_CWGR */ -#define TWI_CWGR_CKDIV(x) ((x) << 16) /* Clock Divider */ -#define TWI_CWGR_CHDIV(x) ((x) << 8) /* Clock High Divider */ -#define TWI_CWGR_CLDIV(x) ((x) << 0) /* Clock Low Divider */ -#define TWI_CWGR_DIV(rate) \ - (at91_is_sam9() || at91_is_sam9xe() ? \ - ((at91_master_clock / (4 * (rate))) - 3) : \ - ((at91_master_clock / (4 * (rate))) - 2)) - -/* TWI_SR */ -/* TWI_IER */ -/* TWI_IDR */ -/* TWI_IMR */ -#define TWI_SR_TXCOMP (1U << 0) /* Transmission Completed */ -#define TWI_SR_RXRDY (1U << 1) /* Receive Holding Register Ready */ -#define TWI_SR_TXRDY (1U << 2) /* Transmit Holding Register Ready */ -#define TWI_SR_SVREAD (1U << 3) /* Slave Read */ -#define TWI_SR_SVACC (1U << 4) /* Slave Access */ -#define TWI_SR_GCACC (1U << 5) /* General Call Access */ -#define TWI_SR_OVRE (1U << 6) /* Overrun error */ -#define TWI_SR_UNRE (1U << 7) /* Underrun Error */ -#define TWI_SR_NACK (1U << 8) /* Not Acknowledged */ -#define TWI_SR_ARBLST (1U << 9) /* Arbitration Lost */ - -#endif /* ARM_AT91_AT91_TWIREG_H */ Index: head/sys/arm/at91/at91_usartreg.h =================================================================== --- head/sys/arm/at91/at91_usartreg.h +++ head/sys/arm/at91/at91_usartreg.h @@ -1,131 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2005 Olivier Houchard. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef AT91USARTREG_H_ -#define AT91USARTREG_H_ - -#define USART_CR 0x00 /* Control register */ -#define USART_CR_RSTRX (1UL << 2) /* Reset Receiver */ -#define USART_CR_RSTTX (1UL << 3) /* Reset Transmitter */ -#define USART_CR_RXEN (1UL << 4) /* Receiver Enable */ -#define USART_CR_RXDIS (1UL << 5) /* Receiver Disable */ -#define USART_CR_TXEN (1UL << 6) /* Transmitter Enable */ -#define USART_CR_TXDIS (1UL << 7) /* Transmitter Disable */ -#define USART_CR_RSTSTA (1UL << 8) /* Reset Status Bits */ -#define USART_CR_STTBRK (1UL << 9) /* Start Break */ -#define USART_CR_STPBRK (1UL << 10) /* Stop Break */ -#define USART_CR_STTTO (1UL << 11) /* Start Time-out */ -#define USART_CR_SENDA (1UL << 12) /* Send Address */ -#define USART_CR_RSTIT (1UL << 13) /* Reset Iterations */ -#define USART_CR_RSTNACK (1UL << 14) /* Reset Non Acknowledge */ -#define USART_CR_RETTO (1UL << 15) /* Rearm Time-out */ -#define USART_CR_DTREN (1UL << 16) /* Data Terminal ready Enable */ -#define USART_CR_DTRDIS (1UL << 17) /* Data Terminal ready Disable */ -#define USART_CR_RTSEN (1UL << 18) /* Request to Send enable */ -#define USART_CR_RTSDIS (1UL << 19) /* Request to Send Disable */ - -#define USART_MR 0x04 /* Mode register */ -#define USART_MR_MODE_NORMAL 0 /* Normal/Async/3-wire rs-232 */ -#define USART_MR_MODE_RS485 1 /* RS485 */ -#define USART_MR_MODE_HWFLOW 2 /* Hardware flow control/handshake */ -#define USART_MR_MODE_MODEM 3 /* Full modem protocol */ -#define USART_MR_MODE_ISO7816T0 4 /* ISO7816 T=0 */ -#define USART_MR_MODE_ISO7816T1 6 /* ISO7816 T=1 */ -#define USART_MR_MODE_IRDA 8 /* IrDA mode */ -#define USART_MR_USCLKS_MCK (0U << 4) /* use MCK for baudclock */ -#define USART_MR_USCLKS_MCKDIV (1U << 4) /* use MCK/DIV for baudclock */ -#define USART_MR_USCLKS_SCK (3U << 4) /* use SCK (ext) for baudclock */ -#define USART_MR_CHRL_5BITS (0U << 6) -#define USART_MR_CHRL_6BITS (1U << 6) -#define USART_MR_CHRL_7BITS (2U << 6) -#define USART_MR_CHRL_8BITS (3U << 6) -#define USART_MR_SYNC (1U << 8) /* 1 -> sync 0 -> async */ -#define USART_MR_PAR_EVEN (0U << 9) -#define USART_MR_PAR_ODD (1U << 9) -#define USART_MR_PAR_SPACE (2U << 9) -#define USART_MR_PAR_MARK (3U << 9) -#define USART_MR_PAR_NONE (4U << 9) -#define USART_MR_PAR_MULTIDROP (6U << 9) -#define USART_MR_NBSTOP_1 (0U << 12) -#define USART_MR_NBSTOP_1_5 (1U << 12) -#define USART_MR_NBSTOP_2 (2U << 12) -#define USART_MR_CHMODE_NORMAL (0U << 14) -#define USART_MR_CHMODE_ECHO (1U << 14) -#define USART_MR_CHMODE_LOOP (2U << 14) -#define USART_MR_CHMODE_REMLOOP (3U << 14) -#define USART_MR_MSBF (1U << 16) -#define USART_MR_MODE9 (1U << 17) -#define USART_MR_CKLO_SCK (1U << 18) -#define USART_MR_OVER16 0 -#define USART_MR_OVER8 (1U << 19) -#define USART_MR_INACK (1U << 20) /* Inhibit NACK generation */ -#define USART_MR_DSNACK (1U << 21) /* Disable Successive NACK */ -#define USART_MR_MAXITERATION(x) ((x) << 24) -#define USART_MR_FILTER (1U << 28) /* Filters for Ir lines */ - -#define USART_IER 0x08 /* Interrupt enable register */ -#define USART_IDR 0x0c /* Interrupt disable register */ -#define USART_IMR 0x10 /* Interrupt mask register */ -#define USART_CSR 0x14 /* Channel status register */ - -#define USART_CSR_RXRDY (1UL << 0) /* Receiver ready */ -#define USART_CSR_TXRDY (1UL << 1) /* Transmitter ready */ -#define USART_CSR_RXBRK (1UL << 2) /* Break received */ -#define USART_CSR_ENDRX (1UL << 3) /* End of Transfer RX from PDC */ -#define USART_CSR_ENDTX (1UL << 4) /* End of Transfer TX from PDC */ -#define USART_CSR_OVRE (1UL << 5) /* Overrun error */ -#define USART_CSR_FRAME (1UL << 6) /* Framing error */ -#define USART_CSR_PARE (1UL << 7) /* Parity Error */ -#define USART_CSR_TIMEOUT (1UL << 8) /* Timeout since start-timeout */ -#define USART_CSR_TXEMPTY (1UL << 9) /* Transmitter empty */ -#define USART_CSR_ITERATION (1UL << 10) /* max repetitions since RSIT */ -#define USART_CSR_TXBUFE (1UL << 11) /* Buffer empty from PDC */ -#define USART_CSR_RXBUFF (1UL << 12) /* Buffer full from PDC */ -#define USART_CSR_NACK (1UL << 13) /* NACK since last RSTNACK */ -#define USART_CSR_RIIC (1UL << 16) /* RI delta since last csr read */ -#define USART_CSR_DSRIC (1UL << 17) /* DSR delta */ -#define USART_CSR_DCDIC (1UL << 18) /* DCD delta */ -#define USART_CSR_CTSIC (1UL << 19) /* CTS delta */ -#define USART_CSR_RI (1UL << 20) /* RI status */ -#define USART_CSR_DSR (1UL << 21) /* DSR status */ -#define USART_CSR_DCD (1UL << 22) /* DCD status */ -#define USART_CSR_CTS (1UL << 23) /* CTS status */ - -#define USART_RHR 0x18 /* Receiver holding register */ -#define USART_THR 0x1c /* Transmitter holding register */ -#define USART_BRGR 0x20 /* Baud rate generator register */ -#define USART_RTOR 0x24 /* Receiver time-out register */ -#define USART_TTR 0x28 /* Transmitter timeguard register */ -/* 0x2c to 0x3c reserved */ -#define USART_FDRR 0x40 /* FI DI ratio register */ -#define USART_NER 0x44 /* Number of errors register */ -/* 0x48 reserved */ -#define USART_IFR 0x48 /* IrDA filter register */ - -#endif /* AT91RM92REG_H_ */ Index: head/sys/arm/at91/at91_wdt.c =================================================================== --- head/sys/arm/at91/at91_wdt.c +++ head/sys/arm/at91/at91_wdt.c @@ -1,239 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010 Greg Ansley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * The SAM9 watchdog hardware can be programed only once. So we set the - * hardware watchdog to 16 s in wdt_attach and only reset it in the wdt_tick - * handler. The watchdog is halted in processor debug mode. - */ - -#include "opt_platform.h" - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#ifdef FDT -#include -#include -#endif - -struct wdt_softc { - struct mtx sc_mtx; - device_t sc_dev; - struct resource *mem_res; - struct callout tick_ch; - eventhandler_tag sc_wet; - void *intrhand; - u_int cmd; - u_int interval; -}; - -static inline uint32_t -RD4(struct wdt_softc *sc, bus_size_t off) -{ - - return (bus_read_4(sc->mem_res, off)); -} - -static inline void -WR4(struct wdt_softc *sc, bus_size_t off, uint32_t val) -{ - - bus_write_4(sc->mem_res, off, val); -} - -static int -wdt_intr(void *argp) -{ - struct wdt_softc *sc = argp; - - - if (RD4(sc, WDT_SR) & (WDT_WDUNF | WDT_WDERR)) { -#if defined(KDB) && !defined(KDB_UNATTENDED) - kdb_backtrace(); - kdb_enter(KDB_WHY_WATCHDOG, "watchdog timeout"); -#else - panic("watchdog timeout"); -#endif - } - return (FILTER_STRAY); -} - -/* User interface, see watchdog(9) */ -static void -wdt_watchdog(void *argp, u_int cmd, int *error) -{ - struct wdt_softc *sc = argp; - u_int interval; - - mtx_lock(&sc->sc_mtx); - - *error = 0; - sc->cmd = 0; - interval = cmd & WD_INTERVAL; - if (interval > WD_TO_16SEC) - *error = EOPNOTSUPP; - else if (interval > 0) - sc->cmd = interval | WD_ACTIVE; - - /* We cannot turn off our watchdog so if user - * fails to turn us on go to passive mode. */ - if ((sc->cmd & WD_ACTIVE) == 0) - sc->cmd = WD_PASSIVE; - - mtx_unlock(&sc->sc_mtx); -} - -/* This routine is called no matter what state the user sets the - * watchdog mode to. Called at a rate that is slightly less than - * half the hardware timeout. */ -static void -wdt_tick(void *argp) -{ - struct wdt_softc *sc = argp; - - mtx_assert(&sc->sc_mtx, MA_OWNED); - if (sc->cmd & (WD_ACTIVE | WD_PASSIVE)) - WR4(sc, WDT_CR, WDT_KEY|WDT_WDRSTT); - - sc->cmd &= WD_PASSIVE; - callout_reset(&sc->tick_ch, sc->interval, wdt_tick, sc); -} - -static int -wdt_probe(device_t dev) -{ -#ifdef FDT - if (!ofw_bus_is_compatible(dev, "atmel,at91sam9260-wdt")) - return (ENXIO); -#endif - device_set_desc(dev, "WDT"); - return (0); -} - -static int -wdt_attach(device_t dev) -{ - static struct wdt_softc *sc; - struct resource *irq; - uint32_t wdt_mr; - int rid, err; - - sc = device_get_softc(dev); - sc->cmd = WD_PASSIVE; - sc->sc_dev = dev; - - mtx_init(&sc->sc_mtx, device_get_nameunit(dev), "at91_wdt", MTX_DEF); - callout_init_mtx(&sc->tick_ch, &sc->sc_mtx, 0); - - rid = 0; - sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - - if (sc->mem_res == NULL) - panic("couldn't allocate wdt register resources"); - - wdt_mr = RD4(sc, WDT_MR); - if ((wdt_mr & WDT_WDRSTEN) == 0) - device_printf(dev, "Watchdog disabled! (Boot ROM?)\n"); - else { -#ifdef WDT_RESET - /* Rude, full reset of whole system on watch dog timeout */ - WR4(sc, WDT_MR, WDT_WDDBGHLT | WDT_WDD(0xC00)| - WDT_WDRSTEN| WDT_WDV(0xFFF)); -#else - /* Generate stack trace and panic on watchdog timeout*/ - WR4(sc, WDT_MR, WDT_WDDBGHLT | WDT_WDD(0xC00)| - WDT_WDFIEN| WDT_WDV(0xFFF)); -#endif - /* - * This may have been set by Boot ROM so register value may - * not be what we just requested since this is a write once - * register. - */ - wdt_mr = RD4(sc, WDT_MR); - if (wdt_mr & WDT_WDFIEN) { - rid = 0; - irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_ACTIVE | RF_SHAREABLE); - if (!irq) - panic("could not allocate interrupt.\n"); - - err = bus_setup_intr(dev, irq, INTR_TYPE_CLK, wdt_intr, - NULL, sc, &sc->intrhand); - } - - /* interval * hz */ - sc->interval = (((wdt_mr & WDT_WDV(~0)) + 1) * WDT_DIV) / - (WDT_CLOCK/hz); - - device_printf(dev, "watchdog timeout: %d seconds\n", - sc->interval / hz); - - /* Slightly less than 1/2 of watchdog hardware timeout */ - sc->interval = (sc->interval/2) - (sc->interval/20); - callout_reset(&sc->tick_ch, sc->interval, wdt_tick, sc); - - /* Register us as a watchdog */ - sc->sc_wet = EVENTHANDLER_REGISTER(watchdog_list, - wdt_watchdog, sc, 0); - } - return (0); -} - -static device_method_t wdt_methods[] = { - DEVMETHOD(device_probe, wdt_probe), - DEVMETHOD(device_attach, wdt_attach), - DEVMETHOD_END -}; - -static driver_t wdt_driver = { - "at91_wdt", - wdt_methods, - sizeof(struct wdt_softc), -}; - -static devclass_t wdt_devclass; - -#ifdef FDT -DRIVER_MODULE(at91_wdt, simplebus, wdt_driver, wdt_devclass, NULL, NULL); -#else -DRIVER_MODULE(at91_wdt, atmelarm, wdt_driver, wdt_devclass, NULL, NULL); -#endif Index: head/sys/arm/at91/at91_wdtreg.h =================================================================== --- head/sys/arm/at91/at91_wdtreg.h +++ head/sys/arm/at91/at91_wdtreg.h @@ -1,62 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2005 Gallon Sylvestre. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * $FreeBSD$ - */ - -#ifndef ARM_AT91_AT91WDTREG_H -#define ARM_AT91_AT91WDTREG_H - -#ifndef WDT_CLOCK -#define WDT_CLOCK (32768) -#endif -#define WDT_DIV (128) /* Clock is slow clock / 128 */ - -#define WDT_CR 0x0 /* Control Register */ -#define WDT_MR 0x4 /* Mode Register */ -#define WDT_SR 0x8 /* Status Register */ - -/* WDT_CR */ -#define WDT_KEY (0xa5<<24) -#define WDT_WDRSTT 0x1 - -/* WDT_MR */ -#define WDT_WDV(x) (x & 0xfff) /* counter value*/ -#define WDT_WDFIEN (1<<12) /* enable interrupt */ -#define WDT_WDRSTEN (1<<13) /* enable reset */ -#define WDT_WDRPROC (1<<14) /* processor reset */ -#define WDT_WDDIS (1<<15) /* disable */ -#define WDT_WDD(x) ((x & 0xfff) << 16) /* delta value */ -#define WDT_WDDBGHLT (1<<28) /* halt in debug */ -#define WDT_WDIDLEHLT (1<<29) /* halt in idle */ - -/* WDT_SR */ -#define WDT_WDUNF 0x1 -#define WDT_WDERR 0x2 - -#endif /* ARM_AT91_AT91WDTREG_H */ Index: head/sys/arm/at91/at91board.h =================================================================== --- head/sys/arm/at91/at91board.h +++ head/sys/arm/at91/at91board.h @@ -1,38 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2008 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef _ARM_AT91_AT91BOARD_H_ -#define _ARM_AT91_AT91BOARD_H_ - -/* - * These routines are used by board init routines - */ -long at91_ramsize(void); - -#endif /* _ARM_AT91_AT91BOARD_H_ */ Index: head/sys/arm/at91/at91reg.h =================================================================== --- head/sys/arm/at91/at91reg.h +++ head/sys/arm/at91/at91reg.h @@ -1,92 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2009 Greg Ansley All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * $FreeBSD$ - */ - -#ifndef _AT91REG_H_ -#define _AT91REG_H_ - -#include "opt_at91.h" - -/* Where builtin peripherals start in KVM */ -#define AT91_BASE 0xd0000000 - -/* Where builtin peripherals start PA */ -#define AT91_PA_BASE 0xf0000000 - -/* A few things that we count on being the same - * throughout the whole family of SOCs */ - -/* SYSC System Controller */ -/* System Registers */ -#define AT91_SYS_BASE 0xffff000 -#define AT91_SYS_SIZE 0x1000 - -#define AT91_DBGU0 0x0ffff200 /* Most */ -#define AT91_DBGU1 0x0fffee00 /* SAM9263, CAP9, and SAM9G45 */ - -#define AT91_DBGU_SIZE 0x200 -#define DBGU_C1R (64) /* Chip ID1 Register */ -#define DBGU_C2R (68) /* Chip ID2 Register */ -#define DBGU_FNTR (72) /* Force NTRST Register */ - -#define AT91_CPU_VERSION_MASK 0x0000001f -#define AT91_CPU_FAMILY_MASK 0x0ff00000 - -#define AT91_CPU_RM9200 0x09290780 -#define AT91_CPU_SAM9260 0x019803a0 -#define AT91_CPU_SAM9261 0x019703a0 -#define AT91_CPU_SAM9263 0x019607a0 -#define AT91_CPU_SAM9G10 0x819903a0 -#define AT91_CPU_SAM9G20 0x019905a0 -#define AT91_CPU_SAM9G45 0x819b05a0 -#define AT91_CPU_SAM9N12 0x819a07a0 -#define AT91_CPU_SAM9RL64 0x019b03a0 -#define AT91_CPU_SAM9X5 0x819a05a0 - -#define AT91_CPU_SAM9XE128 0x329973a0 -#define AT91_CPU_SAM9XE256 0x329a93a0 -#define AT91_CPU_SAM9XE512 0x329aa3a0 - -#define AT91_CPU_CAP9 0x039a03a0 - -#define AT91_EXID_SAM9M11 0x00000001 -#define AT91_EXID_SAM9M10 0x00000002 -#define AT91_EXID_SAM9G46 0x00000003 -#define AT91_EXID_SAM9G45 0x00000004 - -#define AT91_EXID_SAM9G15 0x00000000 -#define AT91_EXID_SAM9G35 0x00000001 -#define AT91_EXID_SAM9X35 0x00000002 -#define AT91_EXID_SAM9G25 0x00000003 -#define AT91_EXID_SAM9X25 0x00000004 - -#define AT91_IRQ_SYSTEM 1 - -#endif /* _AT91REG_H_ */ Index: head/sys/arm/at91/at91rm9200.c =================================================================== --- head/sys/arm/at91/at91rm9200.c +++ head/sys/arm/at91/at91rm9200.c @@ -1,211 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2005 Olivier Houchard. All rights reserved. - * Copyright (c) 2010 Greg Ansley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include - -#define _ARM32_BUS_DMA_PRIVATE -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Standard priority levels for the system. 0 is lowest and 7 is highest. - * These values are the ones Atmel uses for its Linux port, which differ - * a little form the ones that are in the standard distribution. Also, - * the ones marked with 'TWEEK' are different based on experience. - */ -static const int at91_irq_prio[32] = -{ - 7, /* Advanced Interrupt Controller (FIQ) */ - 7, /* System Peripherals */ - 1, /* Parallel IO Controller A */ - 1, /* Parallel IO Controller B */ - 1, /* Parallel IO Controller C */ - 1, /* Parallel IO Controller D */ - 5, /* USART 0 */ - 5, /* USART 1 */ - 5, /* USART 2 */ - 5, /* USART 3 */ - 0, /* Multimedia Card Interface */ - 2, /* USB Device Port */ - 4, /* Two-Wire Interface */ /* TWEEK */ - 5, /* Serial Peripheral Interface */ - 4, /* Serial Synchronous Controller 0 */ - 6, /* Serial Synchronous Controller 1 */ /* TWEEK */ - 4, /* Serial Synchronous Controller 2 */ - 0, /* Timer Counter 0 */ - 6, /* Timer Counter 1 */ /* TWEEK */ - 0, /* Timer Counter 2 */ - 0, /* Timer Counter 3 */ - 0, /* Timer Counter 4 */ - 0, /* Timer Counter 5 */ - 2, /* USB Host port */ - 3, /* Ethernet MAC */ - 0, /* Advanced Interrupt Controller (IRQ0) */ - 0, /* Advanced Interrupt Controller (IRQ1) */ - 0, /* Advanced Interrupt Controller (IRQ2) */ - 0, /* Advanced Interrupt Controller (IRQ3) */ - 0, /* Advanced Interrupt Controller (IRQ4) */ - 0, /* Advanced Interrupt Controller (IRQ5) */ - 0 /* Advanced Interrupt Controller (IRQ6) */ -}; - -static const uint32_t at91_pio_base[] = { - AT91RM92_PIOA_BASE, - AT91RM92_PIOB_BASE, - AT91RM92_PIOC_BASE, - AT91RM92_PIOD_BASE, -}; - -#define DEVICE(_name, _id, _unit) \ - { \ - _name, _unit, \ - AT91RM92_ ## _id ##_BASE, \ - AT91RM92_ ## _id ## _SIZE, \ - AT91RM92_IRQ_ ## _id \ - } - -static const struct cpu_devs at91_devs[] = -{ - DEVICE("at91_aic", AIC, 0), - DEVICE("at91_pmc", PMC, 0), - DEVICE("at91_st", ST, 0), - DEVICE("at91_pio", PIOA, 0), - DEVICE("at91_pio", PIOB, 1), - DEVICE("at91_pio", PIOC, 2), - DEVICE("at91_pio", PIOD, 3), - DEVICE("at91_rtc", RTC, 0), - - DEVICE("at91_mci", MCI, 0), - DEVICE("at91_twi", TWI, 0), - DEVICE("at91_udp", UDP, 0), - DEVICE("ate", EMAC, 0), - DEVICE("at91_ssc", SSC0, 0), - DEVICE("at91_ssc", SSC1, 1), - DEVICE("at91_ssc", SSC2, 2), - DEVICE("spi", SPI, 0), - - DEVICE("uart", DBGU, 0), - DEVICE("uart", USART0, 1), - DEVICE("uart", USART1, 2), - DEVICE("uart", USART2, 3), - DEVICE("uart", USART3, 4), - DEVICE("at91_mc", MC, 0), - DEVICE("at91_tc", TC0, 0), - DEVICE("at91_tc", TC1, 1), - DEVICE("ohci", OHCI, 0), - DEVICE("at91_cfata", CF, 0), - { 0, 0, 0, 0, 0 } -}; - -static uint32_t -at91_pll_outb(int freq) -{ - - if (freq > 155000000) - return (0x0000); - else - return (0x8000); -} - -#if 0 -/* -- XXX are these needed? */ - /* Disable all interrupts for RTC (0xe24 == RTC_IDR) */ - bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xe24, 0xffffffff); - - /* Disable all interrupts for the SDRAM controller */ - bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xfa8, 0xffffffff); -#endif - -static void -at91_clock_init(void) -{ - struct at91_pmc_clock *clk; - - /* Update USB device port clock info */ - clk = at91_pmc_clock_ref("udpck"); - clk->pmc_mask = PMC_SCER_UDP; - at91_pmc_clock_deref(clk); - - /* Update USB host port clock info */ - clk = at91_pmc_clock_ref("uhpck"); - clk->pmc_mask = PMC_SCER_UHP; - at91_pmc_clock_deref(clk); - - /* Each SOC has different PLL contraints */ - clk = at91_pmc_clock_ref("plla"); - clk->pll_min_in = RM9200_PLL_A_MIN_IN_FREQ; /* 1 MHz */ - clk->pll_max_in = RM9200_PLL_A_MAX_IN_FREQ; /* 32 MHz */ - clk->pll_min_out = RM9200_PLL_A_MIN_OUT_FREQ; /* 80 MHz */ - clk->pll_max_out = RM9200_PLL_A_MAX_OUT_FREQ; /* 180 MHz */ - clk->pll_mul_shift = RM9200_PLL_A_MUL_SHIFT; - clk->pll_mul_mask = RM9200_PLL_A_MUL_MASK; - clk->pll_div_shift = RM9200_PLL_A_DIV_SHIFT; - clk->pll_div_mask = RM9200_PLL_A_DIV_MASK; - clk->set_outb = at91_pll_outb; - at91_pmc_clock_deref(clk); - - clk = at91_pmc_clock_ref("pllb"); - clk->pll_min_in = RM9200_PLL_B_MIN_IN_FREQ; /* 100 KHz */ - clk->pll_max_in = RM9200_PLL_B_MAX_IN_FREQ; /* 32 MHz */ - clk->pll_min_out = RM9200_PLL_B_MIN_OUT_FREQ; /* 30 MHz */ - clk->pll_max_out = RM9200_PLL_B_MAX_OUT_FREQ; /* 240 MHz */ - clk->pll_mul_shift = RM9200_PLL_B_MUL_SHIFT; - clk->pll_mul_mask = RM9200_PLL_B_MUL_MASK; - clk->pll_div_shift = RM9200_PLL_B_DIV_SHIFT; - clk->pll_div_mask = RM9200_PLL_B_DIV_MASK; - clk->set_outb = at91_pll_outb; - at91_pmc_clock_deref(clk); -} - -static struct at91_soc_data soc_data = { - .soc_delay = at91_st_delay, - .soc_reset = at91_st_cpu_reset, - .soc_clock_init = at91_clock_init, - .soc_irq_prio = at91_irq_prio, - .soc_children = at91_devs, - .soc_pio_base = at91_pio_base, - .soc_pio_count = nitems(at91_pio_base), -}; - -AT91_SOC(AT91_T_RM9200, &soc_data); Index: head/sys/arm/at91/at91rm9200_devices.c =================================================================== --- head/sys/arm/at91/at91rm9200_devices.c +++ head/sys/arm/at91/at91rm9200_devices.c @@ -1,144 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2012 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include - -#define _ARM32_BUS_DMA_PRIVATE -#include - -#include -#include -#include -#include -#include -#include - -/* - * The AT91RM9200 uses the same silicon for both the BGA and PQFP - * packages. There's no documented way to detect this at runtime, - * so we require the board code to register what type of SoC is on the - * board in question. The pinouts are not quite compatible, and we - * use this information to cope with the slight differences. - */ -void -at91rm9200_set_subtype(enum at91_soc_subtype st) -{ - - switch (st) { - case AT91_ST_RM9200_BGA: - case AT91_ST_RM9200_PQFP: - soc_info.subtype = st; - break; - default: - panic("Bad SoC subtype %d for at91rm9200_set_subtype.", st); - break; - } -} - -void -at91rm9200_config_uart(unsigned devid, unsigned unit, unsigned pinmask) -{ - - /* - * Since the USART supports RS-485 multidrop mode, it allows the - * TX pins to float. However, for RS-232 operations, we don't want - * these pins to float. Instead, they should be pulled up to avoid - * mismatches. Linux does something similar when it configures the - * TX lines. This implies that we also allow the RX lines to float - * rather than be in the state they are left in by the boot loader. - * Since they are input pins, I think that this is the right thing - * to do. - */ - - /* - * Current boards supported don't need the extras, but they should be - * implemented. But that should wait until the new pin api goes in. - */ - switch (devid) { - case AT91_ID_DBGU: - at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA30, 0); /* DRXD */ - at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA31, 1); /* DTXD */ - break; - - case AT91RM9200_ID_USART0: - at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA17, 1); /* TXD0 */ - at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA18, 0); /* RXD0 */ - /* CTS PA20 */ - /* RTS -- errata #39 PA21 */ - break; - - case AT91RM9200_ID_USART1: - at91_pio_use_periph_a(AT91RM92_PIOB_BASE, AT91C_PIO_PB20, 1); /* TXD1 */ - at91_pio_use_periph_a(AT91RM92_PIOB_BASE, AT91C_PIO_PB21, 0); /* RXD1 */ - /* RI - PB18 */ - /* DTR - PB19 */ - /* DCD - PB23 */ - /* CTS - PB24 */ - /* DSR - PB25 */ - /* RTS - PB26 */ - break; - - case AT91RM9200_ID_USART2: - at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA22, 0); /* RXD2 */ - at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA23, 1); /* TXD2 */ - /* CTS - PA30 B periph */ - /* RTS - PA31 B periph */ - break; - - case AT91RM9200_ID_USART3: - at91_pio_use_periph_b(AT91RM92_PIOA_BASE, AT91C_PIO_PA5, 1); /* TXD3 */ - at91_pio_use_periph_b(AT91RM92_PIOA_BASE, AT91C_PIO_PA6, 0); /* RXD3 */ - /* CTS - PB0 B periph */ - /* RTS - PB1 B periph */ - break; - - default: - break; - } -} - -void -at91rm9200_config_mci(int has_4wire) -{ - /* XXX TODO chip changed GPIO, other slots, etc */ - at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA27, 0); /* MCCK */ - at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA28, 1); /* MCCDA */ - at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA29, 1); /* MCDA0 */ - if (has_4wire) { - at91_pio_use_periph_b(AT91RM92_PIOB_BASE, AT91C_PIO_PB3, 1); /* MCDA1 */ - at91_pio_use_periph_b(AT91RM92_PIOB_BASE, AT91C_PIO_PB4, 1); /* MCDA2 */ - at91_pio_use_periph_b(AT91RM92_PIOB_BASE, AT91C_PIO_PB5, 1); /* MCDA3 */ - } -} Index: head/sys/arm/at91/at91rm9200var.h =================================================================== --- head/sys/arm/at91/at91rm9200var.h +++ head/sys/arm/at91/at91rm9200var.h @@ -1,60 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2012 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef ARM_AT91_AT91RM9200VAR_H -#define ARM_AT91_AT91RM9200VAR_H - -void at91rm9200_set_subtype(enum at91_soc_subtype st); - -#define AT91RM9200_ID_USART0 1 -#define AT91RM9200_ID_USART1 2 -#define AT91RM9200_ID_USART2 3 -#define AT91RM9200_ID_USART3 4 - -/* - * Serial port convenience routines - */ -/* uart pins that are wired... */ -#define AT91_UART_CTS 0x01 -#define AT91_UART_RTS 0x02 -#define AT91_UART_RI 0x04 -#define AT91_UART_DTR 0x08 -#define AT91_UART_DCD 0x10 -#define AT91_UART_DSR 0x20 - -#define AT91_ID_DBGU 0 - -void at91rm9200_config_uart(unsigned devid, unsigned unit, unsigned pinmask); - -/* - * MCI (sd/mmc card support) - */ -void at91rm9200_config_mci(int has_4wire); - -#endif /* ARM_AT91_AT91RM9200VAR_H */ Index: head/sys/arm/at91/at91rm92reg.h =================================================================== --- head/sys/arm/at91/at91rm92reg.h +++ head/sys/arm/at91/at91rm92reg.h @@ -1,308 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2005 Olivier Houchard. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef AT91RM92REG_H_ -#define AT91RM92REG_H_ - -/* Chip Specific limits */ -#define RM9200_PLL_A_MIN_IN_FREQ 1000000 /* 1 MHz */ -#define RM9200_PLL_A_MAX_IN_FREQ 32000000 /* 32 MHz */ -#define RM9200_PLL_A_MIN_OUT_FREQ 80000000 /* 80 MHz */ -#define RM9200_PLL_A_MAX_OUT_FREQ 180000000 /* 180 MHz */ -#define RM9200_PLL_A_MUL_SHIFT 16 -#define RM9200_PLL_A_MUL_MASK 0x7FF -#define RM9200_PLL_A_DIV_SHIFT 0 -#define RM9200_PLL_A_DIV_MASK 0xFF - -/* - * PLL B input frequency spec sheet says it must be between 1MHz and 32MHz, - * but it works down as low as 100kHz, a frequency necessary for some - * output frequencies to work. - * - * PLL Max output frequency is 240MHz. The errata says 180MHz is the max - * for some revisions of this part. Be more permissive and optimistic. - */ -#define RM9200_PLL_B_MIN_IN_FREQ 100000 /* 100 KHz */ -#define RM9200_PLL_B_MAX_IN_FREQ 32000000 /* 32 MHz */ -#define RM9200_PLL_B_MIN_OUT_FREQ 30000000 /* 30 MHz */ -#define RM9200_PLL_B_MAX_OUT_FREQ 240000000 /* 240 MHz */ -#define RM9200_PLL_B_MUL_SHIFT 16 -#define RM9200_PLL_B_MUL_MASK 0x7FF -#define RM9200_PLL_B_DIV_SHIFT 0 -#define RM9200_PLL_B_DIV_MASK 0xFF - -/* - * Memory map, from datasheet : - * 0x00000000 - 0x0ffffffff : Internal Memories - * 0x10000000 - 0x1ffffffff : Chip Select 0 - * 0x20000000 - 0x2ffffffff : Chip Select 1 - * 0x30000000 - 0x3ffffffff : Chip Select 2 - * 0x40000000 - 0x4ffffffff : Chip Select 3 - * 0x50000000 - 0x5ffffffff : Chip Select 4 - * 0x60000000 - 0x6ffffffff : Chip Select 5 - * 0x70000000 - 0x7ffffffff : Chip Select 6 - * 0x80000000 - 0x8ffffffff : Chip Select 7 - * 0x90000000 - 0xeffffffff : Undefined (Abort) - * 0xf0000000 - 0xfffffffff : Peripherals - */ - -/* Usart */ - -#define AT91RM92_USART_SIZE 0x4000 -#define AT91RM92_USART0_BASE 0xffc0000 -#define AT91RM92_USART0_PDC 0xffc0100 -#define AT91RM92_USART0_SIZE AT91RM92_USART_SIZE -#define AT91RM92_USART1_BASE 0xffc4000 -#define AT91RM92_USART1_PDC 0xffc4100 -#define AT91RM92_USART1_SIZE AT91RM92_USART_SIZE -#define AT91RM92_USART2_BASE 0xffc8000 -#define AT91RM92_USART2_PDC 0xffc8100 -#define AT91RM92_USART2_SIZE AT91RM92_USART_SIZE -#define AT91RM92_USART3_BASE 0xffcc000 -#define AT91RM92_USART3_PDC 0xffcc100 -#define AT91RM92_USART3_SIZE AT91RM92_USART_SIZE - -/* System Registers */ - -#define AT91RM92_SYS_BASE 0xffff000 -#define AT91RM92_SYS_SIZE 0x1000 - -/* - * PIO - */ -#define AT91RM92_PIO_SIZE 0x200 -#define AT91RM92_PIOA_BASE 0xffff400 -#define AT91RM92_PIOA_SIZE AT91RM92_PIO_SIZE -#define AT91RM92_PIOB_BASE 0xffff600 -#define AT91RM92_PIOB_SIZE AT91RM92_PIO_SIZE -#define AT91RM92_PIOC_BASE 0xffff800 -#define AT91RM92_PIOC_SIZE AT91RM92_PIO_SIZE -#define AT91RM92_PIOD_BASE 0xffffa00 -#define AT91RM92_PIOD_SIZE AT91RM92_PIO_SIZE - -/* - * PMC - */ -#define AT91RM92_PMC_BASE 0xffffc00 -#define AT91RM92_PMC_SIZE 0x100 - -/* IRQs : */ -/* - * 0: AIC - * 1: System peripheral (System timer, RTC, DBGU) - * 2: PIO Controller A - * 3: PIO Controller B - * 4: PIO Controller C - * 5: PIO Controller D - * 6: USART 0 - * 7: USART 1 - * 8: USART 2 - * 9: USART 3 - * 10: MMC Interface - * 11: USB device port - * 12: Two-wire interface - * 13: SPI - * 14: SSC - * 15: SSC - * 16: SSC - * 17: Timer Counter 0 - * 18: Timer Counter 1 - * 19: Timer Counter 2 - * 20: Timer Counter 3 - * 21: Timer Counter 4 - * 22: Timer Counter 5 - * 23: USB Host port - * 24: Ethernet - * 25: AIC - * 26: AIC - * 27: AIC - * 28: AIC - * 29: AIC - * 30: AIC - * 31: AIC - */ - -#define AT91RM92_IRQ_SYSTEM 1 -#define AT91RM92_IRQ_PIOA 2 -#define AT91RM92_IRQ_PIOB 3 -#define AT91RM92_IRQ_PIOC 4 -#define AT91RM92_IRQ_PIOD 5 -#define AT91RM92_IRQ_USART0 6 -#define AT91RM92_IRQ_USART1 7 -#define AT91RM92_IRQ_USART2 8 -#define AT91RM92_IRQ_USART3 9 -#define AT91RM92_IRQ_MCI 10 -#define AT91RM92_IRQ_UDP 11 -#define AT91RM92_IRQ_TWI 12 -#define AT91RM92_IRQ_SPI 13 -#define AT91RM92_IRQ_SSC0 14 -#define AT91RM92_IRQ_SSC1 15 -#define AT91RM92_IRQ_SSC2 16 -#define AT91RM92_IRQ_TC0 17,18,19 -#define AT91RM92_IRQ_TC0C0 17 -#define AT91RM92_IRQ_TC0C1 18 -#define AT91RM92_IRQ_TC0C2 19 -#define AT91RM92_IRQ_TC1 20,21,22 -#define AT91RM92_IRQ_TC1C1 20 -#define AT91RM92_IRQ_TC1C2 21 -#define AT91RM92_IRQ_TC1C3 22 -#define AT91RM92_IRQ_UHP 23 -#define AT91RM92_IRQ_EMAC 24 -#define AT91RM92_IRQ_AIC_IRQ0 25 -#define AT91RM92_IRQ_AIC_IRQ1 26 -#define AT91RM92_IRQ_AIC_IRQ2 27 -#define AT91RM92_IRQ_AIC_IRQ3 28 -#define AT91RM92_IRQ_AIC_IRQ4 29 -#define AT91RM92_IRQ_AIC_IRQ5 30 -#define AT91RM92_IRQ_AIC_IRQ6 31 - -/* Alias */ -#define AT91RM92_IRQ_DBGU AT91RM92_IRQ_SYSTEM -#define AT91RM92_IRQ_PMC AT91RM92_IRQ_SYSTEM -#define AT91RM92_IRQ_ST AT91RM92_IRQ_SYSTEM -#define AT91RM92_IRQ_RTC AT91RM92_IRQ_SYSTEM -#define AT91RM92_IRQ_MC AT91RM92_IRQ_SYSTEM -#define AT91RM92_IRQ_OHCI AT91RM92_IRQ_UHP -#define AT91RM92_IRQ_AIC -1 -#define AT91RM92_IRQ_CF -1 - -/* Timer */ - -#define AT91RM92_AIC_BASE 0xffff000 -#define AT91RM92_AIC_SIZE 0x200 - -/* DBGU */ -#define AT91RM92_DBGU_BASE 0xffff200 -#define AT91RM92_DBGU_SIZE 0x200 - -#define AT91RM92_RTC_BASE 0xffffe00 -#define AT91RM92_RTC_SIZE 0x100 - -#define AT91RM92_MC_BASE 0xfffff00 -#define AT91RM92_MC_SIZE 0x100 - -#define AT91RM92_ST_BASE 0xffffd00 -#define AT91RM92_ST_SIZE 0x100 - -#define AT91RM92_SPI_BASE 0xffe0000 -#define AT91RM92_SPI_SIZE 0x4000 -#define AT91RM92_SPI_PDC 0xffe0100 - -#define AT91RM92_SSC_SIZE 0x4000 -#define AT91RM92_SSC0_BASE 0xffd0000 -#define AT91RM92_SSC0_PDC 0xffd0100 -#define AT91RM92_SSC0_SIZE AT91RM92_SSC_SIZE - -#define AT91RM92_SSC1_BASE 0xffd4000 -#define AT91RM92_SSC1_PDC 0xffd4100 -#define AT91RM92_SSC1_SIZE AT91RM92_SSC_SIZE - -#define AT91RM92_SSC2_BASE 0xffd8000 -#define AT91RM92_SSC2_PDC 0xffd8100 -#define AT91RM92_SSC2_SIZE AT91RM92_SSC_SIZE - -#define AT91RM92_EMAC_BASE 0xffbc000 -#define AT91RM92_EMAC_SIZE 0x4000 - -#define AT91RM92_TWI_BASE 0xffb8000 -#define AT91RM92_TWI_SIZE 0x4000 - -#define AT91RM92_MCI_BASE 0xffb4000 -#define AT91RM92_MCI_PDC 0xffb4100 -#define AT91RM92_MCI_SIZE 0x4000 - -#define AT91RM92_UDP_BASE 0xffb0000 -#define AT91RM92_UDP_SIZE 0x4000 - -#define AT91RM92_TC_SIZE 0x4000 -#define AT91RM92_TC0_BASE 0xffa0000 -#define AT91RM92_TC0_SIZE AT91RM92_TC_SIZE -#define AT91RM92_TC0C0_BASE 0xffa0000 -#define AT91RM92_TC0C1_BASE 0xffa0040 -#define AT91RM92_TC0C2_BASE 0xffa0080 - -#define AT91RM92_TC1_BASE 0xffa4000 -#define AT91RM92_TC1_SIZE AT91RM92_TC_SIZE -#define AT91RM92_TC1C0_BASE 0xffa4000 -#define AT91RM92_TC1C1_BASE 0xffa4040 -#define AT91RM92_TC1C2_BASE 0xffa4080 - -/* XXX Needs to be carfully coordinated with - * other * soc's so phyical and vm address - * mapping are unique. XXX - */ -#define AT91RM92_OHCI_VA_BASE 0xdfe00000 -#define AT91RM92_OHCI_BASE 0x00300000 -#define AT91RM92_OHCI_SIZE 0x00100000 - -#define AT91RM92_CF_VA_BASE 0xdfd00000 -#define AT91RM92_CF_BASE 0x51400000 -#define AT91RM92_CF_SIZE 0x00100000 - -/* SDRAMC */ - -#define AT91RM92_SDRAMC_BASE 0xfffff90 -#define AT91RM92_SDRAMC_MR 0x00 -#define AT91RM92_SDRAMC_MR_MODE_NORMAL 0 -#define AT91RM92_SDRAMC_MR_MODE_NOP 1 -#define AT91RM92_SDRAMC_MR_MODE_PRECHARGE 2 -#define AT91RM92_SDRAMC_MR_MODE_LOAD_MODE_REGISTER 3 -#define AT91RM92_SDRAMC_MR_MODE_REFRESH 4 -#define AT91RM92_SDRAMC_MR_DBW_16 0x10 -#define AT91RM92_SDRAMC_TR 0x04 -#define AT91RM92_SDRAMC_CR 0x08 -#define AT91RM92_SDRAMC_CR_NC_8 0x0 -#define AT91RM92_SDRAMC_CR_NC_9 0x1 -#define AT91RM92_SDRAMC_CR_NC_10 0x2 -#define AT91RM92_SDRAMC_CR_NC_11 0x3 -#define AT91RM92_SDRAMC_CR_NC_MASK 0x00000003 -#define AT91RM92_SDRAMC_CR_NR_11 0x0 -#define AT91RM92_SDRAMC_CR_NR_12 0x4 -#define AT91RM92_SDRAMC_CR_NR_13 0x8 -#define AT91RM92_SDRAMC_CR_NR_RES 0xc -#define AT91RM92_SDRAMC_CR_NR_MASK 0x0000000c -#define AT91RM92_SDRAMC_CR_NB_2 0x00 -#define AT91RM92_SDRAMC_CR_NB_4 0x10 -#define AT91RM92_SDRAMC_CR_NB_MASK 0x00000010 -#define AT91RM92_SDRAMC_CR_NCAS_MASK 0x00000060 -#define AT91RM92_SDRAMC_CR_TWR_MASK 0x00000780 -#define AT91RM92_SDRAMC_CR_TRC_MASK 0x00007800 -#define AT91RM92_SDRAMC_CR_TRP_MASK 0x00078000 -#define AT91RM92_SDRAMC_CR_TRCD_MASK 0x00780000 -#define AT91RM92_SDRAMC_CR_TRAS_MASK 0x07800000 -#define AT91RM92_SDRAMC_CR_TXSR_MASK 0x78000000 -#define AT91RM92_SDRAMC_SRR 0x0c -#define AT91RM92_SDRAMC_LPR 0x10 -#define AT91RM92_SDRAMC_IER 0x14 -#define AT91RM92_SDRAMC_IDR 0x18 -#define AT91RM92_SDRAMC_IMR 0x1c -#define AT91RM92_SDRAMC_ISR 0x20 -#define AT91RM92_SDRAMC_IER_RES 0x1 - -#endif /* AT91RM92REG_H_ */ Index: head/sys/arm/at91/at91sam9260.c =================================================================== --- head/sys/arm/at91/at91sam9260.c +++ head/sys/arm/at91/at91sam9260.c @@ -1,219 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2005 Olivier Houchard. All rights reserved. - * Copyright (c) 2010 Greg Ansley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include - -#define _ARM32_BUS_DMA_PRIVATE -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Standard priority levels for the system. 0 is lowest and 7 is highest. - * These values are the ones Atmel uses for its Linux port - */ -static const int at91_irq_prio[32] = -{ - 7, /* Advanced Interrupt Controller */ - 7, /* System Peripherals */ - 1, /* Parallel IO Controller A */ - 1, /* Parallel IO Controller B */ - 1, /* Parallel IO Controller C */ - 0, /* Analog-to-Digital Converter */ - 5, /* USART 0 */ - 5, /* USART 1 */ - 5, /* USART 2 */ - 0, /* Multimedia Card Interface */ - 2, /* USB Device Port */ - 6, /* Two-Wire Interface */ - 5, /* Serial Peripheral Interface 0 */ - 5, /* Serial Peripheral Interface 1 */ - 5, /* Serial Synchronous Controller */ - 0, /* (reserved) */ - 0, /* (reserved) */ - 0, /* Timer Counter 0 */ - 0, /* Timer Counter 1 */ - 0, /* Timer Counter 2 */ - 2, /* USB Host port */ - 3, /* Ethernet */ - 0, /* Image Sensor Interface */ - 5, /* USART 3 */ - 5, /* USART 4 */ - 5, /* USART 5 */ - 0, /* Timer Counter 3 */ - 0, /* Timer Counter 4 */ - 0, /* Timer Counter 5 */ - 0, /* Advanced Interrupt Controller IRQ0 */ - 0, /* Advanced Interrupt Controller IRQ1 */ - 0, /* Advanced Interrupt Controller IRQ2 */ -}; - -static const uint32_t at91_pio_base[] = { - AT91SAM9260_PIOA_BASE, - AT91SAM9260_PIOB_BASE, - AT91SAM9260_PIOC_BASE, -}; - -#define DEVICE(_name, _id, _unit) \ - { \ - _name, _unit, \ - AT91SAM9260_ ## _id ##_BASE, \ - AT91SAM9260_ ## _id ## _SIZE, \ - AT91SAM9260_IRQ_ ## _id \ - } - -static const struct cpu_devs at91_devs[] = -{ - DEVICE("at91_aic", AIC, 0), - DEVICE("at91_pmc", PMC, 0), - DEVICE("at91_wdt", WDT, 0), - DEVICE("at91_rst", RSTC, 0), - DEVICE("at91_pit", PIT, 0), - DEVICE("at91_pio", PIOA, 0), - DEVICE("at91_pio", PIOB, 1), - DEVICE("at91_pio", PIOC, 2), - DEVICE("at91_twi", TWI, 0), - DEVICE("at91_mci", MCI, 0), - DEVICE("uart", DBGU, 0), - DEVICE("uart", USART0, 1), - DEVICE("uart", USART1, 2), - DEVICE("uart", USART2, 3), - DEVICE("uart", USART3, 4), - DEVICE("uart", USART4, 5), - DEVICE("uart", USART5, 6), - DEVICE("spi", SPI0, 0), - DEVICE("spi", SPI1, 1), - DEVICE("ate", EMAC, 0), - DEVICE("macb", EMAC, 0), - DEVICE("nand", NAND, 0), - DEVICE("ohci", OHCI, 0), - { 0, 0, 0, 0, 0 } -}; - -/* - * The following is unused currently since we don't ever set the PLLA - * frequency of the device. - */ -static uint32_t -at91_pll_outa(int freq) -{ - uint32_t outa = 0; - - /* - * Set OUTA, per the data sheet. See Table 40-15 titled - * PLLA Characteristics in the SAM9260 doc. - */ - - if (freq > 155000000) - outa = 2 << 14; - return ((1 << 29) | outa); -} - -static uint32_t -at91_pll_outb(int freq) -{ - - return (1 << 14); -} - -static void -at91_clock_init(void) -{ - struct at91_pmc_clock *clk; - - /* Update USB device port clock info */ - clk = at91_pmc_clock_ref("udpck"); - clk->pmc_mask = PMC_SCER_UDP_SAM9; - at91_pmc_clock_deref(clk); - - /* Update USB host port clock info */ - clk = at91_pmc_clock_ref("uhpck"); - clk->pmc_mask = PMC_SCER_UHP_SAM9; - at91_pmc_clock_deref(clk); - - /* Each SOC has different PLL contraints */ - clk = at91_pmc_clock_ref("plla"); - clk->pll_min_in = SAM9260_PLL_A_MIN_IN_FREQ; /* 1 MHz */ - clk->pll_max_in = SAM9260_PLL_A_MAX_IN_FREQ; /* 32 MHz */ - clk->pll_min_out = SAM9260_PLL_A_MIN_OUT_FREQ; /* 80 MHz */ - clk->pll_max_out = SAM9260_PLL_A_MAX_OUT_FREQ; /* 240 MHz */ - clk->pll_mul_shift = SAM9260_PLL_A_MUL_SHIFT; - clk->pll_mul_mask = SAM9260_PLL_A_MUL_MASK; - clk->pll_div_shift = SAM9260_PLL_A_DIV_SHIFT; - clk->pll_div_mask = SAM9260_PLL_A_DIV_MASK; - clk->set_outb = at91_pll_outa; - at91_pmc_clock_deref(clk); - - /* - * Fudge MAX pll in frequence down below 3.0 MHz to ensure - * PMC alogrithm choose the divisor that causes the input clock - * to be near the optimal 2 MHz per datasheet. We know - * we are going to be using this for the USB clock at 96 MHz. - * Causes no extra frequency deviation for all recommended crystal - * values. See Note 1, table 40-16 SAM9260 doc. - */ - clk = at91_pmc_clock_ref("pllb"); - clk->pll_min_in = SAM9260_PLL_B_MIN_IN_FREQ; /* 1 MHz */ - clk->pll_max_in = 2999999; /* ~3 MHz */ - clk->pll_min_out = SAM9260_PLL_B_MIN_OUT_FREQ; /* 70 MHz */ - clk->pll_max_out = SAM9260_PLL_B_MAX_OUT_FREQ; /* 130 MHz */ - clk->pll_mul_shift = SAM9260_PLL_B_MUL_SHIFT; - clk->pll_mul_mask = SAM9260_PLL_B_MUL_MASK; - clk->pll_div_shift = SAM9260_PLL_B_DIV_SHIFT; - clk->pll_div_mask = SAM9260_PLL_B_DIV_MASK; - clk->set_outb = at91_pll_outb; - at91_pmc_clock_deref(clk); -} - -static struct at91_soc_data soc_data = { - .soc_delay = at91_pit_delay, - .soc_reset = at91_rst_cpu_reset, - .soc_clock_init = at91_clock_init, - .soc_irq_prio = at91_irq_prio, - .soc_children = at91_devs, - .soc_pio_base = at91_pio_base, - .soc_pio_count = nitems(at91_pio_base), -}; - -AT91_SOC(AT91_T_SAM9260, &soc_data); Index: head/sys/arm/at91/at91sam9260reg.h =================================================================== --- head/sys/arm/at91/at91sam9260reg.h +++ head/sys/arm/at91/at91sam9260reg.h @@ -1,306 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010 Greg Ansley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef AT91SAM9260REG_H_ -#define AT91SAM9260REG_H_ - -/* Chip Specific limits */ -#define SAM9260_PLL_A_MIN_IN_FREQ 1000000 /* 1 Mhz */ -#define SAM9260_PLL_A_MAX_IN_FREQ 32000000 /* 32 Mhz */ -#define SAM9260_PLL_A_MIN_OUT_FREQ 80000000 /* 80 Mhz */ -#define SAM9260_PLL_A_MAX_OUT_FREQ 240000000 /* 240 Mhz */ -#define SAM9260_PLL_A_MUL_SHIFT 16 -#define SAM9260_PLL_A_MUL_MASK 0x3FF -#define SAM9260_PLL_A_DIV_SHIFT 0 -#define SAM9260_PLL_A_DIV_MASK 0xFF - -#define SAM9260_PLL_B_MIN_IN_FREQ 1000000 /* 1 Mhz */ -#define SAM9260_PLL_B_MAX_IN_FREQ 5000000 /* 5 Mhz */ -#define SAM9260_PLL_B_MIN_OUT_FREQ 70000000 /* 70 Mhz */ -#define SAM9260_PLL_B_MAX_OUT_FREQ 130000000 /* 130 Mhz */ -#define SAM9260_PLL_B_MUL_SHIFT 16 -#define SAM9260_PLL_B_MUL_MASK 0x3FF -#define SAM9260_PLL_B_DIV_SHIFT 0 -#define SAM9260_PLL_B_DIV_MASK 0xFF - -/* - * Memory map, from datasheet : - * 0x00000000 - 0x0ffffffff : Internal Memories - * 0x10000000 - 0x1ffffffff : Chip Select 0 - * 0x20000000 - 0x2ffffffff : Chip Select 1 - * 0x30000000 - 0x3ffffffff : Chip Select 2 - * 0x40000000 - 0x4ffffffff : Chip Select 3 - * 0x50000000 - 0x5ffffffff : Chip Select 4 - * 0x60000000 - 0x6ffffffff : Chip Select 5 - * 0x70000000 - 0x7ffffffff : Chip Select 6 - * 0x80000000 - 0x8ffffffff : Chip Select 7 - * 0x90000000 - 0xeffffffff : Undefined (Abort) - * 0xf0000000 - 0xfffffffff : Peripherals - */ - -#define AT91_CHIPSELECT_0 0x10000000 -#define AT91_CHIPSELECT_1 0x20000000 -#define AT91_CHIPSELECT_2 0x30000000 -#define AT91_CHIPSELECT_3 0x40000000 -#define AT91_CHIPSELECT_4 0x50000000 -#define AT91_CHIPSELECT_5 0x60000000 -#define AT91_CHIPSELECT_6 0x70000000 -#define AT91_CHIPSELECT_7 0x80000000 - - -#define AT91SAM9260_EMAC_BASE 0xffc4000 -#define AT91SAM9260_EMAC_SIZE 0x4000 - -#define AT91SAM9260_RSTC_BASE 0xffffd00 -#define AT91SAM9260_RSTC_SIZE 0x10 - -#define RSTC_CR 0 -#define RSTC_PROCRST (1 << 0) -#define RSTC_PERRST (1 << 2) -#define RSTC_KEY (0xa5 << 24) - -/* USART*/ - -#define AT91SAM9260_USART_SIZE 0x4000 -#define AT91SAM9260_USART0_BASE 0xffb0000 -#define AT91SAM9260_USART0_PDC 0xffb0100 -#define AT91SAM9260_USART0_SIZE AT91SAM9260_USART_SIZE -#define AT91SAM9260_USART1_BASE 0xffb4000 -#define AT91SAM9260_USART1_PDC 0xffb4100 -#define AT91SAM9260_USART1_SIZE AT91SAM9260_USART_SIZE -#define AT91SAM9260_USART2_BASE 0xffb8000 -#define AT91SAM9260_USART2_PDC 0xffb8100 -#define AT91SAM9260_USART2_SIZE AT91SAM9260_USART_SIZE -#define AT91SAM9260_USART3_BASE 0xffd0000 -#define AT91SAM9260_USART3_PDC 0xffd0100 -#define AT91SAM9260_USART3_SIZE AT91SAM9260_USART_SIZE -#define AT91SAM9260_USART4_BASE 0xffd4000 -#define AT91SAM9260_USART4_PDC 0xffd4100 -#define AT91SAM9260_USART4_SIZE AT91SAM9260_USART_SIZE -#define AT91SAM9260_USART5_BASE 0xffd8000 -#define AT91SAM9260_USART5_PDC 0xffd8100 -#define AT91SAM9260_USART5_SIZE AT91SAM9260_USART_SIZE - -/*TC*/ -#define AT91SAM9260_TC0_BASE 0xffa0000 -#define AT91SAM9260_TC0_SIZE 0x4000 -#define AT91SAM9260_TC0C0_BASE 0xffa0000 -#define AT91SAM9260_TC0C1_BASE 0xffa0040 -#define AT91SAM9260_TC0C2_BASE 0xffa0080 - -#define AT91SAM9260_TC1_BASE 0xffdc000 -#define AT91SAM9260_TC1_SIZE 0x4000 - -/*SPI*/ - -#define AT91SAM9260_SPI0_BASE 0xffc8000 - -#define AT91SAM9260_SPI0_SIZE 0x4000 -#define AT91SAM9260_IRQ_SPI0 12 - -#define AT91SAM9260_SPI1_BASE 0xffcc000 -#define AT91SAM9260_SPI1_SIZE 0x4000 -#define AT91SAM9260_IRQ_SPI1 13 - -/* System Registers */ -#define AT91SAM9260_SYS_BASE 0xffff000 -#define AT91SAM9260_SYS_SIZE 0x1000 - -#define AT91SAM9260_MATRIX_BASE 0xfffee00 -#define AT91SAM9260_MATRIX_SIZE 0x1000 -#define AT91SAM9260_EBICSA 0x011C - -#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3) - -#define AT91SAM9260_DBGU_BASE 0xffff200 -#define AT91SAM9260_DBGU_SIZE 0x200 - -/* - * PIO - */ -#define AT91SAM9260_PIOA_BASE 0xffff400 -#define AT91SAM9260_PIOA_SIZE 0x200 -#define AT91SAM9260_PIOB_BASE 0xffff600 -#define AT91SAM9260_PIOB_SIZE 0x200 -#define AT91SAM9260_PIOC_BASE 0xffff800 -#define AT91SAM9260_PIOC_SIZE 0x200 - -#define AT91RM92_PMC_BASE 0xffffc00 -#define AT91RM92_PMC_SIZE 0x100 -/* IRQs : */ -/* - * 0: AIC - * 1: System peripheral (System timer, RTC, DBGU) - * 2: PIO Controller A - * 3: PIO Controller B - * 4: PIO Controller C - * 5: ADC - * 6: USART 0 - * 7: USART 1 - * 8: USART 2 - * 9: MMC Interface - * 10: USB device port - * 11: Two-wire interface - * 12: SPI 0 - * 13: SPI 1 - * 14: SSC - * 15: - (reserved) - * 16: - (reserved) - * 17: Timer Counter 0 - * 18: Timer Counter 1 - * 19: Timer Counter 2 - * 20: USB Host port - * 21: EMAC - * 22: ISI - * 23: USART 3 - * 24: USART 4 - * 25: USART 2 - * 26: Timer Counter 3 - * 27: Timer Counter 4 - * 28: Timer Counter 5 - * 29: AIC IRQ0 - * 30: AIC IRQ1 - * 31: AIC IRQ2 - */ - -#define AT91SAM9260_IRQ_SYSTEM 1 -#define AT91SAM9260_IRQ_PIOA 2 -#define AT91SAM9260_IRQ_PIOB 3 -#define AT91SAM9260_IRQ_PIOC 4 -#define AT91SAM9260_IRQ_USART0 6 -#define AT91SAM9260_IRQ_USART1 7 -#define AT91SAM9260_IRQ_USART2 8 -#define AT91SAM9260_IRQ_MCI 9 -#define AT91SAM9260_IRQ_UDP 10 -#define AT91SAM9260_IRQ_TWI 11 -#define AT91SAM9260_IRQ_SPI0 12 -#define AT91SAM9260_IRQ_SPI1 13 -#define AT91SAM9260_IRQ_SSC0 14 -#define AT91SAM9260_IRQ_SSC1 15 -#define AT91SAM9260_IRQ_SSC2 16 -#define AT91SAM9260_IRQ_TC0 17 -#define AT91SAM9260_IRQ_TC1 18 -#define AT91SAM9260_IRQ_TC2 19 -#define AT91SAM9260_IRQ_UHP 20 -#define AT91SAM9260_IRQ_EMAC 21 -#define AT91SAM9260_IRQ_USART3 23 -#define AT91SAM9260_IRQ_USART4 24 -#define AT91SAM9260_IRQ_USART5 25 -#define AT91SAM9260_IRQ_AICBASE 29 - -/* Alias */ -#define AT91SAM9260_IRQ_DBGU AT91SAM9260_IRQ_SYSTEM -#define AT91SAM9260_IRQ_PMC AT91SAM9260_IRQ_SYSTEM -#define AT91SAM9260_IRQ_WDT AT91SAM9260_IRQ_SYSTEM -#define AT91SAM9260_IRQ_PIT AT91SAM9260_IRQ_SYSTEM -#define AT91SAM9260_IRQ_RSTC AT91SAM9260_IRQ_SYSTEM -#define AT91SAM9260_IRQ_OHCI AT91SAM9260_IRQ_UHP -#define AT91SAM9260_IRQ_NAND (-1) -#define AT91SAM9260_IRQ_AIC (-1) - -#define AT91SAM9260_AIC_BASE 0xffff000 -#define AT91SAM9260_AIC_SIZE 0x200 - -/* Timer */ - -#define AT91SAM9260_WDT_BASE 0xffffd40 -#define AT91SAM9260_WDT_SIZE 0x10 - -#define AT91SAM9260_PIT_BASE 0xffffd30 -#define AT91SAM9260_PIT_SIZE 0x10 - -#define AT91SAM9260_SMC_BASE 0xfffec00 -#define AT91SAM9260_SMC_SIZE 0x200 - -#define AT91SAM9260_PMC_BASE 0xffffc00 -#define AT91SAM9260_PMC_SIZE 0x100 - -#define AT91SAM9260_UDP_BASE 0xffa4000 -#define AT91SAM9260_UDP_SIZE 0x4000 - -#define AT91SAM9260_MCI_BASE 0xffa8000 -#define AT91SAM9260_MCI_SIZE 0x4000 - -#define AT91SAM9260_TWI_BASE 0xffaC000 -#define AT91SAM9260_TWI_SIZE 0x4000 - -/* XXX Needs to be carfully coordinated with - * other * soc's so phyical and vm address - * mapping are unique. XXX - */ -#define AT91SAM9260_OHCI_VA_BASE 0xdfc00000 -#define AT91SAM9260_OHCI_BASE 0x00500000 -#define AT91SAM9260_OHCI_SIZE 0x00100000 - -#define AT91SAM9260_NAND_VA_BASE 0xe0000000 -#define AT91SAM9260_NAND_BASE 0x40000000 -#define AT91SAM9260_NAND_SIZE 0x10000000 - - -/* SDRAMC */ -#define AT91SAM9260_SDRAMC_BASE 0xfffea00 -#define AT91SAM9260_SDRAMC_MR 0x00 -#define AT91SAM9260_SDRAMC_MR_MODE_NORMAL 0 -#define AT91SAM9260_SDRAMC_MR_MODE_NOP 1 -#define AT91SAM9260_SDRAMC_MR_MODE_PRECHARGE 2 -#define AT91SAM9260_SDRAMC_MR_MODE_LOAD_MODE_REGISTER 3 -#define AT91SAM9260_SDRAMC_MR_MODE_REFRESH 4 -#define AT91SAM9260_SDRAMC_TR 0x04 -#define AT91SAM9260_SDRAMC_CR 0x08 -#define AT91SAM9260_SDRAMC_CR_NC_8 0x0 -#define AT91SAM9260_SDRAMC_CR_NC_9 0x1 -#define AT91SAM9260_SDRAMC_CR_NC_10 0x2 -#define AT91SAM9260_SDRAMC_CR_NC_11 0x3 -#define AT91SAM9260_SDRAMC_CR_NC_MASK 0x00000003 -#define AT91SAM9260_SDRAMC_CR_NR_11 0x0 -#define AT91SAM9260_SDRAMC_CR_NR_12 0x4 -#define AT91SAM9260_SDRAMC_CR_NR_13 0x8 -#define AT91SAM9260_SDRAMC_CR_NR_RES 0xc -#define AT91SAM9260_SDRAMC_CR_NR_MASK 0x0000000c -#define AT91SAM9260_SDRAMC_CR_NB_2 0x00 -#define AT91SAM9260_SDRAMC_CR_NB_4 0x10 -#define AT91SAM9260_SDRAMC_CR_DBW_16 0x80 -#define AT91SAM9260_SDRAMC_CR_NB_MASK 0x00000010 -#define AT91SAM9260_SDRAMC_CR_NCAS_MASK 0x00000060 -#define AT91SAM9260_SDRAMC_CR_TWR_MASK 0x00000780 -#define AT91SAM9260_SDRAMC_CR_TRC_MASK 0x00007800 -#define AT91SAM9260_SDRAMC_CR_TRP_MASK 0x00078000 -#define AT91SAM9260_SDRAMC_CR_TRCD_MASK 0x00780000 -#define AT91SAM9260_SDRAMC_CR_TRAS_MASK 0x07800000 -#define AT91SAM9260_SDRAMC_CR_TXSR_MASK 0x78000000 -#define AT91SAM9260_SDRAMC_HSR 0x0c -#define AT91SAM9260_SDRAMC_LPR 0x10 -#define AT91SAM9260_SDRAMC_IER 0x14 -#define AT91SAM9260_SDRAMC_IDR 0x18 -#define AT91SAM9260_SDRAMC_IMR 0x1c -#define AT91SAM9260_SDRAMC_ISR 0x20 -#define AT91SAM9260_SDRAMC_MDR 0x24 - -#endif /* AT91SAM9260REG_H_*/ - Index: head/sys/arm/at91/at91sam9g20.c =================================================================== --- head/sys/arm/at91/at91sam9g20.c +++ head/sys/arm/at91/at91sam9g20.c @@ -1,185 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2005 Olivier Houchard. All rights reserved. - * Copyright (c) 2010 Greg Ansley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include - -#define _ARM32_BUS_DMA_PRIVATE -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Standard priority levels for the system. 0 is lowest and 7 is highest. - * These values are the ones Atmel uses for its Linux port - */ -static const int at91_irq_prio[32] = -{ - 7, /* Advanced Interrupt Controller */ - 7, /* System Peripherals */ - 1, /* Parallel IO Controller A */ - 1, /* Parallel IO Controller B */ - 1, /* Parallel IO Controller C */ - 0, /* Analog-to-Digital Converter */ - 5, /* USART 0 */ - 5, /* USART 1 */ - 5, /* USART 2 */ - 0, /* Multimedia Card Interface */ - 2, /* USB Device Port */ - 6, /* Two-Wire Interface */ - 5, /* Serial Peripheral Interface 0 */ - 5, /* Serial Peripheral Interface 1 */ - 5, /* Serial Synchronous Controller */ - 0, /* (reserved) */ - 0, /* (reserved) */ - 0, /* Timer Counter 0 */ - 0, /* Timer Counter 1 */ - 0, /* Timer Counter 2 */ - 2, /* USB Host port */ - 3, /* Ethernet */ - 0, /* Image Sensor Interface */ - 5, /* USART 3 */ - 5, /* USART 4 */ - 5, /* USART 5 */ - 0, /* Timer Counter 3 */ - 0, /* Timer Counter 4 */ - 0, /* Timer Counter 5 */ - 0, /* Advanced Interrupt Controller IRQ0 */ - 0, /* Advanced Interrupt Controller IRQ1 */ - 0, /* Advanced Interrupt Controller IRQ2 */ -}; - -static const uint32_t at91_pio_base[] = { - AT91SAM9G20_PIOA_BASE, - AT91SAM9G20_PIOB_BASE, - AT91SAM9G20_PIOC_BASE, -}; - -#define DEVICE(_name, _id, _unit) \ - { \ - _name, _unit, \ - AT91SAM9G20_ ## _id ##_BASE, \ - AT91SAM9G20_ ## _id ## _SIZE, \ - AT91SAM9G20_IRQ_ ## _id \ - } - -static const struct cpu_devs at91_devs[] = -{ - DEVICE("at91_aic", AIC, 0), - DEVICE("at91_pmc", PMC, 0), - DEVICE("at91_wdt", WDT, 0), - DEVICE("at91_rst", RSTC, 0), - DEVICE("at91_pit", PIT, 0), - DEVICE("at91_pio", PIOA, 0), - DEVICE("at91_pio", PIOB, 1), - DEVICE("at91_pio", PIOC, 2), - DEVICE("at91_twi", TWI, 0), - DEVICE("at91_mci", MCI, 0), - DEVICE("uart", DBGU, 0), - DEVICE("uart", USART0, 1), - DEVICE("uart", USART1, 2), - DEVICE("uart", USART2, 3), - DEVICE("uart", USART3, 4), - DEVICE("uart", USART4, 5), - DEVICE("uart", USART5, 6), - DEVICE("spi", SPI0, 0), - DEVICE("spi", SPI1, 1), - DEVICE("ate", EMAC, 0), - DEVICE("macb", EMAC, 0), - DEVICE("nand", NAND, 0), - DEVICE("ohci", OHCI, 0), - { 0, 0, 0, 0, 0 } -}; - -static void -at91_clock_init(void) -{ - struct at91_pmc_clock *clk; - - /* Update USB device port clock info */ - clk = at91_pmc_clock_ref("udpck"); - clk->pmc_mask = PMC_SCER_UDP_SAM9; - at91_pmc_clock_deref(clk); - - /* Update USB host port clock info */ - clk = at91_pmc_clock_ref("uhpck"); - clk->pmc_mask = PMC_SCER_UHP_SAM9; - at91_pmc_clock_deref(clk); - - /* Each SOC has different PLL contraints */ - clk = at91_pmc_clock_ref("plla"); - clk->pll_min_in = SAM9G20_PLL_A_MIN_IN_FREQ; /* 2 MHz */ - clk->pll_max_in = SAM9G20_PLL_A_MAX_IN_FREQ; /* 32 MHz */ - clk->pll_min_out = SAM9G20_PLL_A_MIN_OUT_FREQ; /* 400 MHz */ - clk->pll_max_out = SAM9G20_PLL_A_MAX_OUT_FREQ; /* 800 MHz */ - clk->pll_mul_shift = SAM9G20_PLL_A_MUL_SHIFT; - clk->pll_mul_mask = SAM9G20_PLL_A_MUL_MASK; - clk->pll_div_shift = SAM9G20_PLL_A_DIV_SHIFT; - clk->pll_div_mask = SAM9G20_PLL_A_DIV_MASK; - clk->set_outb = at91_pmc_800mhz_plla_outb; - at91_pmc_clock_deref(clk); - - clk = at91_pmc_clock_ref("pllb"); - clk->pll_min_in = SAM9G20_PLL_B_MIN_IN_FREQ; /* 2 MHz */ - clk->pll_max_in = SAM9G20_PLL_B_MAX_IN_FREQ; /* 32 MHz */ - clk->pll_min_out = SAM9G20_PLL_B_MIN_OUT_FREQ; /* 30 MHz */ - clk->pll_max_out = SAM9G20_PLL_B_MAX_OUT_FREQ; /* 100 MHz */ - clk->pll_mul_shift = SAM9G20_PLL_B_MUL_SHIFT; - clk->pll_mul_mask = SAM9G20_PLL_B_MUL_MASK; - clk->pll_div_shift = SAM9G20_PLL_B_DIV_SHIFT; - clk->pll_div_mask = SAM9G20_PLL_B_DIV_MASK; - clk->set_outb = at91_pmc_800mhz_pllb_outb; - at91_pmc_clock_deref(clk); -} - -static struct at91_soc_data soc_data = { - .soc_delay = at91_pit_delay, - .soc_reset = at91_rst_cpu_reset, - .soc_clock_init = at91_clock_init, - .soc_irq_prio = at91_irq_prio, - .soc_children = at91_devs, - .soc_pio_base = at91_pio_base, - .soc_pio_count = nitems(at91_pio_base), -}; - -AT91_SOC(AT91_T_SAM9G20, &soc_data); Index: head/sys/arm/at91/at91sam9g20reg.h =================================================================== --- head/sys/arm/at91/at91sam9g20reg.h +++ head/sys/arm/at91/at91sam9g20reg.h @@ -1,306 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2009 Sylvestre Gallon. All rights reserved. - * Copyright (c) 2010 Greg Ansley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef AT91SAM9G20REG_H_ -#define AT91SAM9G20REG_H_ - -/* Chip Specific limits */ -#define SAM9G20_PLL_A_MIN_IN_FREQ 2000000 /* 2 Mhz */ -#define SAM9G20_PLL_A_MAX_IN_FREQ 32000000 /* 32 Mhz */ -#define SAM9G20_PLL_A_MIN_OUT_FREQ 400000000 /* 400 Mhz */ -#define SAM9G20_PLL_A_MAX_OUT_FREQ 800000000 /* 800 Mhz */ -#define SAM9G20_PLL_A_MUL_SHIFT 16 -#define SAM9G20_PLL_A_MUL_MASK 0xFF -#define SAM9G20_PLL_A_DIV_SHIFT 0 -#define SAM9G20_PLL_A_DIV_MASK 0xFF - -#define SAM9G20_PLL_B_MIN_IN_FREQ 2000000 /* 2 Mhz */ -#define SAM9G20_PLL_B_MAX_IN_FREQ 32000000 /* 32 Mhz */ -#define SAM9G20_PLL_B_MIN_OUT_FREQ 30000000 /* 30 Mhz */ -#define SAM9G20_PLL_B_MAX_OUT_FREQ 100000000 /* 100 Mhz */ -#define SAM9G20_PLL_B_MUL_SHIFT 16 -#define SAM9G20_PLL_B_MUL_MASK 0x3F -#define SAM9G20_PLL_B_DIV_SHIFT 0 -#define SAM9G20_PLL_B_DIV_MASK 0xFF - -/* - * Memory map, from datasheet : - * 0x00000000 - 0x0ffffffff : Internal Memories - * 0x10000000 - 0x1ffffffff : Chip Select 0 - * 0x20000000 - 0x2ffffffff : Chip Select 1 - * 0x30000000 - 0x3ffffffff : Chip Select 2 - * 0x40000000 - 0x4ffffffff : Chip Select 3 - * 0x50000000 - 0x5ffffffff : Chip Select 4 - * 0x60000000 - 0x6ffffffff : Chip Select 5 - * 0x70000000 - 0x7ffffffff : Chip Select 6 - * 0x80000000 - 0x8ffffffff : Chip Select 7 - * 0x90000000 - 0xeffffffff : Undefined (Abort) - * 0xf0000000 - 0xfffffffff : Peripherals - */ - -#define AT91_CHIPSELECT_0 0x10000000 -#define AT91_CHIPSELECT_1 0x20000000 -#define AT91_CHIPSELECT_2 0x30000000 -#define AT91_CHIPSELECT_3 0x40000000 -#define AT91_CHIPSELECT_4 0x50000000 -#define AT91_CHIPSELECT_5 0x60000000 -#define AT91_CHIPSELECT_6 0x70000000 -#define AT91_CHIPSELECT_7 0x80000000 - - -#define AT91SAM9G20_EMAC_BASE 0xffc4000 -#define AT91SAM9G20_EMAC_SIZE 0x4000 - -#define AT91SAM9G20_RSTC_BASE 0xffffd00 -#define AT91SAM9G20_RSTC_SIZE 0x10 - -#define RSTC_CR 0 -#define RSTC_PROCRST (1 << 0) -#define RSTC_PERRST (1 << 2) -#define RSTC_KEY (0xa5 << 24) - -/* USART*/ - -#define AT91SAM9G20_USART_SIZE 0x4000 -#define AT91SAM9G20_USART0_BASE 0xffb0000 -#define AT91SAM9G20_USART0_PDC 0xffb0100 -#define AT91SAM9G20_USART0_SIZE AT91SAM9G20_USART_SIZE -#define AT91SAM9G20_USART1_BASE 0xffb4000 -#define AT91SAM9G20_USART1_PDC 0xffb4100 -#define AT91SAM9G20_USART1_SIZE AT91SAM9G20_USART_SIZE -#define AT91SAM9G20_USART2_BASE 0xffb8000 -#define AT91SAM9G20_USART2_PDC 0xffb8100 -#define AT91SAM9G20_USART2_SIZE AT91SAM9G20_USART_SIZE -#define AT91SAM9G20_USART3_BASE 0xffd0000 -#define AT91SAM9G20_USART3_PDC 0xffd0100 -#define AT91SAM9G20_USART3_SIZE AT91SAM9G20_USART_SIZE -#define AT91SAM9G20_USART4_BASE 0xffd4000 -#define AT91SAM9G20_USART4_PDC 0xffd4100 -#define AT91SAM9G20_USART4_SIZE AT91SAM9G20_USART_SIZE -#define AT91SAM9G20_USART5_BASE 0xffd8000 -#define AT91SAM9G20_USART5_PDC 0xffd8100 -#define AT91SAM9G20_USART5_SIZE AT91SAM9G20_USART_SIZE - -/*TC*/ -#define AT91SAM9G20_TC0_BASE 0xffa0000 -#define AT91SAM9G20_TC0_SIZE 0x4000 -#define AT91SAM9G20_TC0C0_BASE 0xffa0000 -#define AT91SAM9G20_TC0C1_BASE 0xffa0040 -#define AT91SAM9G20_TC0C2_BASE 0xffa0080 - -#define AT91SAM9G20_TC1_BASE 0xffdc000 -#define AT91SAM9G20_TC1_SIZE 0x4000 - -/*SPI*/ - -#define AT91SAM9G20_SPI0_BASE 0xffc8000 - -#define AT91SAM9G20_SPI0_SIZE 0x4000 -#define AT91SAM9G20_IRQ_SPI0 12 - -#define AT91SAM9G20_SPI1_BASE 0xffcc000 -#define AT91SAM9G20_SPI1_SIZE 0x4000 -#define AT91SAM9G20_IRQ_SPI1 13 - -/* System Registers */ -#define AT91SAM9G20_SYS_BASE 0xffff000 -#define AT91SAM9G20_SYS_SIZE 0x1000 - -#define AT91SAM9G20_MATRIX_BASE 0xfffee00 -#define AT91SAM9G20_MATRIX_SIZE 0x1000 -#define AT91SAM9G20_EBICSA 0x011C - -#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3) - -#define AT91SAM9G20_DBGU_BASE 0xffff200 -#define AT91SAM9G20_DBGU_SIZE 0x200 - -/* - * PIO - */ -#define AT91SAM9G20_PIOA_BASE 0xffff400 -#define AT91SAM9G20_PIOA_SIZE 0x200 -#define AT91SAM9G20_PIOB_BASE 0xffff600 -#define AT91SAM9G20_PIOB_SIZE 0x200 -#define AT91SAM9G20_PIOC_BASE 0xffff800 -#define AT91SAM9G20_PIOC_SIZE 0x200 - -#define AT91RM92_PMC_BASE 0xffffc00 -#define AT91RM92_PMC_SIZE 0x100 -/* IRQs : */ -/* - * 0: AIC - * 1: System peripheral (System timer, RTC, DBGU) - * 2: PIO Controller A - * 3: PIO Controller B - * 4: PIO Controller C - * 5: ADC - * 6: USART 0 - * 7: USART 1 - * 8: USART 2 - * 9: MMC Interface - * 10: USB device port - * 11: Two-wire interface - * 12: SPI 0 - * 13: SPI 1 - * 14: SSC - * 15: - (reserved) - * 16: - (reserved) - * 17: Timer Counter 0 - * 18: Timer Counter 1 - * 19: Timer Counter 2 - * 20: USB Host port - * 21: EMAC - * 22: ISI - * 23: USART 3 - * 24: USART 4 - * 25: USART 2 - * 26: Timer Counter 3 - * 27: Timer Counter 4 - * 28: Timer Counter 5 - * 29: AIC IRQ0 - * 30: AIC IRQ1 - * 31: AIC IRQ2 - */ - -#define AT91SAM9G20_IRQ_SYSTEM 1 -#define AT91SAM9G20_IRQ_PIOA 2 -#define AT91SAM9G20_IRQ_PIOB 3 -#define AT91SAM9G20_IRQ_PIOC 4 -#define AT91SAM9G20_IRQ_USART0 6 -#define AT91SAM9G20_IRQ_USART1 7 -#define AT91SAM9G20_IRQ_USART2 8 -#define AT91SAM9G20_IRQ_MCI 9 -#define AT91SAM9G20_IRQ_UDP 10 -#define AT91SAM9G20_IRQ_TWI 11 -#define AT91SAM9G20_IRQ_SPI0 12 -#define AT91SAM9G20_IRQ_SPI1 13 -#define AT91SAM9G20_IRQ_SSC0 14 -#define AT91SAM9G20_IRQ_SSC1 15 -#define AT91SAM9G20_IRQ_SSC2 16 -#define AT91SAM9G20_IRQ_TC0 17 -#define AT91SAM9G20_IRQ_TC1 18 -#define AT91SAM9G20_IRQ_TC2 19 -#define AT91SAM9G20_IRQ_UHP 20 -#define AT91SAM9G20_IRQ_EMAC 21 -#define AT91SAM9G20_IRQ_USART3 23 -#define AT91SAM9G20_IRQ_USART4 24 -#define AT91SAM9G20_IRQ_USART5 25 -#define AT91SAM9G20_IRQ_AICBASE 29 - -/* Alias */ -#define AT91SAM9G20_IRQ_DBGU AT91SAM9G20_IRQ_SYSTEM -#define AT91SAM9G20_IRQ_PMC AT91SAM9G20_IRQ_SYSTEM -#define AT91SAM9G20_IRQ_WDT AT91SAM9G20_IRQ_SYSTEM -#define AT91SAM9G20_IRQ_PIT AT91SAM9G20_IRQ_SYSTEM -#define AT91SAM9G20_IRQ_RSTC AT91SAM9G20_IRQ_SYSTEM -#define AT91SAM9G20_IRQ_OHCI AT91SAM9G20_IRQ_UHP -#define AT91SAM9G20_IRQ_NAND (-1) -#define AT91SAM9G20_IRQ_AIC (-1) - -#define AT91SAM9G20_AIC_BASE 0xffff000 -#define AT91SAM9G20_AIC_SIZE 0x200 - -/* Timer */ - -#define AT91SAM9G20_WDT_BASE 0xffffd40 -#define AT91SAM9G20_WDT_SIZE 0x10 - -#define AT91SAM9G20_PIT_BASE 0xffffd30 -#define AT91SAM9G20_PIT_SIZE 0x10 - -#define AT91SAM9G20_SMC_BASE 0xfffec00 -#define AT91SAM9G20_SMC_SIZE 0x200 - -#define AT91SAM9G20_PMC_BASE 0xffffc00 -#define AT91SAM9G20_PMC_SIZE 0x100 - -#define AT91SAM9G20_UDP_BASE 0xffa4000 -#define AT91SAM9G20_UDP_SIZE 0x4000 - -#define AT91SAM9G20_MCI_BASE 0xffa8000 -#define AT91SAM9G20_MCI_SIZE 0x4000 - -#define AT91SAM9G20_TWI_BASE 0xffaC000 -#define AT91SAM9G20_TWI_SIZE 0x4000 - -/* XXX Needs to be carfully coordinated with - * other * soc's so phyical and vm address - * mapping are unique. XXX - */ -#define AT91SAM9G20_OHCI_VA_BASE 0xdfc00000 -#define AT91SAM9G20_OHCI_BASE 0x00500000 -#define AT91SAM9G20_OHCI_SIZE 0x00100000 - -#define AT91SAM9G20_NAND_VA_BASE 0xe0000000 -#define AT91SAM9G20_NAND_BASE 0x40000000 -#define AT91SAM9G20_NAND_SIZE 0x10000000 - -/* SDRAMC */ -#define AT91SAM9G20_SDRAMC_BASE 0xfffea00 -#define AT91SAM9G20_SDRAMC_MR 0x00 -#define AT91SAM9G20_SDRAMC_MR_MODE_NORMAL 0 -#define AT91SAM9G20_SDRAMC_MR_MODE_NOP 1 -#define AT91SAM9G20_SDRAMC_MR_MODE_PRECHARGE 2 -#define AT91SAM9G20_SDRAMC_MR_MODE_LOAD_MODE_REGISTER 3 -#define AT91SAM9G20_SDRAMC_MR_MODE_REFRESH 4 -#define AT91SAM9G20_SDRAMC_TR 0x04 -#define AT91SAM9G20_SDRAMC_CR 0x08 -#define AT91SAM9G20_SDRAMC_CR_NC_8 0x0 -#define AT91SAM9G20_SDRAMC_CR_NC_9 0x1 -#define AT91SAM9G20_SDRAMC_CR_NC_10 0x2 -#define AT91SAM9G20_SDRAMC_CR_NC_11 0x3 -#define AT91SAM9G20_SDRAMC_CR_NC_MASK 0x00000003 -#define AT91SAM9G20_SDRAMC_CR_NR_11 0x0 -#define AT91SAM9G20_SDRAMC_CR_NR_12 0x4 -#define AT91SAM9G20_SDRAMC_CR_NR_13 0x8 -#define AT91SAM9G20_SDRAMC_CR_NR_RES 0xc -#define AT91SAM9G20_SDRAMC_CR_NR_MASK 0x0000000c -#define AT91SAM9G20_SDRAMC_CR_NB_2 0x00 -#define AT91SAM9G20_SDRAMC_CR_NB_4 0x10 -#define AT91SAM9G20_SDRAMC_CR_DBW_16 0x80 -#define AT91SAM9G20_SDRAMC_CR_NB_MASK 0x00000010 -#define AT91SAM9G20_SDRAMC_CR_NCAS_MASK 0x00000060 -#define AT91SAM9G20_SDRAMC_CR_TWR_MASK 0x00000780 -#define AT91SAM9G20_SDRAMC_CR_TRC_MASK 0x00007800 -#define AT91SAM9G20_SDRAMC_CR_TRP_MASK 0x00078000 -#define AT91SAM9G20_SDRAMC_CR_TRCD_MASK 0x00780000 -#define AT91SAM9G20_SDRAMC_CR_TRAS_MASK 0x07800000 -#define AT91SAM9G20_SDRAMC_CR_TXSR_MASK 0x78000000 -#define AT91SAM9G20_SDRAMC_HSR 0x0c -#define AT91SAM9G20_SDRAMC_LPR 0x10 -#define AT91SAM9G20_SDRAMC_IER 0x14 -#define AT91SAM9G20_SDRAMC_IDR 0x18 -#define AT91SAM9G20_SDRAMC_IMR 0x1c -#define AT91SAM9G20_SDRAMC_ISR 0x20 -#define AT91SAM9G20_SDRAMC_MDR 0x24 - -#endif /* AT91SAM9G20REG_H_*/ - Index: head/sys/arm/at91/at91sam9g45.c =================================================================== --- head/sys/arm/at91/at91sam9g45.c +++ head/sys/arm/at91/at91sam9g45.c @@ -1,172 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2005 Olivier Houchard. All rights reserved. - * Copyright (c) 2010 Greg Ansley. All rights reserved. - * Copyright (c) 2012 Andrew Turner. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include - -#define _ARM32_BUS_DMA_PRIVATE -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Standard priority levels for the system. 0 is lowest and 7 is highest. - * These values are the ones Atmel uses for its Linux port - */ -static const int at91_irq_prio[32] = -{ - 7, /* Advanced Interrupt Controller */ - 7, /* System Peripherals */ - 1, /* Parallel IO Controller A */ - 1, /* Parallel IO Controller B */ - 1, /* Parallel IO Controller C */ - 1, /* Parallel IO Controller D and E */ - 0, - 5, /* USART 0 */ - 5, /* USART 1 */ - 5, /* USART 2 */ - 5, /* USART 3 */ - 0, /* Multimedia Card Interface 0 */ - 6, /* Two-Wire Interface 0 */ - 6, /* Two-Wire Interface 1 */ - 5, /* Serial Peripheral Interface 0 */ - 5, /* Serial Peripheral Interface 1 */ - 4, /* Serial Synchronous Controller 0 */ - 4, /* Serial Synchronous Controller 1 */ - 0, /* Timer Counter 0, 1, 2, 3, 4 and 5 */ - 0, /* Pulse Width Modulation Controller */ - 0, /* Touch Screen Controller */ - 0, /* DMA Controller */ - 2, /* USB Host High Speed port */ - 3, /* LCD Controller */ - 5, /* AC97 Controller */ - 3, /* Ethernet */ - 0, /* Image Sensor Interface */ - 2, /* USB Device High Speed port */ - 0, /* (reserved) */ - 0, /* Multimedia Card Interface 1 */ - 0, /* (reserved) */ - 0, /* Advanced Interrupt Controller IRQ0 */ -}; - -static const uint32_t at91_pio_base[] = { - AT91SAM9G45_PIOA_BASE, - AT91SAM9G45_PIOB_BASE, - AT91SAM9G45_PIOC_BASE, - AT91SAM9G45_PIOD_BASE, - AT91SAM9G45_PIOE_BASE, -}; - -#define DEVICE(_name, _id, _unit) \ - { \ - _name, _unit, \ - AT91SAM9G45_ ## _id ##_BASE, \ - AT91SAM9G45_ ## _id ## _SIZE, \ - AT91SAM9G45_IRQ_ ## _id \ - } - -static const struct cpu_devs at91_devs[] = -{ - DEVICE("at91_pmc", PMC, 0), - DEVICE("at91_wdt", WDT, 0), - DEVICE("at91_rst", RSTC, 0), - DEVICE("at91_pit", PIT, 0), - DEVICE("at91_pio", PIOA, 0), - DEVICE("at91_pio", PIOB, 1), - DEVICE("at91_pio", PIOC, 2), - DEVICE("at91_pio", PIOD, 3), - DEVICE("at91_pio", PIOE, 4), - DEVICE("at91_twi", TWI0, 0), - DEVICE("at91_twi", TWI1, 1), - DEVICE("at91_mci", HSMCI0, 0), - DEVICE("at91_mci", HSMCI1, 1), - DEVICE("uart", DBGU, 0), - DEVICE("uart", USART0, 1), - DEVICE("uart", USART1, 2), - DEVICE("uart", USART2, 3), - DEVICE("uart", USART3, 4), - DEVICE("spi", SPI0, 0), - DEVICE("spi", SPI1, 1), - DEVICE("ate", EMAC, 0), - DEVICE("macb", EMAC, 0), - DEVICE("nand", NAND, 0), - DEVICE("ohci", OHCI, 0), - { 0, 0, 0, 0, 0 } -}; - -static void -at91_clock_init(void) -{ - struct at91_pmc_clock *clk; - - /* Update USB host port clock info */ - clk = at91_pmc_clock_ref("uhpck"); - clk->pmc_mask = PMC_SCER_UHP_SAM9; - at91_pmc_clock_deref(clk); - - /* Each SOC has different PLL contraints */ - clk = at91_pmc_clock_ref("plla"); - clk->pll_min_in = SAM9G45_PLL_A_MIN_IN_FREQ; /* 2 MHz */ - clk->pll_max_in = SAM9G45_PLL_A_MAX_IN_FREQ; /* 32 MHz */ - clk->pll_min_out = SAM9G45_PLL_A_MIN_OUT_FREQ; /* 400 MHz */ - clk->pll_max_out = SAM9G45_PLL_A_MAX_OUT_FREQ; /* 800 MHz */ - clk->pll_mul_shift = SAM9G45_PLL_A_MUL_SHIFT; - clk->pll_mul_mask = SAM9G45_PLL_A_MUL_MASK; - clk->pll_div_shift = SAM9G45_PLL_A_DIV_SHIFT; - clk->pll_div_mask = SAM9G45_PLL_A_DIV_MASK; - clk->set_outb = at91_pmc_800mhz_plla_outb; - at91_pmc_clock_deref(clk); -} - -static struct at91_soc_data soc_data = { - .soc_delay = at91_pit_delay, - .soc_reset = at91_rst_cpu_reset, - .soc_clock_init = at91_clock_init, - .soc_irq_prio = at91_irq_prio, - .soc_children = at91_devs, - .soc_pio_base = at91_pio_base, - .soc_pio_count = nitems(at91_pio_base), -}; - -AT91_SOC(AT91_T_SAM9G45, &soc_data); Index: head/sys/arm/at91/at91sam9g45reg.h =================================================================== --- head/sys/arm/at91/at91sam9g45reg.h +++ head/sys/arm/at91/at91sam9g45reg.h @@ -1,295 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2009 Sylvestre Gallon. All rights reserved. - * Copyright (c) 2010 Greg Ansley. All rights reserved. - * Copyright (c) 2012 Andrew Turner. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef AT91SAM9G45REG_H_ -#define AT91SAM9G45REG_H_ - -/* Chip Specific limits */ -#define SAM9G45_PLL_A_MIN_IN_FREQ 2000000 /* 2 Mhz */ -#define SAM9G45_PLL_A_MAX_IN_FREQ 32000000 /* 32 Mhz */ -#define SAM9G45_PLL_A_MIN_OUT_FREQ 400000000 /* 400 Mhz */ -#define SAM9G45_PLL_A_MAX_OUT_FREQ 800000000 /* 800 Mhz */ -#define SAM9G45_PLL_A_MUL_SHIFT 16 -#define SAM9G45_PLL_A_MUL_MASK 0xFF -#define SAM9G45_PLL_A_DIV_SHIFT 0 -#define SAM9G45_PLL_A_DIV_MASK 0xFF - -/* - * Memory map, from datasheet : - * 0x00000000 - 0x0ffffffff : Internal Memories - * 0x10000000 - 0x1ffffffff : Chip Select 0 - * 0x20000000 - 0x2ffffffff : Chip Select 1 - * 0x30000000 - 0x3ffffffff : Chip Select 2 - * 0x40000000 - 0x4ffffffff : Chip Select 3 - * 0x50000000 - 0x5ffffffff : Chip Select 4 - * 0x60000000 - 0x6ffffffff : Chip Select 5 - * 0x70000000 - 0x7ffffffff : DDR SDRC 0 - * 0x80000000 - 0xeffffffff : Undefined (Abort) - * 0xf0000000 - 0xfffffffff : Peripherals - */ - -#define AT91_CHIPSELECT_0 0x10000000 -#define AT91_CHIPSELECT_1 0x20000000 -#define AT91_CHIPSELECT_2 0x30000000 -#define AT91_CHIPSELECT_3 0x40000000 -#define AT91_CHIPSELECT_4 0x50000000 -#define AT91_CHIPSELECT_5 0x60000000 - - -#define AT91SAM9G45_EMAC_BASE 0xffbc000 -#define AT91SAM9G45_EMAC_SIZE 0x4000 - -#define AT91SAM9G45_RSTC_BASE 0xffffd00 -#define AT91SAM9G45_RSTC_SIZE 0x10 - -/* USART*/ - -#define AT91SAM9G45_USART_SIZE 0x4000 -#define AT91SAM9G45_USART0_BASE 0xff8c000 -#define AT91SAM9G45_USART0_SIZE AT91SAM9G45_USART_SIZE -#define AT91SAM9G45_USART1_BASE 0xff90000 -#define AT91SAM9G45_USART1_SIZE AT91SAM9G45_USART_SIZE -#define AT91SAM9G45_USART2_BASE 0xff94000 -#define AT91SAM9G45_USART2_SIZE AT91SAM9G45_USART_SIZE -#define AT91SAM9G45_USART3_BASE 0xff98000 -#define AT91SAM9G45_USART3_SIZE AT91SAM9G45_USART_SIZE - -/*TC*/ -#define AT91SAM9G45_TC0_BASE 0xff7c000 -#define AT91SAM9G45_TC0_SIZE 0x4000 -#define AT91SAM9G45_TC0C0_BASE 0xff7c000 -#define AT91SAM9G45_TC0C1_BASE 0xff7c040 -#define AT91SAM9G45_TC0C2_BASE 0xff7c080 - -#define AT91SAM9G45_TC1_BASE 0xffd4000 -#define AT91SAM9G45_TC1_SIZE 0x4000 -#define AT91SAM9G45_TC1C0_BASE 0xffd4000 -#define AT91SAM9G45_TC1C1_BASE 0xffd4040 -#define AT91SAM9G45_TC1C2_BASE 0xffd4080 - -/*SPI*/ - -#define AT91SAM9G45_SPI0_BASE 0xffa48000 -#define AT91SAM9G45_SPI0_SIZE 0x4000 - -#define AT91SAM9G45_SPI1_BASE 0xffa8000 -#define AT91SAM9G45_SPI1_SIZE 0x4000 - -/* System Registers */ -#define AT91SAM9G45_SYS_BASE 0xffff000 -#define AT91SAM9G45_SYS_SIZE 0x1000 - -#define AT91SAM9G45_MATRIX_BASE 0xfffea00 -#define AT91SAM9G45_MATRIX_SIZE 0x200 - -#define AT91SAM9G45_DBGU_BASE 0xfffee00 -#define AT91SAM9G45_DBGU_SIZE 0x200 - -/* - * PIO - */ -#define AT91SAM9G45_PIOA_BASE 0xffff200 -#define AT91SAM9G45_PIOA_SIZE 0x200 -#define AT91SAM9G45_PIOB_BASE 0xffff400 -#define AT91SAM9G45_PIOB_SIZE 0x200 -#define AT91SAM9G45_PIOC_BASE 0xffff600 -#define AT91SAM9G45_PIOC_SIZE 0x200 -#define AT91SAM9G45_PIOD_BASE 0xffff800 -#define AT91SAM9G45_PIOD_SIZE 0x200 -#define AT91SAM9G45_PIOE_BASE 0xffffa00 -#define AT91SAM9G45_PIOE_SIZE 0x200 - -#define AT91SAM9G45_PMC_BASE 0xffffc00 -#define AT91SAM9G45_PMC_SIZE 0x100 - -/* IRQs : */ -/* - * 0: AIC - * 1: System peripheral (System timer, RTC, DBGU) - * 2: PIO Controller A - * 3: PIO Controller B - * 4: PIO Controller C - * 5: PIO Controller D/E - * 6: TRNG - * 7: USART 0 - * 8: USART 1 - * 9: USART 2 - * 10: USART 3 - * 11: Multimedia Card interface 0 - * 12: Two-wire interface 0 - * 13: Two-wire interface 1 - * 14: SPI 0 - * 15: SPI 1 - * 16: SSC 0 - * 17: SSC 1 - * 18: Timer Counter 0, 1, 2, 3, 4, 5 - * 19: PWM - * 20: Touch Screen ADC - * 21: DMA - * 22: USB Host port - * 23: LCD - * 24: AC97 - * 25: EMAC - * 26: Image Sensor Interface - * 27: USB Device High Speed - * 28: - - * 29: Multimedia Card interface 1 - * 30: Reserved - * 31: AIC - */ - -#define AT91SAM9G45_IRQ_SYSTEM 1 -#define AT91SAM9G45_IRQ_PIOA 2 -#define AT91SAM9G45_IRQ_PIOB 3 -#define AT91SAM9G45_IRQ_PIOC 4 -#define AT91SAM9G45_IRQ_PIODE 5 -#define AT91SAM9G45_IRQ_TRNG 6 -#define AT91SAM9G45_IRQ_USART0 7 -#define AT91SAM9G45_IRQ_USART1 8 -#define AT91SAM9G45_IRQ_USART2 9 -#define AT91SAM9G45_IRQ_USART3 10 -#define AT91SAM9G45_IRQ_HSMCI0 11 -#define AT91SAM9G45_IRQ_TWI0 12 -#define AT91SAM9G45_IRQ_TWI1 13 -#define AT91SAM9G45_IRQ_SPI0 14 -#define AT91SAM9G45_IRQ_SPI1 15 -#define AT91SAM9G45_IRQ_SSC0 16 -#define AT91SAM9G45_IRQ_SSC1 17 -#define AT91SAM9G45_IRQ_TC0_TC5 18 -#define AT91SAM9G45_IRQ_PWM 19 -#define AT91SAM9G45_IRQ_TSADCC 20 -#define AT91SAM9G45_IRQ_DMA 21 -#define AT91SAM9G45_IRQ_UHP 22 -#define AT91SAM9G45_IRQ_LCDC 23 -#define AT91SAM9G45_IRQ_AC97C 24 -#define AT91SAM9G45_IRQ_EMAC 25 -#define AT91SAM9G45_IRQ_ISI 26 -#define AT91SAM9G45_IRQ_UDPHS 27 -/* Reserved 28 */ -#define AT91SAM9G45_IRQ_HSMCI1 29 -/* Reserved 30 */ -#define AT91SAM9G45_IRQ_AICBASE 31 - -/* Alias */ -#define AT91SAM9G45_IRQ_DBGU AT91SAM9G45_IRQ_SYSTEM -#define AT91SAM9G45_IRQ_PMC AT91SAM9G45_IRQ_SYSTEM -#define AT91SAM9G45_IRQ_WDT AT91SAM9G45_IRQ_SYSTEM -#define AT91SAM9G45_IRQ_PIT AT91SAM9G45_IRQ_SYSTEM -#define AT91SAM9G45_IRQ_RSTC AT91SAM9G45_IRQ_SYSTEM -#define AT91SAM9G45_IRQ_PIOD AT91SAM9G45_IRQ_PIODE -#define AT91SAM9G45_IRQ_PIOE AT91SAM9G45_IRQ_PIODE -#define AT91SAM9G45_IRQ_OHCI AT91SAM9G45_IRQ_UHP -#define AT91SAM9G45_IRQ_TC0 AT91SAM9G45_IRQ_TC0_TC5 -#define AT91SAM9G45_IRQ_TC1 AT91SAM9G45_IRQ_TC0_TC5 -#define AT91SAM9G45_IRQ_TC2 AT91SAM9G45_IRQ_TC0_TC5 -#define AT91SAM9G45_IRQ_TC3 AT91SAM9G45_IRQ_TC0_TC5 -#define AT91SAM9G45_IRQ_TC4 AT91SAM9G45_IRQ_TC0_TC5 -#define AT91SAM9G45_IRQ_TC5 AT91SAM9G45_IRQ_TC0_TC5 -#define AT91SAM9G45_IRQ_NAND (-1) - -#define AT91SAM9G45_AIC_BASE 0xffff000 -#define AT91SAM9G45_AIC_SIZE 0x200 - -/* Timer */ - -#define AT91SAM9G45_WDT_BASE 0xffffd40 -#define AT91SAM9G45_WDT_SIZE 0x10 - -#define AT91SAM9G45_PIT_BASE 0xffffd30 -#define AT91SAM9G45_PIT_SIZE 0x10 - -#define AT91SAM9G45_SMC_BASE 0xfffe800 -#define AT91SAM9G45_SMC_SIZE 0x200 - -#define AT91SAM9G45_HSMCI0_BASE 0xff80000 -#define AT91SAM9G45_HSMCI0_SIZE 0x4000 - -#define AT91SAM9G45_HSMCI1_BASE 0xffd0000 -#define AT91SAM9G45_HSMCI1_SIZE 0x4000 - -#define AT91SAM9G45_TWI0_BASE 0xff84000 -#define AT91SAM9G45_TWI0_SIZE 0x4000 -#define AT91SAM9G45_TWI1_BASE 0xff88000 -#define AT91SAM9G45_TWI1_SIZE 0x4000 - -/* XXX Needs to be carfully coordinated with - * other * soc's so phyical and vm address - * mapping are unique. XXX - */ -#define AT91SAM9G45_OHCI_VA_BASE 0xdfb00000 -#define AT91SAM9G45_OHCI_BASE 0x00700000 -#define AT91SAM9G45_OHCI_SIZE 0x00100000 - -#define AT91SAM9G45_NAND_VA_BASE 0xe0000000 -#define AT91SAM9G45_NAND_BASE 0x40000000 -#define AT91SAM9G45_NAND_SIZE 0x10000000 - - -/* DDRSDRC */ -#define AT91SAM9G45_DDRSDRC1_BASE 0xfffea00 -#define AT91SAM9G45_DDRSDRC0_BASE 0xfffe600 -#define AT91SAM9G45_DDRSDRC_MR 0x00 -#define AT91SAM9G45_DDRSDRC_TR 0x04 -#define AT91SAM9G45_DDRSDRC_CR 0x08 -#define AT91SAM9G45_DDRSDRC_CR_NC_8 0x0 -#define AT91SAM9G45_DDRSDRC_CR_NC_9 0x1 -#define AT91SAM9G45_DDRSDRC_CR_NC_10 0x2 -#define AT91SAM9G45_DDRSDRC_CR_NC_11 0x3 -#define AT91SAM9G45_DDRSDRC_CR_NC_MASK 0x00000003 -#define AT91SAM9G45_DDRSDRC_CR_NR_11 0x0 -#define AT91SAM9G45_DDRSDRC_CR_NR_12 0x4 -#define AT91SAM9G45_DDRSDRC_CR_NR_13 0x8 -#define AT91SAM9G45_DDRSDRC_CR_NR_14 0xc -#define AT91SAM9G45_DDRSDRC_CR_NR_MASK 0x0000000c -#define AT91SAM9G45_DDRSDRC_TPR0 0x0c -#define AT91SAM9G45_DDRSDRC_TPR1 0x10 -#define AT91SAM9G45_DDRSDRC_TPR2 0x14 -/* Reserved 0x18 */ -#define AT91SAM9G45_DDRSDRC_LPR 0x1c -#define AT91SAM9G45_DDRSDRC_MDR 0x20 -#define AT91SAM9G45_DDRSDRC_MDR_SDR 0x0 -#define AT91SAM9G45_DDRSDRC_MDR_LPSDR 0x1 -#define AT91SAM9G45_DDRSDRC_MDR_LPDDR1 0x3 -#define AT91SAM9G45_DDRSDRC_MDR_DDR2 0x6 -#define AT91SAM9G45_DDRSDRC_MDR_MASK 0x00000007 -#define AT91SAM9G45_DDRSDRC_MDR_DBW_16 0x10 -#define AT91SAM9G45_DDRSDRC_DLL 0x24 -#define AT91SAM9G45_DDRSDRC_HSR 0x2c -#define AT91SAM9G45_DDRSDRC_DELAY1R 0x40 -#define AT91SAM9G45_DDRSDRC_DELAY2R 0x44 -#define AT91SAM9G45_DDRSDRC_DELAY3R 0x48 -#define AT91SAM9G45_DDRSDRC_DELAY4R 0x4c -/* Reserved 0x50 - 0xe0 */ -#define AT91SAM9G45_DDRSDRC_WPMR 0xe4 -#define AT91SAM9G45_DDRSDRC_WPSR 0xe8 - -#endif /* AT91SAM9G45REG_H_*/ - Index: head/sys/arm/at91/at91sam9x5.c =================================================================== --- head/sys/arm/at91/at91sam9x5.c +++ head/sys/arm/at91/at91sam9x5.c @@ -1,189 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2005 Olivier Houchard. All rights reserved. - * Copyright (c) 2010 Greg Ansley. All rights reserved. - * Copyright (c) 2012 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Standard priority levels for the system. 0 is lowest and 7 is highest. - * These values are the ones Atmel uses for its Linux port - */ -static const int at91_irq_prio[32] = -{ - 7, /* Advanced Interrupt Controller (FIQ) */ - 7, /* System Peripherals */ - 1, /* Parallel IO Controller A and B */ - 1, /* Parallel IO Controller C and D */ - 4, /* Soft Modem */ - 5, /* USART 0 */ - 5, /* USART 1 */ - 5, /* USART 2 */ - 5, /* USART 3 */ - 6, /* Two-Wire Interface 0 */ - 6, /* Two-Wire Interface 1 */ - 6, /* Two-Wire Interface 2 */ - 0, /* Multimedia Card Interface 0 */ - 5, /* Serial Peripheral Interface 0 */ - 5, /* Serial Peripheral Interface 1 */ - 5, /* UART 0 */ - 5, /* UART 1 */ - 0, /* Timer Counter 0, 1, 2, 3, 4 and 5 */ - 0, /* Pulse Width Modulation Controller */ - 0, /* ADC Controller */ - 0, /* DMA Controller 0 */ - 0, /* DMA Controller 1 */ - 2, /* USB Host High Speed port */ - 2, /* USB Device High speed port */ - 3, /* Ethernet MAC 0 */ - 3, /* LDC Controller or Image Sensor Interface */ - 0, /* Multimedia Card Interface 1 */ - 3, /* Ethernet MAC 1 */ - 4, /* Synchronous Serial Interface */ - 4, /* CAN Controller 0 */ - 4, /* CAN Controller 1 */ - 0, /* Advanced Interrupt Controller (IRQ0) */ -}; - -static const uint32_t at91_pio_base[] = { - AT91SAM9X25_PIOA_BASE, - AT91SAM9X25_PIOB_BASE, - AT91SAM9X25_PIOC_BASE, - AT91SAM9X25_PIOD_BASE, -}; - -#define DEVICE(_name, _id, _unit) \ - { \ - _name, _unit, \ - AT91SAM9X25_ ## _id ##_BASE, \ - AT91SAM9X25_ ## _id ## _SIZE, \ - AT91SAM9X25_IRQ_ ## _id \ - } - -static const struct cpu_devs at91_devs[] = -{ - DEVICE("at91_aic", AIC, 0), - DEVICE("at91_pmc", PMC, 0), - DEVICE("at91_wdt", WDT, 0), - DEVICE("at91_rst", RSTC, 0), - DEVICE("at91_pit", PIT, 0), - DEVICE("at91_pio", PIOA, 0), - DEVICE("at91_pio", PIOB, 1), - DEVICE("at91_pio", PIOC, 2), - DEVICE("at91_pio", PIOD, 3), - DEVICE("at91_twi", TWI0, 0), - DEVICE("at91_twi", TWI1, 1), - DEVICE("at91_twi", TWI2, 2), - DEVICE("at91_mci", HSMCI0, 0), - DEVICE("at91_mci", HSMCI1, 1), - DEVICE("uart", DBGU, 0), - DEVICE("uart", USART0, 1), - DEVICE("uart", USART1, 2), - DEVICE("uart", USART2, 3), - DEVICE("uart", USART3, 4), - DEVICE("spi", SPI0, 0), - DEVICE("spi", SPI1, 1), - DEVICE("macb", EMAC0, 0), - DEVICE("macb", EMAC1, 0), - DEVICE("nand", NAND, 0), - DEVICE("ohci", OHCI, 0), - DEVICE("ehci", EHCI, 0), - { 0, 0, 0, 0, 0 } -}; - -static void -at91_clock_init(void) -{ - struct at91_pmc_clock *clk; - - /* Update USB device port clock info */ - clk = at91_pmc_clock_ref("udpck"); - clk->pmc_mask = PMC_SCER_UDP_SAM9; - at91_pmc_clock_deref(clk); - - /* Update USB host port clock info */ - clk = at91_pmc_clock_ref("uhpck"); - clk->pmc_mask = PMC_SCER_UHP_SAM9; - at91_pmc_clock_deref(clk); - - /* Each SOC has different PLL contraints */ - clk = at91_pmc_clock_ref("plla"); - clk->pll_min_in = SAM9X25_PLL_A_MIN_IN_FREQ; /* 2 MHz */ - clk->pll_max_in = SAM9X25_PLL_A_MAX_IN_FREQ; /* 32 MHz */ - clk->pll_min_out = SAM9X25_PLL_A_MIN_OUT_FREQ; /* 400 MHz */ - clk->pll_max_out = SAM9X25_PLL_A_MAX_OUT_FREQ; /* 800 MHz */ - clk->pll_mul_shift = SAM9X25_PLL_A_MUL_SHIFT; - clk->pll_mul_mask = SAM9X25_PLL_A_MUL_MASK; - clk->pll_div_shift = SAM9X25_PLL_A_DIV_SHIFT; - clk->pll_div_mask = SAM9X25_PLL_A_DIV_MASK; - clk->set_outb = at91_pmc_800mhz_plla_outb; - at91_pmc_clock_deref(clk); - - clk = at91_pmc_clock_ref("pllb"); - clk->pll_min_in = SAM9X25_PLL_B_MIN_IN_FREQ; /* 2 MHz */ - clk->pll_max_in = SAM9X25_PLL_B_MAX_IN_FREQ; /* 32 MHz */ - clk->pll_min_out = SAM9X25_PLL_B_MIN_OUT_FREQ; /* 30 MHz */ - clk->pll_max_out = SAM9X25_PLL_B_MAX_OUT_FREQ; /* 100 MHz */ - clk->pll_mul_shift = SAM9X25_PLL_B_MUL_SHIFT; - clk->pll_mul_mask = SAM9X25_PLL_B_MUL_MASK; - clk->pll_div_shift = SAM9X25_PLL_B_DIV_SHIFT; - clk->pll_div_mask = SAM9X25_PLL_B_DIV_MASK; - clk->set_outb = at91_pmc_800mhz_pllb_outb; - at91_pmc_clock_deref(clk); -} - -static struct at91_soc_data soc_data = { - .soc_delay = at91_pit_delay, - .soc_reset = at91_rst_cpu_reset, - .soc_clock_init = at91_clock_init, - .soc_irq_prio = at91_irq_prio, - .soc_children = at91_devs, - .soc_pio_base = at91_pio_base, - .soc_pio_count = nitems(at91_pio_base), -}; - -AT91_SOC_SUB(AT91_T_SAM9X5, AT91_ST_SAM9X25, &soc_data); Index: head/sys/arm/at91/at91sam9x5reg.h =================================================================== --- head/sys/arm/at91/at91sam9x5reg.h +++ head/sys/arm/at91/at91sam9x5reg.h @@ -1,317 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2009 Sylvestre Gallon. All rights reserved. - * Copyright (c) 2010 Greg Ansley. All rights reserved. - * Copyright (c) 2012 M. Warener Losh. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef AT91SAM9X5REG_H_ -#define AT91SAM9X5REG_H_ - -#ifndef AT91SAM9X25_MASTER_CLOCK -#define AT91SAM9X25_MASTER_CLOCK ((18432000 * 43)/6) -#endif - -/* Chip Specific limits */ -#define SAM9X25_PLL_A_MIN_IN_FREQ 2000000 /* 2 Mhz */ -#define SAM9X25_PLL_A_MAX_IN_FREQ 32000000 /* 32 Mhz */ -#define SAM9X25_PLL_A_MIN_OUT_FREQ 400000000 /* 400 Mhz */ -#define SAM9X25_PLL_A_MAX_OUT_FREQ 800000000 /* 800 Mhz */ -#define SAM9X25_PLL_A_MUL_SHIFT 16 -#define SAM9X25_PLL_A_MUL_MASK 0xFF -#define SAM9X25_PLL_A_DIV_SHIFT 0 -#define SAM9X25_PLL_A_DIV_MASK 0xFF - -#define SAM9X25_PLL_B_MIN_IN_FREQ 2000000 /* 2 Mhz */ -#define SAM9X25_PLL_B_MAX_IN_FREQ 32000000 /* 32 Mhz */ -#define SAM9X25_PLL_B_MIN_OUT_FREQ 30000000 /* 30 Mhz */ -#define SAM9X25_PLL_B_MAX_OUT_FREQ 100000000 /* 100 Mhz */ -#define SAM9X25_PLL_B_MUL_SHIFT 16 -#define SAM9X25_PLL_B_MUL_MASK 0x3F -#define SAM9X25_PLL_B_DIV_SHIFT 0 -#define SAM9X25_PLL_B_DIV_MASK 0xFF - -/* - * Memory map, from datasheet : - * 0x00000000 - 0x0ffffffff : Internal Memories - * 0x10000000 - 0x1ffffffff : Chip Select 0 - * 0x20000000 - 0x2ffffffff : Chip Select 1 DDR2/LPDDR/SDR/LPSDR - * 0x30000000 - 0x3ffffffff : Chip Select 2 - * 0x40000000 - 0x4ffffffff : Chip Select 3 NAND Flash - * 0x50000000 - 0x5ffffffff : Chip Select 4 - * 0x60000000 - 0x6ffffffff : Chip Select 5 - * 0x70000000 - 0xeffffffff : Undefined (Abort) - * 0xf0000000 - 0xfffffffff : Peripherals - */ - -#define AT91_CHIPSELECT_0 0x10000000 -#define AT91_CHIPSELECT_1 0x20000000 -#define AT91_CHIPSELECT_2 0x30000000 -#define AT91_CHIPSELECT_3 0x40000000 -#define AT91_CHIPSELECT_4 0x50000000 -#define AT91_CHIPSELECT_5 0x60000000 - -#define AT91SAM9X25_EMAC_SIZE 0x4000 -#define AT91SAM9X25_EMAC0_BASE 0x802c000 -#define AT91SAM9X25_EMAC0_SIZE AT91SAM9X25_EMAC_SIZE -#define AT91SAM9X25_EMAC1_BASE 0x8030000 -#define AT91SAM9X25_EMAC1_SIZE AT91SAM9X25_EMAC_SIZE - -#define AT91SAM9X25_RSTC_BASE 0xffffe00 -#define AT91SAM9X25_RSTC_SIZE 0x10 - -/* USART*/ - -#define AT91SAM9X25_USART_SIZE 0x4000 -#define AT91SAM9X25_USART0_BASE 0x801c000 -#define AT91SAM9X25_USART0_PDC 0x801c100 -#define AT91SAM9X25_USART0_SIZE AT91SAM9X25_USART_SIZE -#define AT91SAM9X25_USART1_BASE 0x8020000 -#define AT91SAM9X25_USART1_PDC 0x8020100 -#define AT91SAM9X25_USART1_SIZE AT91SAM9X25_USART_SIZE -#define AT91SAM9X25_USART2_BASE 0x8024000 -#define AT91SAM9X25_USART2_PDC 0x8024100 -#define AT91SAM9X25_USART2_SIZE AT91SAM9X25_USART_SIZE -#define AT91SAM9X25_USART3_BASE 0x8028000 -#define AT91SAM9X25_USART3_PDC 0x8028100 -#define AT91SAM9X25_USART3_SIZE AT91SAM9X25_USART_SIZE - -/*TC*/ -#define AT91SAM9X25_TC0_BASE 0x8008000 -#define AT91SAM9X25_TC0_SIZE 0x4000 -#define AT91SAM9X25_TC0C0_BASE 0x8008000 -#define AT91SAM9X25_TC0C1_BASE 0x8008040 -#define AT91SAM9X25_TC0C2_BASE 0x8008080 - -#define AT91SAM9X25_TC1_BASE 0x800c000 -#define AT91SAM9X25_TC1_SIZE 0x4000 - -/*SPI*/ - -#define AT91SAM9X25_SPI0_BASE 0x0000000 - -#define AT91SAM9X25_SPI0_SIZE 0x4000 - -#define AT91SAM9X25_SPI1_BASE 0x0004000 -#define AT91SAM9X25_SPI1_SIZE 0x4000 - -/* System Registers */ -#define AT91SAM9X25_SYS_BASE 0xffff000 -#define AT91SAM9X25_SYS_SIZE 0x1000 - -#define AT91SAM9X25_MATRIX_BASE 0xfffde00 -#define AT91SAM9X25_MATRIX_SIZE 0x200 - -#define AT91SAM9X25_DBGU_BASE 0xffff200 -#define AT91SAM9X25_DBGU_SIZE 0x200 - -/* - * PIO - */ -#define AT91SAM9X25_PIOA_BASE 0xffff400 -#define AT91SAM9X25_PIOA_SIZE 0x200 -#define AT91SAM9X25_PIOB_BASE 0xffff600 -#define AT91SAM9X25_PIOB_SIZE 0x200 -#define AT91SAM9X25_PIOC_BASE 0xffff800 -#define AT91SAM9X25_PIOC_SIZE 0x200 -#define AT91SAM9X25_PIOD_BASE 0xffffa00 -#define AT91SAM9X25_PIOD_SIZE 0x200 - -#define AT91RM92_PMC_BASE 0xffffc00 -#define AT91RM92_PMC_SIZE 0x100 -/* IRQs : - * 0: AIC - * 1: System peripheral (System timer, RTC, DBGU) - * 2: PIO Controller A,B - * 3: PIO Controller C,D - * 4: SMD Soft Modem - * 5: USART 0 - * 6: USART 1 - * 7: USART 2 - * 8: USART 3 - * 9: Two-wire interface - * 10: Two-wire interface - * 11: Two-wire interface - * 12: HSMCI Interface - * 13: SPI 0 - * 14: SPI 1 - * 15: UART0 - * 16: UART1 - * 17: Timer Counter 0,1 - * 18: PWM - * 19: ADC - * 20: DMAC 0 - * 21: DMAC 1 - * 22: UHPHS - USB Host controller - * 23: UDPHS - USB Device Controller - * 24: EMAC0 - * 25: LCD controller or Image Sensor Interface - * 26: HSMCI1 - * 27: EMAC1 - * 28: SSC - * 29: CAN0 - * 30: CAN1 - * 31: AIC IRQ0 - */ - -#define AT91SAM9X25_IRQ_AIC 0 -#define AT91SAM9X25_IRQ_SYSTEM 1 -#define AT91SAM9X25_IRQ_PIOAB 2 -#define AT91SAM9X25_IRQ_PIOCD 3 -#define AT91SAM9X25_IRQ_SMD 4 -#define AT91SAM9X25_IRQ_USART0 5 -#define AT91SAM9X25_IRQ_USART1 6 -#define AT91SAM9X25_IRQ_USART2 7 -#define AT91SAM9X25_IRQ_USART3 8 -#define AT91SAM9X25_IRQ_TWI0 9 -#define AT91SAM9X25_IRQ_TWI1 10 -#define AT91SAM9X25_IRQ_TWI2 11 -#define AT91SAM9X25_IRQ_HSMCI0 12 -#define AT91SAM9X25_IRQ_SPI0 13 -#define AT91SAM9X25_IRQ_SPI1 14 -#define AT91SAM9X25_IRQ_UART0 15 -#define AT91SAM9X25_IRQ_UART1 16 -#define AT91SAM9X25_IRQ_TC01 17 -#define AT91SAM9X25_IRQ_PWM 18 -#define AT91SAM9X25_IRQ_ADC 19 -#define AT91SAM9X25_IRQ_DMAC0 20 -#define AT91SAM9X25_IRQ_DMAC1 21 -#define AT91SAM9X25_IRQ_UHPHS 22 -#define AT91SAM9X25_IRQ_UDPHS 23 -#define AT91SAM9X25_IRQ_EMAC0 24 -#define AT91SAM9X25_IRQ_HSMCI1 26 -#define AT91SAM9X25_IRQ_EMAC1 27 -#define AT91SAM9X25_IRQ_SSC 28 -#define AT91SAM9X25_IRQ_CAN0 29 -#define AT91SAM9X25_IRQ_CAN1 30 -#define AT91SAM9X25_IRQ_AICBASE 31 - -/* Alias */ -#define AT91SAM9X25_IRQ_DBGU AT91SAM9X25_IRQ_SYSTEM -#define AT91SAM9X25_IRQ_PMC AT91SAM9X25_IRQ_SYSTEM -#define AT91SAM9X25_IRQ_WDT AT91SAM9X25_IRQ_SYSTEM -#define AT91SAM9X25_IRQ_PIT AT91SAM9X25_IRQ_SYSTEM -#define AT91SAM9X25_IRQ_RSTC AT91SAM9X25_IRQ_SYSTEM -#define AT91SAM9X25_IRQ_OHCI AT91SAM9X25_IRQ_UHPHS -#define AT91SAM9X25_IRQ_EHCI AT91SAM9X25_IRQ_UHPHS -#define AT91SAM9X25_IRQ_PIOA AT91SAM9X25_IRQ_PIOAB -#define AT91SAM9X25_IRQ_PIOB AT91SAM9X25_IRQ_PIOAB -#define AT91SAM9X25_IRQ_PIOC AT91SAM9X25_IRQ_PIOCD -#define AT91SAM9X25_IRQ_PIOD AT91SAM9X25_IRQ_PIOCD -#define AT91SAM9X25_IRQ_NAND (-1) - -#define AT91SAM9X25_AIC_BASE 0xffff000 -#define AT91SAM9X25_AIC_SIZE 0x200 - -/* Timer */ - -#define AT91SAM9X25_WDT_BASE 0xffffd40 -#define AT91SAM9X25_WDT_SIZE 0x10 - -#define AT91SAM9X25_PIT_BASE 0xffffd30 -#define AT91SAM9X25_PIT_SIZE 0x10 - -#define AT91SAM9X25_SMC_BASE 0xfffea00 -#define AT91SAM9X25_SMC_SIZE 0x200 - -#define AT91SAM9X25_PMC_BASE 0xffffc00 -#define AT91SAM9X25_PMC_SIZE 0x100 - -#define AT91SAM9X25_UDPHS_BASE 0x803c000 -#define AT91SAM9X25_UDPHS_SIZE 0x4000 - -#define AT91SAM9X25_HSMCI_SIZE 0x4000 -#define AT91SAM9X25_HSMCI0_BASE 0x0008000 -#define AT91SAM9X25_HSMCI0_SIZE AT91SAM9X25_HSMCI_SIZE -#define AT91SAM9X25_HSMCI1_BASE 0x000c000 -#define AT91SAM9X25_HSMCI1_SIZE AT91SAM9X25_HSMCI_SIZE - -#define AT91SAM9X25_TWI_SIZE 0x4000 -#define AT91SAM9X25_TWI0_BASE 0xffaC000 -#define AT91SAM9X25_TWI0_SIZE AT91SAM9X25_TWI_SIZE -#define AT91SAM9X25_TWI1_BASE 0xffaC000 -#define AT91SAM9X25_TWI1_SIZE AT91SAM9X25_TWI_SIZE -#define AT91SAM9X25_TWI2_BASE 0xffaC000 -#define AT91SAM9X25_TWI2_SIZE AT91SAM9X25_TWI_SIZE - -/* XXX Needs to be carfully coordinated with - * other * soc's so phyical and vm address - * mapping are unique. XXX - */ -#define AT91SAM9X25_OHCI_BASE 0xdfc00000 /* SAME as 9c40 */ -#define AT91SAM9X25_OHCI_PA_BASE 0x00600000 -#define AT91SAM9X25_OHCI_SIZE 0x00100000 - -#define AT91SAM9X25_EHCI_BASE 0xdfd00000 -#define AT91SAM9X25_EHCI_PA_BASE 0x00700000 -#define AT91SAM9X25_EHCI_SIZE 0x00100000 - -#define AT91SAM9X25_NAND_BASE 0xe0000000 -#define AT91SAM9X25_NAND_PA_BASE 0x40000000 -#define AT91SAM9X25_NAND_SIZE 0x10000000 - - -/* SDRAMC */ -#define AT91SAM9X25_SDRAMC_BASE 0xfffea00 /* SAME as SMC? */ -#define AT91SAM9X25_SDRAMC_MR 0x00 -#define AT91SAM9X25_SDRAMC_MR_MODE_NORMAL 0 -#define AT91SAM9X25_SDRAMC_MR_MODE_NOP 1 -#define AT91SAM9X25_SDRAMC_MR_MODE_PRECHARGE 2 -#define AT91SAM9X25_SDRAMC_MR_MODE_LOAD_MODE_REGISTER 3 -#define AT91SAM9X25_SDRAMC_MR_MODE_REFRESH 4 -#define AT91SAM9X25_SDRAMC_TR 0x04 -#define AT91SAM9X25_SDRAMC_CR 0x08 -#define AT91SAM9X25_SDRAMC_CR_NC_8 0x0 -#define AT91SAM9X25_SDRAMC_CR_NC_9 0x1 -#define AT91SAM9X25_SDRAMC_CR_NC_10 0x2 -#define AT91SAM9X25_SDRAMC_CR_NC_11 0x3 -#define AT91SAM9X25_SDRAMC_CR_NC_MASK 0x00000003 -#define AT91SAM9X25_SDRAMC_CR_NR_11 0x0 -#define AT91SAM9X25_SDRAMC_CR_NR_12 0x4 -#define AT91SAM9X25_SDRAMC_CR_NR_13 0x8 -#define AT91SAM9X25_SDRAMC_CR_NR_RES 0xc -#define AT91SAM9X25_SDRAMC_CR_NR_MASK 0x0000000c -#define AT91SAM9X25_SDRAMC_CR_NB_2 0x00 -#define AT91SAM9X25_SDRAMC_CR_NB_4 0x10 -#define AT91SAM9X25_SDRAMC_CR_DBW_16 0x80 -#define AT91SAM9X25_SDRAMC_CR_NB_MASK 0x00000010 -#define AT91SAM9X25_SDRAMC_CR_NCAS_MASK 0x00000060 -#define AT91SAM9X25_SDRAMC_CR_TWR_MASK 0x00000780 -#define AT91SAM9X25_SDRAMC_CR_TRC_MASK 0x00007800 -#define AT91SAM9X25_SDRAMC_CR_TRP_MASK 0x00078000 -#define AT91SAM9X25_SDRAMC_CR_TRCD_MASK 0x00780000 -#define AT91SAM9X25_SDRAMC_CR_TRAS_MASK 0x07800000 -#define AT91SAM9X25_SDRAMC_CR_TXSR_MASK 0x78000000 -#define AT91SAM9X25_SDRAMC_HSR 0x0c -#define AT91SAM9X25_SDRAMC_LPR 0x10 -#define AT91SAM9X25_SDRAMC_IER 0x14 -#define AT91SAM9X25_SDRAMC_IDR 0x18 -#define AT91SAM9X25_SDRAMC_IMR 0x1c -#define AT91SAM9X25_SDRAMC_ISR 0x20 -#define AT91SAM9X25_SDRAMC_MDR 0x24 - -#endif /* AT91SAM9X5REG_H_*/ Index: head/sys/arm/at91/at91soc.h =================================================================== --- head/sys/arm/at91/at91soc.h +++ head/sys/arm/at91/at91soc.h @@ -1,60 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2012 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef _ARM_AT91_AT91SOC_H_ -#define _ARM_AT91_AT91SOC_H_ - -#include - -struct at91_soc { - enum at91_soc_type soc_type; /* Family of mail type of SoC */ - enum at91_soc_subtype soc_subtype; /* More specific soc, if any */ - struct at91_soc_data *soc_data; -}; - -// Make varadic -#define AT91_SOC(type, data) \ - static struct at91_soc this_soc = { \ - .soc_type = type, \ - .soc_subtype = AT91_ST_ANY, \ - .soc_data = data, \ - }; \ - DATA_SET(at91_socs, this_soc); - -#define AT91_SOC_SUB(type, subtype, data) \ - static struct at91_soc this_soc = { \ - .soc_type = type, \ - .soc_subtype = subtype, \ - .soc_data = data, \ - }; \ - DATA_SET(at91_socs, this_soc); - -struct at91_soc_data *at91_match_soc(enum at91_soc_type, enum at91_soc_subtype); - -#endif /* _ARM_AT91_AT91SOC_H_ */ Index: head/sys/arm/at91/at91soc.c =================================================================== --- head/sys/arm/at91/at91soc.c +++ head/sys/arm/at91/at91soc.c @@ -1,53 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2012 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include - -#include -#include - -SET_DECLARE(at91_socs, const struct at91_soc); - -struct at91_soc_data * -at91_match_soc(enum at91_soc_type type, enum at91_soc_subtype subtype) -{ - const struct at91_soc **socp; - - SET_FOREACH(socp, at91_socs) { - if ((*socp)->soc_type != type) - continue; - if ((*socp)->soc_subtype != AT91_ST_ANY && - (*socp)->soc_subtype != subtype) - continue; - return (*socp)->soc_data; - } - return NULL; -} Index: head/sys/arm/at91/at91var.h =================================================================== --- head/sys/arm/at91/at91var.h +++ head/sys/arm/at91/at91var.h @@ -1,175 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2005 Olivier Houchard. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef _AT91VAR_H_ -#define _AT91VAR_H_ - -#include -#include - -#include - -struct at91_softc { - device_t dev; - bus_space_tag_t sc_st; - bus_space_handle_t sc_sh; - bus_space_handle_t sc_aic_sh; - struct rman sc_irq_rman; - struct rman sc_mem_rman; -}; - -struct at91_ivar { - struct resource_list resources; -}; - -struct cpu_devs -{ - const char *name; - int unit; - bus_addr_t mem_base; - bus_size_t mem_len; - int irq0; - int irq1; - int irq2; - const char *parent_clk; -}; - -enum at91_soc_type { - AT91_T_NONE = 0, - AT91_T_CAP9, - AT91_T_RM9200, - AT91_T_SAM9260, - AT91_T_SAM9261, - AT91_T_SAM9263, - AT91_T_SAM9G10, - AT91_T_SAM9G20, - AT91_T_SAM9G45, - AT91_T_SAM9N12, - AT91_T_SAM9RL, - AT91_T_SAM9X5, -}; - -enum at91_soc_subtype { - AT91_ST_ANY = -1, /* Match any type */ - AT91_ST_NONE = 0, - /* AT91RM9200 */ - AT91_ST_RM9200_BGA, - AT91_ST_RM9200_PQFP, - /* AT91SAM9260 */ - AT91_ST_SAM9XE, - /* AT91SAM9G45 */ - AT91_ST_SAM9G45, - AT91_ST_SAM9M10, - AT91_ST_SAM9G46, - AT91_ST_SAM9M11, - /* AT91SAM9X5 */ - AT91_ST_SAM9G15, - AT91_ST_SAM9G25, - AT91_ST_SAM9G35, - AT91_ST_SAM9X25, - AT91_ST_SAM9X35, -}; - -enum at91_soc_family { - AT91_FAMILY_SAM9 = 0x19, - AT91_FAMILY_SAM9XE = 0x29, - AT91_FAMILY_RM92 = 0x92, -}; - -#define AT91_SOC_NAME_MAX 50 - -typedef void (*DELAY_t)(int); -typedef void (*cpu_reset_t)(void); -typedef void (*clk_init_t)(void); - -struct at91_soc_data { - DELAY_t soc_delay; /* SoC specific delay function */ - cpu_reset_t soc_reset; /* SoC specific reset function */ - clk_init_t soc_clock_init; /* SoC specific clock init function */ - const int *soc_irq_prio; /* SoC specific IRQ priorities */ - const struct cpu_devs *soc_children; /* SoC specific children list */ - const uint32_t *soc_pio_base; /* SoC specific PIO base registers */ - size_t soc_pio_count; /* Count of PIO units (not pins) in SoC */ -}; - -struct at91_soc_info { - enum at91_soc_type type; - enum at91_soc_subtype subtype; - enum at91_soc_family family; - uint32_t cidr; - uint32_t exid; - char name[AT91_SOC_NAME_MAX]; - uint32_t dbgu_base; - struct at91_soc_data *soc_data; -}; - -extern struct at91_soc_info soc_info; - -static inline int at91_is_rm92(void); -static inline int at91_is_sam9(void); -static inline int at91_is_sam9xe(void); -static inline int at91_cpu_is(u_int cpu); - -static inline int -at91_is_rm92(void) -{ - - return (soc_info.type == AT91_T_RM9200); -} - -static inline int -at91_is_sam9(void) -{ - - return (soc_info.family == AT91_FAMILY_SAM9); -} - -static inline int -at91_is_sam9xe(void) -{ - - return (soc_info.family == AT91_FAMILY_SAM9XE); -} - -static inline int -at91_cpu_is(u_int cpu) -{ - - return (soc_info.type == cpu); -} - -void at91_add_child(device_t dev, int prio, const char *name, int unit, - bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2); - -extern uint32_t at91_irq_system; -extern uint32_t at91_master_clock; -void at91_pmc_init_clock(void); -void at91_soc_id(void); - -#endif /* _AT91VAR_H_ */ Index: head/sys/arm/at91/board_bwct.c =================================================================== --- head/sys/arm/at91/board_bwct.c +++ head/sys/arm/at91/board_bwct.c @@ -1,56 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2005-2008 Olivier Houchard. All rights reserved. - * Copyright (c) 2005-2012 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); -#include -#include - -#include -#include -#include -#include - -BOARD_INIT long -board_init(void) -{ - - at91rm9200_set_subtype(AT91_ST_RM9200_BGA); - - /* - * I don't know anything at all about this board. - */ - at91rm9200_config_uart(AT91_ID_DBGU, 0, 0); /* DBGU just Tx and Rx */ - - at91rm9200_config_mci(0); - /* Configure ethernet */ - - return (at91_ramsize()); -} - -ARM_BOARD(NONE, "BWCT special"); Index: head/sys/arm/at91/board_eb9200.c =================================================================== --- head/sys/arm/at91/board_eb9200.c +++ head/sys/arm/at91/board_eb9200.c @@ -1,70 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2005-2008 Olivier Houchard. All rights reserved. - * Copyright (c) 2005-2012 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); -#include -#include - -#include -#include -#include -#include - -BOARD_INIT long -board_init(void) -{ - - at91rm9200_set_subtype(AT91_ST_RM9200_BGA); - - /* - * Setup the serial ports. - * DBGU and USART0 are DB9 ports. - * USART2 is IrDA. - */ - at91rm9200_config_uart(AT91_ID_DBGU, 0, 0); /* DBGU just Tx and Rx */ - at91rm9200_config_uart(AT91RM9200_ID_USART0, 1, - AT91_UART_CTS | AT91_UART_RTS | AT91_UART_DTR | AT91_UART_DSR | - AT91_UART_DCD | AT91_UART_RI); - at91rm9200_config_uart(AT91RM9200_ID_USART1, 2, 0); - - at91rm9200_config_mci(1); - - /* CFE interface */ - /* SPI interface */ - /* ethernet interface */ - /* USB host */ - /* USB device (gadget) */ - /* TWI */ - /* CF interface */ - /* SmartMedia Interface */ - - return (at91_ramsize()); -} - -ARM_BOARD(ATEB9200, "Embest ATEB9200") Index: head/sys/arm/at91/board_ethernut5.c =================================================================== --- head/sys/arm/at91/board_ethernut5.c +++ head/sys/arm/at91/board_ethernut5.c @@ -1,151 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2012 Marius Strobl - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Ethernut 5 board support - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -BOARD_INIT long -board_init(void) -{ - - /* - * DBGU - */ - /* DRXD */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB14, 0); - /* DTXD */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB15, 1); - - /* - * EMAC - */ - /* ETX0 */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA12, 0); - /* ETX1 */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA13, 0); - /* ERX0 */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA14, 0); - /* ERX1 */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA15, 0); - /* ETXEN */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA16, 0); - /* ERXDV */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA17, 0); - /* ERXER */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA18, 0); - /* ETXCK */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA19, 0); - /* EMDC */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA20, 0); - /* EMDIO */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA21, 0); - - /* - * MMC - */ - /* MCDA0 */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA6, 1); - /* MCCDA */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA7, 1); - /* MCCK */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA8, 1); - /* MCDA1 */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA9, 1); - /* MCDA2 */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA10, 1); - /* MCDA3 */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA11, 1); - - /* - * SPI0 - */ - /* MISO */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA0, 0); - /* MOSI */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA1, 0); - /* SPCK */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA2, 0); - /* NPCS0 */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA3, 0); - - /* - * TWI - */ - /* TWD */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA23, 1); - /* TWCK */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA24, 1); - - /* - * USART0 - */ - /* TXD0 */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB4, 1); - /* RXD0 */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB5, 0); - /* DSR0 */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB22, 0); - /* DCD0 */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB23, 0); - /* DTR0 */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB24, 1); - /* RI0 */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB25, 0); - /* RTS0 */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB26, 1); - /* CTS0 */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB27, 0); - - /* - * USART2 - */ - /* RTS2 */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA4, 1); - /* CTS2 */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA5, 0); - /* TXD2 */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB8, 1); - /* RXD2 */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB9, 0); - - return (at91_ramsize()); -} - -ARM_BOARD(ETHERNUT5, "Ethernut 5") Index: head/sys/arm/at91/board_hl200.c =================================================================== --- head/sys/arm/at91/board_hl200.c +++ head/sys/arm/at91/board_hl200.c @@ -1,67 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2005-2008 Olivier Houchard. All rights reserved. - * Copyright (c) 2005-2012 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); -#include -#include - -#include -#include -#include -#include -#include - -BOARD_INIT long -board_init(void) -{ - - at91rm9200_set_subtype(AT91_ST_RM9200_BGA); - - /* - * Unsure what all is in the HOTe HL200, but I do know there's - * one serial port that isn't DBGU. There's many other peripherals - * that need to be configured here. - */ - at91rm9200_config_uart(AT91_ID_DBGU, 0, 0); /* DBGU just Tx and Rx */ - at91rm9200_config_uart(AT91RM9200_ID_USART0, 1, 0); /* Tx and Rx */ - - at91rm9200_config_mci(0); /* HOTe HL200 unknown 1 vs 4 wire */ - - /* Enable CF card slot */ - /* Enable sound thing */ - /* Enable VGA chip */ - /* Enable ethernet */ - /* Enable TWI + RTC */ - /* Enable USB Host */ - /* Enable USB Device (gadget) */ - - return (at91_ramsize()); -} - -ARM_BOARD(NONE, "HOTe 200"); Index: head/sys/arm/at91/board_hl201.c =================================================================== --- head/sys/arm/at91/board_hl201.c +++ head/sys/arm/at91/board_hl201.c @@ -1,123 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2005-2008 Olivier Houchard. All rights reserved. - * Copyright (c) 2005-2008 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -static struct at91_smc_init nand_smc = { - .ncs_rd_setup = 0, - .nrd_setup = 2, - .ncs_wr_setup = 0, - .nwe_setup = 2, - - .ncs_rd_pulse = 4, - .nrd_pulse = 4, - .ncs_wr_pulse = 4, - .nwe_pulse = 4, - - .nrd_cycle = 7, - .nwe_cycle = 7, - - .mode = SMC_MODE_READ | SMC_MODE_WRITE | SMC_MODE_EXNW_DISABLED, - .tdf_cycles = 3, -}; - -static struct at91_nand_params nand_param = { - .ale = 1u << 21, - .cle = 1u << 22, - .width = 8, - .rnb_pin = AT91_PIN_PC13, /* Note: These pins not confirmed */ - .nce_pin = AT91_PIN_PC14, - .cs = 3, -}; - -BOARD_INIT long -board_init(void) -{ - /* Setup Ethernet Pins */ - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, 1<<7, 0); - - at91_pio_gpio_input(AT91SAM9G20_PIOA_BASE, 1<<7); - at91_pio_gpio_set_deglitch(AT91SAM9G20_PIOA_BASE, 1<<7, 1); - - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA19, 0); /* ETXCK_EREFCK */ - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA17, 0); /* ERXDV */ - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA14, 0); /* ERX0 */ - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA15, 0); /* ERX1 */ - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA18, 0); /* ERXER */ - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA16, 0); /* ETXEN */ - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA12, 0); /* ETX0 */ - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA13, 0); /* ETX1 */ - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA21, 0); /* EMDIO */ - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA20, 0); /* EMDC */ - - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA28, 0); /* ECRS */ - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA29, 0); /* ECOL */ - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA25, 0); /* ERX2 */ - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA26, 0); /* ERX3 */ - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA27, 0); /* ERXCK */ - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA23, 0); /* ETX2 */ - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA24, 0); /* ETX3 */ - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA22, 0); /* ETXER */ - - /* Setup Static Memory Controller */ - at91_smc_setup(0, 3, &nand_smc); - at91_enable_nand(&nand_param); - - /* - * This assumes - * - RNB is on pin PC13 - * - CE is on pin PC14 - * - * Nothing actually uses RNB right now. - * - * For CE, this currently asserts it during board setup and leaves it - * that way forever. - * - * All this can go away when the gpio pin-renumbering happens... - */ - at91_pio_use_gpio(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC13 | AT91C_PIO_PC14); - at91_pio_gpio_input(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC13); /* RNB */ - at91_pio_gpio_output(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC14, 0); /* nCS */ - at91_pio_gpio_clear(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC14); /* Assert nCS */ - - return (at91_ramsize()); -} - -ARM_BOARD(NONE, "HOTe 201"); Index: head/sys/arm/at91/board_kb920x.c =================================================================== --- head/sys/arm/at91/board_kb920x.c +++ head/sys/arm/at91/board_kb920x.c @@ -1,68 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2005-2008 Olivier Houchard. All rights reserved. - * Copyright (c) 2005-2012 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); -#include -#include - -#include -#include -#include -#include - -BOARD_INIT long -board_init(void) -{ - - at91rm9200_set_subtype(AT91_ST_RM9200_PQFP); - - /* - * Setup the serial ports. - * DBGU is the main one, although jumpers can make USART0 default. - * USART1 is IrDA, and USART3 is optional RS485. - */ - at91rm9200_config_uart(AT91_ID_DBGU, 0, 0); /* DBGU just Tx and Rx */ - at91rm9200_config_uart(AT91RM9200_ID_USART0, 1, 0); /* Tx and Rx */ - at91rm9200_config_uart(AT91RM9200_ID_USART1, 2, 0); /* Tx and Rx - IRDA */ - at91rm9200_config_uart(AT91RM9200_ID_USART3, 3, /* Tx, Rx, CTS, RTS - RS485 */ - AT91_UART_CTS | AT91_UART_RTS); - - at91rm9200_config_mci(1); - - /* CFE interface */ - /* ethernet interface */ - /* lcd interface */ - /* USB host */ - /* USB device (gadget) */ - /* TWI */ - - return (at91_ramsize()); -} - -ARM_BOARD(KB9200, "Kwikbyte KB920x") Index: head/sys/arm/at91/board_qila9g20.c =================================================================== --- head/sys/arm/at91/board_qila9g20.c +++ head/sys/arm/at91/board_qila9g20.c @@ -1,110 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2009 Greg Ansley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* Calao Systems QIL-9G20-Cxx - * http://www.calao-systems.com - */ - -#include -__FBSDID("$FreeBSD$"); -#include -#include - -#include -#include -#include -#include -#include -#include -#include -//#include - -#define AT91SAM9G20_LED_BASE AT91SAM9G20_PIOA_BASE -#define AT91SAM9G20_LED_SIZE AT91SAM9G20_PIO_SIZE -#define AT91SAM9G20_IRQ_LED AT91SAM9G20_IRQ_PIOA - -BOARD_INIT long -board_init(void) -{ - - //at91_led_create("power", 0, 9, 0); - - /* PIOB's A periph: Turn USART 0's TX/RX pins */ - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB14_DRXD, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB15_DTXD, 1); - - /* PIOB's A periph: Turn USART 0's TX/RX pins */ - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB4_TXD0, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB5_RXD0, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB22_DSR0, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB23_DCD0, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB24_DTR0, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB25_RI0, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB26_RTS0, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB27_CTS0, 0); - - /* PIOB's A periph: Turn USART 1's TX/RX pins */ - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB6_TXD1, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB7_RXD1, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB28_RTS1, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB29_CTS1, 0); - - /* TWI Two-wire Serial Data */ - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA23_TWD, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA24_TWCK, 1); - - /* Multimedia Card */ - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA6_MCDA0, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA7_MCCDA, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA8_MCCK, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA9_MCDA1, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA10_MCDA2, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA11_MCDA3, 1); - - /* SPI0 to DataFlash */ - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PA0_SPI0_MISO, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PA1_SPI0_MOSI, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PA2_SPI0_SPCK, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PA3_SPI0_NPCS0, 0); - - /* EMAC */ - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA19_ETXCK, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA21_EMDIO, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA20_EMDC, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA17_ERXDV, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA16_ETXEN, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA12_ETX0 , 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA13_ETX1, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA14_ERX0, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA15_ERX1, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA18_ERXER, 0); - - - return (at91_ramsize()); -} - -ARM_BOARD(QIL_A9G20, "Calico System QIL-9G20-Cxx"); Index: head/sys/arm/at91/board_sam9260ek.c =================================================================== --- head/sys/arm/at91/board_sam9260ek.c +++ head/sys/arm/at91/board_sam9260ek.c @@ -1,264 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2012 Marius Strobl - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Ethernut 5 board support - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct at91_smc_init nand_smc = { - .ncs_rd_setup = 0, - .nrd_setup = 1, - .ncs_wr_setup = 0, - .nwe_setup = 1, - - .ncs_rd_pulse = 3, - .nrd_pulse = 3, - .ncs_wr_pulse = 3, - .nwe_pulse = 3, - - .nrd_cycle = 5, - .nwe_cycle = 5, - - .mode = SMC_MODE_READ | SMC_MODE_WRITE | SMC_MODE_EXNW_DISABLED, - .tdf_cycles = 2, -}; - -static struct at91_nand_params nand_param = { - .ale = 1u << 21, - .cle = 1u << 22, - .width = 8, - .rnb_pin = AT91_PIN_PC13, - .nce_pin = AT91_PIN_PC14, - .cs = 3, -}; - -static void -bi_dbgu(void) -{ - - /* - * DBGU - */ - /* DRXD */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB14, 0); - /* DTXD */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB15, 1); -} - -static void -bi_emac(void) -{ - - /* - * EMAC - */ - /* ETX0 */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA12, 0); - /* ETX1 */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA13, 0); - /* ERX0 */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA14, 0); - /* ERX1 */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA15, 0); - /* ETXEN */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA16, 0); - /* ERXDV */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA17, 0); - /* ERXER */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA18, 0); - /* ETXCK */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA19, 0); - /* EMDC */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA20, 0); - /* EMDIO */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA21, 0); - /* Not RMII */ - /* ETX2 */ - at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA10, 0); - /* ETX3 */ - at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA11, 0); - /* ETXER */ - at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA22, 0); - /* ERX2 */ - at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA25, 0); - /* ERX3 */ - at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA26, 0); - /* ERXCK */ - at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA27, 0); - /* ECRS */ - at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA28, 0); - /* ECOL */ - at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA29, 0); -} - -static void -bi_mmc(void) -{ - - /* - * MMC, wired to socket B. - */ - /* MCDB0 */ - at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA0, 1); - /* MCCDB */ - at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA1, 1); - /* MCDB3 */ - at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA3, 1); - /* MCDB2 */ - at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA4, 1); - /* MCDB1 */ - at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA5, 1); - /* MCCK */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA8, 1); - - /* - * SPI0 and MMC are wired together, since we don't support sharing - * don't support the dataflash. But if you did, you'd have to - * use CS0 and CS1. - */ -} - -static void -bi_iic(void) -{ - - /* - * TWI. Only one child on the iic bus, which we take care of - * via hints. - */ - /* TWD */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA23, 1); - /* TWCK */ - at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA24, 1); -} - -static void -bi_usart0(void) -{ - - /* - * USART0 - */ - /* TXD0 */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB4, 1); - /* RXD0 */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB5, 0); - /* DSR0 */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB22, 0); - /* DCD0 */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB23, 0); - /* DTR0 */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB24, 1); - /* RI0 */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB25, 0); - /* RTS0 */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB26, 1); - /* CTS0 */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB27, 0); -} - -static void -bi_usart1(void) -{ - /* - * USART1 - */ - /* RTS1 */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB28, 1); - /* CTS1 */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB29, 0); - /* TXD1 */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB6, 1); - /* RXD1 */ - at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB7, 0); -} - -static void -bi_nand(void) -{ - /* Samsung 256MB SLC Flash */ - - /* Setup Static Memory Controller */ - at91_smc_setup(0, 3, &nand_smc); - at91_enable_nand(&nand_param); - - /* - * This assumes - * - RNB is on pin PC13 - * - CE is on pin PC14 - * - * Nothing actually uses RNB right now. - * - * For CE, this currently asserts it during board setup and leaves it - * that way forever. - * - * All this can go away when the gpio pin-renumbering happens... - */ - at91_pio_use_gpio(AT91SAM9260_PIOC_BASE, AT91C_PIO_PC13 | AT91C_PIO_PC14); - at91_pio_gpio_input(AT91SAM9260_PIOC_BASE, AT91C_PIO_PC13); /* RNB */ - at91_pio_gpio_output(AT91SAM9260_PIOC_BASE, AT91C_PIO_PC14, 0); /* nCS */ - at91_pio_gpio_clear(AT91SAM9260_PIOC_BASE, AT91C_PIO_PC14); /* Assert nCS */ -} - -BOARD_INIT long -board_init(void) -{ - bi_dbgu(); - bi_emac(); - bi_mmc(); - - /* - * SPI1 is wired to a audio CODEC that we don't support, so - * give it a pass. - */ - - bi_iic(); - bi_usart0(); - bi_usart1(); - /* USART2 - USART5 aren't wired up, except via PIO pins, ignore them. */ - - bi_nand(); - - return (at91_ramsize()); -} - -ARM_BOARD(AT91SAM9260EK, "Atmel SMA9260-EK") Index: head/sys/arm/at91/board_sam9g20ek.c =================================================================== --- head/sys/arm/at91/board_sam9g20ek.c +++ head/sys/arm/at91/board_sam9g20ek.c @@ -1,129 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2009 Greg Ansley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * This board file can be used for both: - * Atmel SAM9G20-EK Development Card - */ - -#include -__FBSDID("$FreeBSD$"); -#include -#include - -#include -#include -#include -#include -#include -#include -#include -//#include - -BOARD_INIT long -board_init(void) -{ - /* PIOB's A periph: Turn USART 0's TX/RX pins */ - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB14_DRXD, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB15_DTXD, 1); - - /* PIOB's A periph: Turn USART 0's TX/RX pins */ - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB4_TXD0, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB5_RXD0, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB22_DSR0, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB23_DCD0, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB24_DTR0, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB25_RI0, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB26_RTS0, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB27_CTS0, 0); - - /* PIOB's A periph: Turn USART 1's TX/RX pins */ - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB6_TXD1, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB7_RXD1, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB28_RTS1, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB29_CTS1, 0); - - /* TWI Two-wire Serial Data */ - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA23_TWD, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA24_TWCK, 1); - -#if 1 - /* - * Turn off Clock to DataFlash, conflicts with MCI clock. - */ - at91_pio_use_gpio(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA2); - at91_pio_gpio_input(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA2); - - /* Turn off chip select to DataFlash */ - at91_pio_gpio_output(AT91SAM9G20_PIOC_BASE,AT91C_PIO_PC11, 0); - at91_pio_gpio_set(AT91SAM9G20_PIOC_BASE,AT91C_PIO_PC11); - at91_pio_use_gpio(AT91SAM9G20_PIOC_BASE,AT91C_PIO_PC11); - - /* Multimedia Card */ - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA0_MCDB0, 1); - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA1_MCCDB, 1); - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA3_MCDB3, 1); - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA4_MCDB2, 1); - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA5_MCDB1, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA8_MCCK, 1); - at91_pio_use_gpio(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC9); -#else - /* SPI0 to DataFlash */ - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA0, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA1, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA2, 0); - at91_pio_use_periph_b(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC11,0); - - at91_pio_gpio_input(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA8); - at91_pio_use_gpio(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA8); -#endif - - /* EMAC */ - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA12_ETX0 , 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA13_ETX1, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA14_ERX0, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA15_ERX1, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA16_ETXEN, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA17_ERXDV, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA18_ERXER, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA19_ETXCK, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA20_EMDC, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA21_EMDIO, 0); - - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA10_ETX2_0, 0); - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA11_ETX3_0, 0); - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA22_ETXER, 0); - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA25_ERX2, 0); - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA26_ERX3, 0); - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA27_ERXCK, 0); - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA28_ECRS, 0); - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA29_ECOL, 0); - - return (at91_ramsize()); -} - -ARM_BOARD(AT91SAM9G20, "Atmel SAM9G20-EK Development Card"); Index: head/sys/arm/at91/board_sam9x25ek.c =================================================================== --- head/sys/arm/at91/board_sam9x25ek.c +++ head/sys/arm/at91/board_sam9x25ek.c @@ -1,130 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2009 Greg Ansley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * This board file can be used for both: - * SAM9X26EK board - */ - -#include -__FBSDID("$FreeBSD$"); -#include -#include - -#include -#include -#include -#include -#include -#include -#include -//#include - -BOARD_INIT long -board_init(void) -{ -#if 0 - /* PIOB's A periph: Turn USART 0's TX/RX pins */ - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB14_DRXD, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB15_DTXD, 1); - - /* PIOB's A periph: Turn USART 0's TX/RX pins */ - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB4_TXD0, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB5_RXD0, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB22_DSR0, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB23_DCD0, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB24_DTR0, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB25_RI0, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB26_RTS0, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB27_CTS0, 0); - - /* PIOB's A periph: Turn USART 1's TX/RX pins */ - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB6_TXD1, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB7_RXD1, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB28_RTS1, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB29_CTS1, 0); - - /* TWI Two-wire Serial Data */ - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA23_TWD, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA24_TWCK, 1); - -#if 1 - /* - * Turn off Clock to DataFlash, conflicts with MCI clock. - */ - at91_pio_use_gpio(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA2); - at91_pio_gpio_input(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA2); - - /* Turn off chip select to DataFlash */ - at91_pio_gpio_output(AT91SAM9G20_PIOC_BASE,AT91C_PIO_PC11, 0); - at91_pio_gpio_set(AT91SAM9G20_PIOC_BASE,AT91C_PIO_PC11); - at91_pio_use_gpio(AT91SAM9G20_PIOC_BASE,AT91C_PIO_PC11); - - /* Multimedia Card */ - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA0_MCDB0, 1); - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA1_MCCDB, 1); - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA3_MCDB3, 1); - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA4_MCDB2, 1); - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA5_MCDB1, 1); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA8_MCCK, 1); - at91_pio_use_gpio(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC9); -#else - /* SPI0 to DataFlash */ - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA0, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA1, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA2, 0); - at91_pio_use_periph_b(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC11,0); - - at91_pio_gpio_input(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA8); - at91_pio_use_gpio(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA8); -#endif - - /* EMAC */ - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA12_ETX0 , 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA13_ETX1, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA14_ERX0, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA15_ERX1, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA16_ETXEN, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA17_ERXDV, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA18_ERXER, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA19_ETXCK, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA20_EMDC, 0); - at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA21_EMDIO, 0); - - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA10_ETX2_0, 0); - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA11_ETX3_0, 0); - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA22_ETXER, 0); - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA25_ERX2, 0); - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA26_ERX3, 0); - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA27_ERXCK, 0); - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA28_ECRS, 0); - at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA29_ECOL, 0); -#endif - return (at91_ramsize()); -} - -ARM_BOARD(AT91SAM9X5EK, "Atmel AT91SAM9x-EK Evaluation Board"); Index: head/sys/arm/at91/board_sn9g45.c =================================================================== --- head/sys/arm/at91/board_sn9g45.c +++ head/sys/arm/at91/board_sn9g45.c @@ -1,57 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2009 Greg Ansley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * DesignA Electronics Snapper9g45 - * http://www.designa-electronics.com/ - */ - -#include -__FBSDID("$FreeBSD$"); -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -BOARD_INIT long -board_init(void) -{ - - /* PIOB's A periph: Turn the debug USART's TX/RX pins */ - at91_pio_use_periph_a(AT91SAM9G45_PIOB_BASE, AT91C_PB12_DRXD, 0); - at91_pio_use_periph_a(AT91SAM9G45_PIOB_BASE, AT91C_PB13_DTXD, 1); - - return (at91_ramsize()); -} - -ARM_BOARD(SNAPPER9G45, "DesignA Electronics Snapper9G45"); Index: head/sys/arm/at91/board_tsc4370.c =================================================================== --- head/sys/arm/at91/board_tsc4370.c +++ head/sys/arm/at91/board_tsc4370.c @@ -1,610 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2005-2008 Olivier Houchard. All rights reserved. - * Copyright (c) 2005-2012 M. Warner Losh. - * Copyright (c) 2007-2014 Ian Lepore. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Board init code for the TSC4370, and all other current TSC mainboards. - */ - -#include -__FBSDID("$FreeBSD$"); -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * RD4HW()/WR4HW() read and write at91rm9200 hardware register space directly. - * They serve the same purpose as the RD4()/WR4() idiom you see in many drivers, - * except that those translate to bus_space calls, but in this code we need to - * access the registers directly before the at91 bus_space stuff is set up. - */ - -static inline uint32_t -RD4HW(uint32_t devbase, uint32_t regoff) -{ - return *(volatile uint32_t *)(AT91_BASE + devbase + regoff); -} - -static inline void -WR4HW(uint32_t devbase, uint32_t regoff, uint32_t val) -{ - *(volatile uint32_t *)(AT91_BASE + devbase + regoff) = val; -} - -/* - * This is the same calculation the at91 uart driver does, we use it to update - * the console uart baud rate after changing the MCK rate. - */ -#ifndef BAUD2DIVISOR -#define BAUD2DIVISOR(b) \ - ((((at91_master_clock * 10) / ((b) * 16)) + 5) / 10) -#endif - -/* - * If doing an in-house build, use tsc_bootinfo.h which is shared with our - * custom boot2. Otherwise define some crucial bits of it here, enough to allow - * this code to compile. - */ -#ifdef TSC_BUILD -#include -#else -struct tsc_bootinfo { - uint32_t bi_size; - uint32_t bi_version; - uint32_t bi_flags; /* RB_xxxxx flags from sys/reboot.h */ - char bi_rootdevname[64]; -}; -#define TSC_BOOTINFO_MAGIC 0x06C30000 -#endif - -static struct arm_boot_params boot_params; -static struct tsc_bootinfo inkernel_bootinfo; - -/* - * Change the master clock config and wait for it to stabilize. - */ -static void -change_mckr(uint32_t mckr) -{ - int i; - - WR4HW(AT91RM92_PMC_BASE, PMC_MCKR, mckr); - - for (i = 0; i < 1000; ++i) - if ((RD4HW(AT91RM92_PMC_BASE, PMC_SR) & PMC_IER_MCKRDY)) - return; -} - -/* - * Allow the master clock frequency to be changed from whatever the bootloader - * set up, because sometimes it's harder to change/update a bootloader than it - * is to change/update the kernel once a product is in the field. - */ -static void -master_clock_init(void) -{ - uint32_t mckr = RD4HW(AT91RM92_PMC_BASE, PMC_MCKR); - int hintvalue = 0; - int newmckr = 0; - - /* - * If there's a hint that specifies the contents of MCKR, use it - * without question (it had better be right). - * - * If there's a "mckfreq" hint it might be in hertz or mhz (convert the - * latter to hz). Calculate the new MCK divider. If the CPU frequency - * is not a sane multiple of the hinted MCK frequency this is likely to - * behave badly. The moral is: don't hint at impossibilities. - */ - - if (resource_int_value("at91", 0, "mckr", &hintvalue) == 0) { - newmckr = hintvalue; - } else { - hintvalue = 90; /* Default to 90mhz if not specified. */ - resource_int_value("at91", 0, "mckfreq", &hintvalue); - if (hintvalue != 0) { - if (hintvalue < 1000) - hintvalue *= 1000000; - if (hintvalue != at91_master_clock) { - uint32_t divider; - struct at91_pmc_clock * cpuclk; - cpuclk = at91_pmc_clock_ref("cpu"); - divider = (cpuclk->hz / hintvalue) - 1; - newmckr = (mckr & 0xFFFFFCFF) | ((divider & 0x03) << 8); - at91_pmc_clock_deref(cpuclk); - } - } - } - - /* If the new mckr value is different than what's in the register now, - * make the change and wait for the clocks to settle (MCKRDY status). - * - * MCKRDY will never be asserted unless either the selected clock or the - * prescaler value changes (but not both at once) [this is detailed in - * the rm9200 errata]. This code assumes the prescaler value is always - * zero and that by time we get to here we're running on something other - * than the slow clock, so to change the mckr divider we first change - * back to the slow clock (keeping prescaler and divider unchanged), - * then go back to the original selected clock with the new divider. - * - * After changing MCK, go re-init everything clock-related, and reset - * the baud rate generator for the console (doing this here is kind of a - * rude hack, but hey, you do what you have to to run MCK faster). - */ - - if (newmckr != 0 && newmckr != mckr) { - if (mckr & 0x03) - change_mckr(mckr & ~0x03); - change_mckr(newmckr); - at91_pmc_init_clock(); - WR4HW(AT91RM92_DBGU_BASE, USART_BRGR, BAUD2DIVISOR(115200)); - } -} - -/* - * TSC-specific code to read the ID eeprom on the mainboard and extract the - * unit's EUI-64 which gets translated into a MAC-48 for ethernet. - */ -static void -eeprom_init(void) -{ - const uint32_t twiHz = 400000; - const uint32_t twiCkDiv = 1 << 16; - const uint32_t twiChDiv = ((at91_master_clock / twiHz) - 2) << 8; - const uint32_t twiClDiv = ((at91_master_clock / twiHz) - 2); - - /* - * Set the TWCK and TWD lines for Periph A, no pullup, open-drain. - */ - at91_pio_use_periph_a(AT91RM92_PIOA_BASE, - AT91C_PIO_PA25 | AT91C_PIO_PA26, 0); - at91_pio_gpio_high_z(AT91RM92_PIOA_BASE, AT91C_PIO_PA25, 1); - - /* - * Enable TWI power (irq numbers are also device IDs for power) - */ - WR4HW(AT91RM92_PMC_BASE, PMC_PCER, 1u << AT91RM92_IRQ_TWI); - - /* - * Disable TWI interrupts, reset device, enable Master mode, - * disable Slave mode, set the clock. - */ - WR4HW(AT91RM92_TWI_BASE, TWI_IDR, 0xffffffff); - WR4HW(AT91RM92_TWI_BASE, TWI_CR, TWI_CR_SWRST); - WR4HW(AT91RM92_TWI_BASE, TWI_CR, TWI_CR_MSEN | TWI_CR_SVDIS); - WR4HW(AT91RM92_TWI_BASE, TWI_CWGR, twiCkDiv | twiChDiv | twiClDiv); -} - -static int -eeprom_read(uint32_t EE_DEV_ADDR, uint32_t ee_off, void * buf, uint32_t size) -{ - uint8_t *bufptr = (uint8_t *)buf; - uint32_t status; - uint32_t count; - - /* Clean out any old status and received byte. */ - status = RD4HW(AT91RM92_TWI_BASE, TWI_SR); - status = RD4HW(AT91RM92_TWI_BASE, TWI_RHR); - - /* Set the TWI Master Mode Register */ - WR4HW(AT91RM92_TWI_BASE, TWI_MMR, - TWI_MMR_DADR(EE_DEV_ADDR) | TWI_MMR_IADRSZ(2) | TWI_MMR_MREAD); - - /* Set TWI Internal Address Register */ - WR4HW(AT91RM92_TWI_BASE, TWI_IADR, ee_off); - - /* Start transfer */ - WR4HW(AT91RM92_TWI_BASE, TWI_CR, TWI_CR_START); - - status = RD4HW(AT91RM92_TWI_BASE, TWI_SR); - - while (size-- > 1){ - /* Wait until Receive Holding Register is full */ - count = 1000000; - while (!(RD4HW(AT91RM92_TWI_BASE, TWI_SR) & TWI_SR_RXRDY) && - --count != 0) - continue; - if (count <= 0) - return -1; - /* Read and store byte */ - *bufptr++ = (uint8_t)RD4HW(AT91RM92_TWI_BASE, TWI_RHR); - } - WR4HW(AT91RM92_TWI_BASE, TWI_CR, TWI_CR_STOP); - - status = RD4HW(AT91RM92_TWI_BASE, TWI_SR); - - /* Wait until transfer is finished */ - while (!(RD4HW(AT91RM92_TWI_BASE, TWI_SR) & TWI_SR_TXCOMP)) - continue; - - /* Read last byte */ - *bufptr = (uint8_t)RD4HW(AT91RM92_TWI_BASE, TWI_RHR); - - return 0; -} - -static int -set_mac_from_idprom(void) -{ -#define SIGNATURE_SIZE 4 -#define EETYPE_SIZE 2 -#define BSLENGTH_SIZE 2 -#define RAW_SIZE 52 -#define EUI64_SIZE 8 -#define BS_SIGNATURE 0x21706d69 -#define BSO_SIGNATURE 0x216f7362 -#define DEVOFFSET_BSO_SIGNATURE 0x20 -#define OFFSET_BS_SIGNATURE 0 -#define SIZE_BS_SIGNATURE SIGNATURE_SIZE -#define OFFSET_EETYPE (OFFSET_BS_SIGNATURE + SIZE_BS_SIGNATURE) -#define SIZE_EETYPE EETYPE_SIZE -#define OFFSET_BOOTSECTSIZE (OFFSET_EETYPE + SIZE_EETYPE) -#define SIZE_BOOTSECTSIZE BSLENGTH_SIZE -#define OFFSET_RAW (OFFSET_BOOTSECTSIZE + SIZE_BOOTSECTSIZE) -#define OFFSET_EUI64 (OFFSET_RAW + RAW_SIZE) -#define EE_DEV_ADDR 0xA0 /* eeprom is AT24C256 at address 0xA0 */ - - int status; - uint32_t dev_offset = 0; - uint32_t sig; - uint8_t eui64[EUI64_SIZE]; - uint8_t eaddr[ETHER_ADDR_LEN]; - - eeprom_init(); - - /* Check for the boot section signature at offset 0. */ - status = eeprom_read(EE_DEV_ADDR, OFFSET_BS_SIGNATURE, &sig, sizeof(sig)); - if (status == -1) - return -1; - - if (sig != BS_SIGNATURE) { - /* Check for the boot section offset signature. */ - status = eeprom_read(EE_DEV_ADDR, - DEVOFFSET_BSO_SIGNATURE, &sig, sizeof(sig)); - if ((status == -1) || (sig != BSO_SIGNATURE)) - return -1; - - /* Read the device offset of the boot section structure. */ - status = eeprom_read(EE_DEV_ADDR, - DEVOFFSET_BSO_SIGNATURE + sizeof(sig), - &dev_offset, sizeof(dev_offset)); - if (status == -1) - return -1; - - /* Check for the boot section signature. */ - status = eeprom_read(EE_DEV_ADDR, - dev_offset + OFFSET_BS_SIGNATURE, &sig, sizeof(sig)); - if ((status == -1) || (sig != BS_SIGNATURE)) - return -1; - } - dev_offset += OFFSET_EUI64; - - /* Read the EUI64 from the device. */ - if (eeprom_read(EE_DEV_ADDR, dev_offset, eui64, sizeof(eui64)) == -1) - return -1; - - /* Transcribe the EUI-64 to a MAC-48. - * - * Given an EUI-64 of aa:bb:cc:dd:ee:ff:gg:hh - * - * if (ff is zero and ee is non-zero) - * mac is aa:bb:cc:ee:gg:hh - * else - * mac is aa:bb:cc:ff:gg:hh - * - * This logic fixes a glitch in our mfg process in which the ff byte was - * always zero and the ee byte contained a non-zero value. This - * resulted in duplicate MAC addresses because we discarded the ee byte. - * Now they've fixed the process so that the ff byte is non-zero and - * unique addresses are formed from the ff:gg:hh bytes. If the ff byte - * is zero, then we have a unit manufactured during the glitch era, and - * we fix the problem by grabbing the ee byte rather than the ff byte. - */ - eaddr[0] = eui64[0]; - eaddr[1] = eui64[1]; - eaddr[2] = eui64[2]; - eaddr[3] = eui64[5]; - eaddr[4] = eui64[6]; - eaddr[5] = eui64[7]; - - if (eui64[5] == 0 && eui64[4] != 0) { - eaddr[3] = eui64[4]; - } - - /* - * Set the address in the hardware regs where the ate driver - * looks for it. - */ - WR4HW(AT91RM92_EMAC_BASE, ETH_SA1L, - (eaddr[3] << 24) | (eaddr[2] << 16) | (eaddr[1] << 8) | eaddr[0]); - WR4HW(AT91RM92_EMAC_BASE, ETH_SA1H, - (eaddr[5] << 8) | (eaddr[4])); - - printf( - "ID: EUI-64 %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n" - " MAC-48 %02x:%02x:%02x:%02x:%02x:%02x\n" - " read from i2c device 0x%02X offset 0x%x\n", - eui64[0], eui64[1], eui64[2], eui64[3], - eui64[4], eui64[5], eui64[6], eui64[7], - eaddr[0], eaddr[1], eaddr[2], - eaddr[3], eaddr[4], eaddr[5], - EE_DEV_ADDR, dev_offset); - - return (0); -} - -/* - * Assign SPI chip select pins based on which chip selects are found in hints. - */ -static void -assign_spi_pins(void) -{ - struct { - uint32_t num; - const char * name; - } chipsel_pins[] = { - { AT91C_PIO_PA3, "PA3", }, - { AT91C_PIO_PA4, "PA4", }, - { AT91C_PIO_PA5, "PA5", }, - { AT91C_PIO_PA6, "PA6", }, - }; - int anchor = 0; - uint32_t chipsel_inuse = 0; - - /* - * Search through all device hints looking for any that have - * ".at=spibus0". For each one found, ensure that there is also a - * chip select hint ".cs=" and that is 0-3, and assign the - * corresponding pin to the SPI peripheral. Whine if we find a SPI - * device with a missing or invalid chipsel hint. - */ - for (;;) { - const char * rName = ""; - int unit = 0; - int cs = 0; - int ret; - - ret = resource_find_match(&anchor, &rName, &unit, "at", "spibus0"); - if (ret != 0) - break; - - ret = resource_int_value(rName, unit, "cs", &cs); - if (ret != 0) { - printf( "Error: hint for SPI device %s%d " - "without a chip select hint; " - "device will not function.\n", - rName, unit); - continue; - } - if (cs < 0 || cs > 3) { - printf( "Error: hint for SPI device %s%d " - "contains an invalid chip select " - "value: %d\n", - rName, unit, cs); - continue; - } - if (chipsel_inuse & (1 << cs)) { - printf( "Error: hint for SPI device %s%d " - "specifies chip select %d, which " - "is already used by another device\n", - rName, unit, cs); - continue; - } - chipsel_inuse |= 1 << cs; - at91_pio_use_periph_a(AT91RM92_PIOA_BASE, - chipsel_pins[cs].num, 1); - printf( "Configured pin %s as SPI chip " - "select %d for %s%d\n", - chipsel_pins[cs].name, cs, rName, unit); - } - - /* - * If there were hints for any SPI devices, assign the basic SPI IO pins - * and enable SPI power (irq numbers are also device IDs for power). - */ - if (chipsel_inuse != 0) { - at91_pio_use_periph_a(AT91RM92_PIOA_BASE, - AT91C_PIO_PA1 | AT91C_PIO_PA0 | AT91C_PIO_PA2, 0); - WR4HW(AT91RM92_PMC_BASE, PMC_PCER, 1u << AT91RM92_IRQ_SPI); - } -} - -BOARD_INIT long -board_init(void) -{ - int is_bga, rev_mii; - - /* - * Deal with bootinfo (if any) passed in from the boot2 bootloader and - * copied to the static inkernel_bootinfo earlier in the init. Do this - * early so that bootverbose is set from this point on. - */ - if (inkernel_bootinfo.bi_size > 0 && - (inkernel_bootinfo.bi_flags & RB_BOOTINFO)) { - struct tsc_bootinfo *bip = &inkernel_bootinfo; - printf("TSC_BOOTINFO: size %u howtoflags=0x%08x rootdev='%s'\n", - bip->bi_size, bip->bi_flags, bip->bi_rootdevname); - boothowto = bip->bi_flags; - bootverbose = (boothowto & RB_VERBOSE); - if (bip->bi_rootdevname[0] != 0) - rootdevnames[0] = bip->bi_rootdevname; - } - - /* - * The only way to know if we're in a BGA package (and thus have PIOD) - * is to be told via a hint; there's nothing detectable in the silicon. - * This is esentially an rm92-specific extension to getting the chip ID - * (which was done by at91_machdep just before calling this routine). - * If it is the BGA package, enable the clock for PIOD. - */ - is_bga = 0; - resource_int_value("at91", 0, "is_bga_package", &is_bga); - - if (is_bga) - WR4HW(AT91RM92_PMC_BASE, PMC_PCER, 1u << AT91RM92_IRQ_PIOD); - -#if __FreeBSD_version >= 1000000 - at91rm9200_set_subtype(is_bga ? AT91_ST_RM9200_BGA : - AT91_ST_RM9200_PQFP); -#endif - - /* - * Go reprogram the MCK frequency based on hints. - */ - master_clock_init(); - - /* From this point on you can use printf. */ - - /* - * Configure UARTs. - */ - at91rm9200_config_uart(AT91_ID_DBGU, 0, 0); /* DBGU just Tx and Rx */ - at91rm9200_config_uart(AT91RM9200_ID_USART0, 1, 0); /* Tx and Rx */ - at91rm9200_config_uart(AT91RM9200_ID_USART1, 2, 0); /* Tx and Rx */ - at91rm9200_config_uart(AT91RM9200_ID_USART2, 3, 0); /* Tx and Rx */ - at91rm9200_config_uart(AT91RM9200_ID_USART3, 4, 0); /* Tx and Rx */ - - /* - * Configure MCI (sdcard) - */ - at91rm9200_config_mci(0); - - /* - * Assign the pins needed by the emac device, and power it up. Also, - * configure it for RMII operation unless the 'revmii_mode' hint is set, - * in which case configure the full set of MII pins. The revmii_mode - * hint is for so-called reverse-MII, used for connections to a Broadcom - * 5325E switch on some boards. Note that order is important here: - * configure pins, then power on the device, then access the device's - * config registers. - */ - rev_mii = 0; - resource_int_value("ate", 0, "phy_revmii_mode", &rev_mii); - - at91_pio_use_periph_a(AT91RM92_PIOA_BASE, - AT91C_PIO_PA7 | AT91C_PIO_PA8 | AT91C_PIO_PA9 | - AT91C_PIO_PA10 | AT91C_PIO_PA11 | AT91C_PIO_PA12 | - AT91C_PIO_PA13 | AT91C_PIO_PA14 | AT91C_PIO_PA15 | - AT91C_PIO_PA16, 0); - if (rev_mii) { - at91_pio_use_periph_b(AT91RM92_PIOB_BASE, - AT91C_PIO_PB12 | AT91C_PIO_PB13 | AT91C_PIO_PB14 | - AT91C_PIO_PB15 | AT91C_PIO_PB16 | AT91C_PIO_PB17 | - AT91C_PIO_PB18 | AT91C_PIO_PB19, 0); - } - WR4HW(AT91RM92_PMC_BASE, PMC_PCER, 1u << AT91RM92_IRQ_EMAC); - if (!rev_mii) { - WR4HW(AT91RM92_EMAC_BASE, ETH_CFG, - RD4HW(AT91RM92_EMAC_BASE, ETH_CFG) | ETH_CFG_RMII); - } - - /* - * Get our ethernet MAC address from the ID eeprom. - * Configures TWI as a side effect. - */ - set_mac_from_idprom(); - - /* - * Configure SPI - */ - assign_spi_pins(); - - /* - * Configure SSC - */ - at91_pio_use_periph_a( - AT91RM92_PIOB_BASE, - AT91C_PIO_PB6 | AT91C_PIO_PB7 | AT91C_PIO_PB8 | /* transmit */ - AT91C_PIO_PB9 | AT91C_PIO_PB10 | AT91C_PIO_PB11, /* receive */ - 0); /* no pullup */ - - /* - * We're using TC1's A1 input for PPS measurements that drive the - * kernel PLL and our NTP refclock. On some old boards we route a 5mhz - * signal to TC1's A2 input (pin PA21), but we have never used that - * clock (it rolls over too fast for hz=100), and now newer boards are - * using pin PA21 as a CTS0 for USART1, so we no longer assign it to - * the timer block like we used to here. - */ - at91_pio_use_periph_b(AT91RM92_PIOA_BASE, AT91C_PIO_PA19, 0); - - /* - * Configure pins used to bitbang-upload the firmware to the main FPGA. - */ - at91_pio_use_gpio(AT91RM92_PIOB_BASE, - AT91C_PIO_PB16 | AT91C_PIO_PB17 | AT91C_PIO_PB18 | AT91C_PIO_PB19); - - return (at91_ramsize()); -} - -/* - * Override the default boot param parser (supplied via weak linkage) with one - * that knows how to handle our custom tsc_bootinfo passed in from boot2. - */ -vm_offset_t -parse_boot_param(struct arm_boot_params *abp) -{ - - boot_params = *abp; - - /* - * If the right magic is in r0 and a non-NULL pointer is in r1, then - * it's our bootinfo, copy it. The pointer in r1 is a physical address - * passed from boot2. This routine is called immediately upon entry to - * initarm() and is in very nearly the same environment as boot2. In - * particular, va=pa and we can safely copy the args before we lose easy - * access to the memory they're stashed in right now. - * - * Note that all versions of boot2 that we've ever shipped have put - * zeroes into r2 and r3. Maybe that'll be useful some day. - */ - if (abp->abp_r0 == TSC_BOOTINFO_MAGIC && abp->abp_r1 != 0) { - inkernel_bootinfo = *(struct tsc_bootinfo *)(abp->abp_r1); - } - - return fake_preload_metadata(abp, NULL, 0); -} - -ARM_BOARD(NONE, "TSC4370 Controller Board"); - Index: head/sys/arm/at91/files.at91 =================================================================== --- head/sys/arm/at91/files.at91 +++ head/sys/arm/at91/files.at91 @@ -1,73 +0,0 @@ -# $FreeBSD$ -arm/at91/at91_machdep.c standard -arm/at91/at91_aic.c standard -arm/at91/at91.c standard -arm/at91/at91_aic.c standard -arm/at91/at91_pio.c standard -arm/at91/at91_pmc.c standard -arm/at91/at91_smc.c standard -arm/at91/at91_cfata.c optional at91_cfata -arm/at91/at91_common.c optional fdt -arm/at91/at91_mci.c optional at91_mci -arm/at91/at91_ohci.c optional ohci ! fdt -arm/at91/at91_ohci_fdt.c optional ohci fdt -arm/at91/at91_pinctrl.c optional fdt fdt_pinctrl -arm/at91/at91_pit.c optional at91sam9 -arm/at91/at91_reset.S optional at91sam9 -arm/at91/at91_rst.c optional at91sam9 -arm/at91/at91_rtc.c optional at91_rtc -arm/at91/at91_sdramc.c optional fdt -arm/at91/at91_shdwc.c optional fdt -arm/at91/at91_spi.c optional at91_spi \ - dependency "spibus_if.h" -arm/at91/at91_ssc.c optional at91_ssc -arm/at91/at91_st.c optional at91rm9200 -arm/at91/at91_tcb.c optional fdt -arm/at91/at91_twi.c optional at91_twi -arm/at91/at91_wdt.c optional at91_wdt -arm/at91/if_ate.c optional ate -arm/at91/if_macb.c optional macb -arm/at91/uart_bus_at91usart.c optional uart ! fdt -arm/at91/uart_cpu_at91usart.c optional uart ! fdt -arm/at91/uart_dev_at91usart.c optional uart -dev/uart/uart_cpu_fdt.c optional uart fdt -dev/nand/nfc_at91.c optional nand -# -# All the "systems on a chip" we support -# -arm/at91/at91soc.c standard -arm/at91/at91rm9200.c optional at91rm9200 -arm/at91/at91rm9200_devices.c optional at91rm9200 -arm/at91/at91sam9260.c optional at91sam9260 -arm/at91/at91sam9g20.c optional at91sam9g20 -arm/at91/at91sam9g45.c optional at91sam9g45 -arm/at91/at91sam9x5.c optional at91sam9x5 -# -# All the boards we support -# -arm/at91/board_bwct.c optional at91_board_bwct -arm/at91/board_eb9200.c optional at91_board_eb9200 -arm/at91/board_ethernut5.c optional at91_board_ethernut5 -arm/at91/board_hl200.c optional at91_board_hl200 -arm/at91/board_hl201.c optional at91_board_hl201 -arm/at91/board_kb920x.c optional at91_board_kb920x -arm/at91/board_qila9g20.c optional at91_board_qila9g20 -arm/at91/board_sam9260ek.c optional at91_board_sam9260ek -arm/at91/board_sam9g20ek.c optional at91_board_sam9g20ek -arm/at91/board_sam9x25ek.c optional at91_board_sam9x25ek -arm/at91/board_sn9g45.c optional at91_board_sn9g45 -arm/at91/board_tsc4370.c optional at91_board_tsc4370 -# -# usb -# -# XXX these should likely move to sys/at91 as well. They are also -# XXX slightly inconsistent with sys/conf/files and that ambiguity -# XXX should be fixed when this can be tested on real kit. The dci -# XXX code has hard-coded GPIO pins which is almost certainly wrong. -dev/usb/controller/at91dci.c optional at91_dci -dev/usb/controller/at91dci_atmelarm.c optional at91_dci ! fdt -dev/usb/controller/at91dci_fdt.c optional at91_dci fdt - -# We need this for both FDT and !FDT since we use arm_base_bs_ta -# files.arm picks it up for FDT. -arm/arm/bus_space_base.c optional !fdt Index: head/sys/arm/at91/if_ate.c =================================================================== --- head/sys/arm/at91/if_ate.c +++ head/sys/arm/at91/if_ate.c @@ -1,1532 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2006 M. Warner Losh. - * 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. - */ - -/* TODO - * - * 1) Turn on the clock in pmc? Turn off? - * 2) GPIO initializtion in board setup code. - */ - -#include "opt_platform.h" - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef INET -#include -#include -#include -#include -#endif - -#include -#include - -#include -#include - -#include "opt_at91.h" -#include -#include -#include - -#ifdef FDT -#include -#include -#endif - -#include "miibus_if.h" - -/* - * Driver-specific flags. - */ -#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 ifmib_iso_8802_3 mibdata; /* Stuff for network mgmt */ - 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 -RD4(struct ate_softc *sc, bus_size_t off) -{ - - return (bus_read_4(sc->mem_res, off)); -} - -static inline void -WR4(struct ate_softc *sc, bus_size_t off, uint32_t val) -{ - - bus_write_4(sc->mem_res, off, val); -} - -static inline void -BARRIER(struct ate_softc *sc, bus_size_t off, bus_size_t len, int flags) -{ - - bus_barrier(sc->mem_res, off, len, flags); -} - -#define ATE_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) -#define ATE_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) -#define ATE_LOCK_INIT(_sc) \ - mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \ - MTX_NETWORK_LOCK, MTX_DEF) -#define ATE_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); -#define ATE_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED); -#define ATE_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); - -static devclass_t ate_devclass; - -/* - * ifnet entry points. - */ -static void ateinit_locked(void *); -static void atestart_locked(struct ifnet *); - -static void ateinit(void *); -static void atestart(struct ifnet *); -static void atestop(struct ate_softc *); -static int ateioctl(struct ifnet * ifp, u_long, caddr_t); - -/* - * Bus entry points. - */ -static int ate_probe(device_t dev); -static int ate_attach(device_t dev); -static int ate_detach(device_t dev); -static void ate_intr(void *); - -/* - * Helper routines. - */ -static int ate_activate(device_t dev); -static void ate_deactivate(struct ate_softc *sc); -static int ate_ifmedia_upd(struct ifnet *ifp); -static void ate_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr); -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 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. - * However, FDT makes it self-identifying. - */ -static int -ate_probe(device_t dev) -{ -#ifdef FDT - if (!ofw_bus_is_compatible(dev, "cdns,at91rm9200-emac") && - !ofw_bus_is_compatible(dev, "cdns,emac") && - !ofw_bus_is_compatible(dev, "cdns,at32ap7000-macb")) - return (ENXIO); -#endif - device_set_desc(dev, "EMAC"); - return (0); -} - -#ifdef FDT -/* - * We have to know if we're using MII or RMII attachment - * for the MACB to talk to the PHY correctly. With FDT, - * we must use rmii if there's a proprety phy-mode - * equal to "rmii". Otherwise we MII mode is used. - */ -static void -ate_set_rmii(struct ate_softc *sc) -{ - phandle_t node; - char prop[10]; - ssize_t len; - - node = ofw_bus_get_node(sc->dev); - memset(prop, 0 ,sizeof(prop)); - len = OF_getproplen(node, "phy-mode"); - if (len != 4) - return; - if (OF_getprop(node, "phy-mode", prop, len) != len) - return; - if (strncmp(prop, "rmii", 4) == 0) - sc->use_rmii = 1; -} - -#else -/* - * We have to know if we're using MII or RMII attachment - * for the MACB to talk to the PHY correctly. Without FDT, - * there's no good way to do this. So, if the config file - * has 'option AT91_ATE_USE_RMII', then we'll force RMII. - * Otherwise, we'll use what the bootloader setup. Either - * it setup RMII or MII, in which case we'll get it right, - * or it did nothing, and we'll fall back to MII and the - * option would override if present. - */ -static void -ate_set_rmii(struct ate_softc *sc) -{ - - /* 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 -} -#endif - -static int -ate_attach(device_t dev) -{ - struct ate_softc *sc; - struct ifnet *ifp = NULL; - struct sysctl_ctx_list *sctx; - struct sysctl_oid *soid; - u_char eaddr[ETHER_ADDR_LEN]; - uint32_t rnd; - int rid, err; - - sc = device_get_softc(dev); - sc->dev = dev; - ATE_LOCK_INIT(sc); - - 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); - if (sc->irq_res == NULL) { - device_printf(dev, "could not allocate interrupt resources.\n"); - err = ENOMEM; - goto out; - } - - /* New or old version, chooses buffer size. */ -#ifdef FDT - sc->is_emacb = ofw_bus_is_compatible(dev, "cdns,at32ap7000-macb"); -#else - sc->is_emacb = at91_is_sam9() || at91_is_sam9xe(); -#endif - sc->rx_buf_size = RX_BUF_SIZE(sc); - - err = ate_activate(dev); - if (err) - goto out; - - ate_set_rmii(sc); - - /* Sysctls */ - sctx = device_get_sysctl_ctx(dev); - soid = device_get_sysctl_tree(dev); - SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "rmii", - 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) - device_printf(dev, - "Generating random ethernet address.\n"); - rnd = arc4random(); - - /* - * Set OUI to convenient locally assigned address. 'b' - * is 0x62, which has the locally assigned bit set, and - * the broadcast/multicast bit clear. - */ - eaddr[0] = 'b'; - eaddr[1] = 's'; - eaddr[2] = 'd'; - eaddr[3] = (rnd >> 16) & 0xff; - eaddr[4] = (rnd >> 8) & 0xff; - eaddr[5] = (rnd >> 0) & 0xff; - } - - sc->ifp = ifp = if_alloc(IFT_ETHER); - err = mii_attach(dev, &sc->miibus, ifp, ate_ifmedia_upd, - ate_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0); - if (err != 0) { - device_printf(dev, "attaching PHYs failed\n"); - 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)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_capabilities |= IFCAP_VLAN_MTU; - ifp->if_capenable |= IFCAP_VLAN_MTU; /* The hw bits already set. */ - ifp->if_start = atestart; - ifp->if_ioctl = ateioctl; - ifp->if_init = ateinit; - ifp->if_baudrate = 10000000; - 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); - sc->mibdata.dot3Compliance = DOT3COMPLIANCE_COLLS; - sc->if_flags = ifp->if_flags; - - ether_ifattach(ifp, eaddr); - - /* Activate the interrupt. */ - err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE, - NULL, ate_intr, sc, &sc->intrhand); - if (err) { - device_printf(dev, "could not establish interrupt handler.\n"); - ether_ifdetach(ifp); - goto out; - } - -out: - if (err) - ate_detach(dev); - return (err); -} - -static int -ate_detach(device_t dev) -{ - struct ate_softc *sc; - struct ifnet *ifp; - - sc = device_get_softc(dev); - KASSERT(sc != NULL, ("[ate: %d]: sc is NULL", __LINE__)); - ifp = sc->ifp; - if (device_is_attached(dev)) { - ATE_LOCK(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); - sc->miibus = NULL; - } - bus_generic_detach(sc->dev); - ate_deactivate(sc); - if (sc->intrhand != NULL) { - bus_teardown_intr(dev, sc->irq_res, sc->intrhand); - sc->intrhand = NULL; - } - if (ifp != NULL) { - if_free(ifp); - sc->ifp = NULL; - } - if (sc->mem_res != NULL) { - bus_release_resource(dev, SYS_RES_IOPORT, - rman_get_rid(sc->mem_res), sc->mem_res); - sc->mem_res = NULL; - } - if (sc->irq_res != NULL) { - bus_release_resource(dev, SYS_RES_IRQ, - rman_get_rid(sc->irq_res), sc->irq_res); - sc->irq_res = NULL; - } - ATE_LOCK_DESTROY(sc); - return (0); -} - -static void -ate_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error) -{ - - if (error != 0) - return; - *(bus_addr_t *)arg = segs[0].ds_addr; -} - -static void -ate_load_rx_buf(void *arg, bus_dma_segment_t *segs, int nsegs, int error) -{ - struct ate_softc *sc; - - if (error != 0) - return; - sc = (struct ate_softc *)arg; - - bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, BUS_DMASYNC_PREWRITE); - 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); -} - -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); -} - -/* - * Compute the multicast filter for this device. - */ -static int -ate_setmcast(struct ate_softc *sc) -{ - uint32_t index; - uint32_t mcaf[2]; - u_char *af = (u_char *) mcaf; - struct ifmultiaddr *ifma; - struct ifnet *ifp; - - ifp = sc->ifp; - - if ((ifp->if_flags & IFF_PROMISC) != 0) - return (0); - if ((ifp->if_flags & IFF_ALLMULTI) != 0) { - WR4(sc, ETH_HSL, 0xffffffff); - WR4(sc, ETH_HSH, 0xffffffff); - return (1); - } - - /* Compute the multicast hash. */ - mcaf[0] = 0; - mcaf[1] = 0; - if_maddr_rlock(ifp); - CK_STAILQ_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)); - af[index >> 3] |= 1 << (index & 7); - } - if_maddr_runlock(ifp); - - /* - * Write the hash to the hash register. This card can also - * accept unicast packets as well as multicast packets using this - * register for easier bridging operations, but we don't take - * advantage of that. Locks here are to avoid LOR with the - * if_maddr_rlock, but might not be strictly necessary. - */ - WR4(sc, ETH_HSL, mcaf[0]); - WR4(sc, ETH_HSH, mcaf[1]); - return (mcaf[0] || mcaf[1]); -} - -static int -ate_activate(device_t dev) -{ - struct ate_softc *sc; - int i; - - sc = device_get_softc(dev); - - /* 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)) - goto errout; - for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) { - if ( bus_dmamap_create(sc->mtag, 0, &sc->tx_map[i])) - goto errout; - } - - - /* 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_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_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. - * XXX On MACB (SAM9 part) we should receive directly into mbuf - * to avoid the copy. XXX - */ - 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->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); - } - - /* - * 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. - */ - 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; - - /* Initialize 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 */ - WR4(sc, ETHB_UIO, RD4(sc, ETHB_UIO) | ETHB_UIO_CLKE); - } - - return (0); - -errout: - return (ENOMEM); -} - -static void -ate_deactivate(struct ate_softc *sc) -{ - int i; - - KASSERT(sc != NULL, ("[ate, %d]: sc is NULL!", __LINE__)); - if (sc->mtag != NULL) { - for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) { - if (sc->sent_mbuf[i] != NULL) { - bus_dmamap_sync(sc->mtag, sc->tx_map[i], - BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->mtag, sc->tx_map[i]); - m_freem(sc->sent_mbuf[i]); - } - bus_dmamap_destroy(sc->mtag, sc->tx_map[i]); - sc->sent_mbuf[i] = NULL; - sc->tx_map[i] = NULL; - } - bus_dma_tag_destroy(sc->mtag); - } - if (sc->rx_desc_tag != NULL) { - if (sc->rx_descs != NULL) { - if (sc->rx_desc_phys != 0) { - bus_dmamap_sync(sc->rx_desc_tag, - sc->rx_desc_map, BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(sc->rx_desc_tag, - sc->rx_desc_map); - sc->rx_desc_phys = 0; - } - } - } - 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_descs[i].addr = 0; - } - bus_dmamem_free(sc->rx_tag, sc->rx_buf[i], - sc->rx_map[i]); - sc->rx_buf[i] = NULL; - } - bus_dma_tag_destroy(sc->rx_tag); - } - if (sc->rx_desc_tag != NULL) { - if (sc->rx_descs != NULL) - bus_dmamem_free(sc->rx_desc_tag, sc->rx_descs, - sc->rx_desc_map); - bus_dma_tag_destroy(sc->rx_desc_tag); - sc->rx_descs = NULL; - sc->rx_desc_tag = NULL; - } - - if (sc->is_emacb) - WR4(sc, ETHB_UIO, RD4(sc, ETHB_UIO) & ~ETHB_UIO_CLKE); -} - -/* - * Change media according to request. - */ -static int -ate_ifmedia_upd(struct ifnet *ifp) -{ - struct ate_softc *sc = ifp->if_softc; - struct mii_data *mii; - - mii = device_get_softc(sc->miibus); - ATE_LOCK(sc); - mii_mediachg(mii); - ATE_UNLOCK(sc); - return (0); -} - -/* - * Notify the world which media we're using. - */ -static void -ate_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) -{ - struct ate_softc *sc = ifp->if_softc; - struct mii_data *mii; - - mii = device_get_softc(sc->miibus); - ATE_LOCK(sc); - mii_pollstat(mii); - ifmr->ifm_active = mii->mii_media_active; - ifmr->ifm_status = mii->mii_media_status; - ATE_UNLOCK(sc); -} - -static void -ate_stat_update(struct ate_softc *sc, int active) -{ - uint32_t reg; - - /* - * The speed and full/half-duplex state needs to be reflected - * in the ETH_CFG register. - */ - reg = RD4(sc, ETH_CFG); - reg &= ~(ETH_CFG_SPD | ETH_CFG_FD); - if (IFM_SUBTYPE(active) != IFM_10_T) - reg |= ETH_CFG_SPD; - if (active & IFM_FDX) - reg |= ETH_CFG_FD; - WR4(sc, ETH_CFG, reg); -} - -static void -ate_tick(void *xsc) -{ - struct ate_softc *sc = xsc; - struct ifnet *ifp = sc->ifp; - struct mii_data *mii; - int active; - uint32_t c; - - /* - * The KB920x boot loader tests ETH_SR & ETH_SR_LINK and will ask - * the MII if there's a link if this bit is clear. Not sure if we - * should do the same thing here or not. - */ - ATE_ASSERT_LOCKED(sc); - if (sc->miibus != NULL) { - mii = device_get_softc(sc->miibus); - active = mii->mii_media_active; - mii_tick(mii); - if (mii->mii_media_status & IFM_ACTIVE && - active != mii->mii_media_active) - ate_stat_update(sc, mii->mii_media_active); - } - - /* - * Update the stats as best we can. When we're done, clear - * the status counters and start over. We're supposed to read these - * registers often enough that they won't overflow. Hopefully - * once a second is often enough. Some don't map well to - * the dot3Stats mib, so for those we just count them as general - * errors. Stats for iframes, ibutes, oframes and obytes are - * collected elsewhere. These registers zero on a read to prevent - * races. For all the collision stats, also update the collision - * stats for the interface. - */ - sc->mibdata.dot3StatsAlignmentErrors += RD4(sc, ETH_ALE); - sc->mibdata.dot3StatsFCSErrors += RD4(sc, ETH_SEQE); - c = RD4(sc, ETH_SCOL); - if_inc_counter(ifp, IFCOUNTER_COLLISIONS, c); - sc->mibdata.dot3StatsSingleCollisionFrames += c; - c = RD4(sc, ETH_MCOL); - sc->mibdata.dot3StatsMultipleCollisionFrames += c; - if_inc_counter(ifp, IFCOUNTER_COLLISIONS, c); - sc->mibdata.dot3StatsSQETestErrors += RD4(sc, ETH_SQEE); - sc->mibdata.dot3StatsDeferredTransmissions += RD4(sc, ETH_DTE); - c = RD4(sc, ETH_LCOL); - sc->mibdata.dot3StatsLateCollisions += c; - if_inc_counter(ifp, IFCOUNTER_COLLISIONS, c); - c = RD4(sc, ETH_ECOL); - sc->mibdata.dot3StatsExcessiveCollisions += c; - if_inc_counter(ifp, IFCOUNTER_COLLISIONS, c); - sc->mibdata.dot3StatsCarrierSenseErrors += RD4(sc, ETH_CSE); - sc->mibdata.dot3StatsFrameTooLongs += RD4(sc, ETH_ELR); - sc->mibdata.dot3StatsInternalMacReceiveErrors += RD4(sc, ETH_DRFC); - - /* - * Not sure where to lump these, so count them against the errors - * for the interface. - */ - if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, RD4(sc, ETH_TUE)); - if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, - RD4(sc, ETH_CDE) + RD4(sc, ETH_RJB) + RD4(sc, ETH_USF)); - - /* Schedule another timeout one second from now. */ - callout_reset(&sc->tick_ch, hz, ate_tick, sc); -} - -static void -ate_set_mac(struct ate_softc *sc, u_char *eaddr) -{ - - WR4(sc, ETH_SA1L, (eaddr[3] << 24) | (eaddr[2] << 16) | - (eaddr[1] << 8) | eaddr[0]); - WR4(sc, ETH_SA1H, (eaddr[5] << 8) | (eaddr[4])); -} - -static int -ate_get_mac(struct ate_softc *sc, u_char *eaddr) -{ - bus_size_t sa_low_reg[] = { ETH_SA1L, ETH_SA2L, ETH_SA3L, ETH_SA4L }; - bus_size_t sa_high_reg[] = { ETH_SA1H, ETH_SA2H, ETH_SA3H, ETH_SA4H }; - uint32_t low, high; - int i; - - /* - * 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]); - high = RD4(sc, sa_high_reg[i]); - if ((low | (high & 0xffff)) != 0) { - eaddr[0] = low & 0xff; - eaddr[1] = (low >> 8) & 0xff; - eaddr[2] = (low >> 16) & 0xff; - eaddr[3] = (low >> 24) & 0xff; - eaddr[4] = high & 0xff; - eaddr[5] = (high >> 8) & 0xff; - return (0); - } - } - return (ENXIO); -} - -static void -ate_intr(void *xsc) -{ - struct ate_softc *sc = xsc; - struct ifnet *ifp = sc->ifp; - struct mbuf *mb; - 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_DMASYNC_POSTREAD); - - 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 length 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; - } - - /* 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. */ - mb = m_get2(remain + ETHER_ALIGN, M_NOWAIT, MT_DATA, - M_PKTHDR); - if (mb == NULL) { - if_inc_counter(sc->ifp, IFCOUNTER_IQDROPS, 1); - 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 descriptor. */ - 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 - * receive directly to mbufs if not an - * RM9200. And even then we could likely - * copy just the protocol headers. 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_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); - (*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->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->tx_descs[sc->txtail].status & ETHB_TX_USED) && - sc->sent_mbuf[sc->txtail] != NULL) { - bus_dmamap_sync(sc->mtag, sc->tx_map[sc->txtail], - BUS_DMASYNC_POSTWRITE); - 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; - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - 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. - */ - sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - atestart_locked(sc->ifp); - ATE_UNLOCK(sc); - } - - if (status & ETH_ISR_RBNA) { - /* Workaround RM9200 Errata #11 */ - if (bootverbose) - device_printf(sc->dev, "RBNA workaround\n"); - reg = RD4(sc, ETH_CTL); - WR4(sc, ETH_CTL, reg & ~ETH_CTL_RE); - BARRIER(sc, ETH_CTL, 4, BUS_SPACE_BARRIER_WRITE); - WR4(sc, ETH_CTL, reg | ETH_CTL_RE); - } - - /* XXX need to work around SAM9260 errata 43.2.4.1: - * disable the mac, reset tx buffer, enable mac on TUND */ -} - -/* - * Reset and initialize the chip. - */ -static void -ateinit_locked(void *xsc) -{ - struct ate_softc *sc = xsc; - struct ifnet *ifp = sc->ifp; - struct mii_data *mii; - uint8_t eaddr[ETHER_ADDR_LEN]; - uint32_t reg; - - ATE_ASSERT_LOCKED(sc); - - /* - * XXX TODO(3) - * we need to turn on the EMAC clock in the pmc. With the - * default boot loader, this is already turned on. However, we - * 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 (in board_xxx.c). - */ - - /* - * There are two different ways that the mii bus is connected - * to this chip mii or rmii. - */ - 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); - - /* - * Set the chip MAC address. - */ - 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. - */ - WR4(sc, ETH_CTL, RD4(sc, ETH_CTL) | ETH_CTL_TE | ETH_CTL_RE); - WR4(sc, ETH_IER, ETH_ISR_RCOM | ETH_ISR_TCOM | ETH_ISR_RBNA); - - /* Enable big packets. */ - WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_BIG); - - /* - * Set 'running' flag, and clear output active flag - * and attempt to start the output. - */ - ifp->if_drv_flags |= IFF_DRV_RUNNING; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - - mii = device_get_softc(sc->miibus); - mii_pollstat(mii); - ate_stat_update(sc, mii->mii_media_active); - atestart_locked(ifp); - - callout_reset(&sc->tick_ch, hz, ate_tick, sc); -} - -/* - * Dequeue packets and transmit. - */ -static void -atestart_locked(struct ifnet *ifp) -{ - struct ate_softc *sc = ifp->if_softc; - struct mbuf *m, *mdefrag; - bus_dma_segment_t segs[1]; - int nseg, e; - - ATE_ASSERT_LOCKED(sc); - if (ifp->if_drv_flags & IFF_DRV_OACTIVE) - return; - - 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 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)." - */ - /* 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 == NULL) - 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_NOWAIT); - if (mdefrag == NULL) { - IFQ_DRV_PREPEND(&ifp->if_snd, m); - return; - } - m = mdefrag; - e = bus_dmamap_load_mbuf_sg(sc->mtag, - sc->tx_map[sc->txhead], m, segs, &nseg, 0); - } - if (e != 0) { - m_freem(m); - continue; - } - - /* - * There's a small race between the loop in ate_intr finishing - * and the check above to see if the packet was finished, as well - * as when atestart gets called via other paths. Lose the race - * gracefully and free the mbuf... - */ - if (sc->sent_mbuf[sc->txhead] != NULL) { - bus_dmamap_sync(sc->mtag, sc->tx_map[sc->txtail], - BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->mtag, sc->tx_map[sc->txtail]); - m_free(sc->sent_mbuf[sc->txhead]); - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - } - - 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. */ - 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. */ - BPF_MTAP(ifp, m); - } - - if ((sc->tx_descs[sc->txhead].status & ETHB_TX_USED) == 0) - ifp->if_drv_flags |= IFF_DRV_OACTIVE; -} - -static void -ateinit(void *xsc) -{ - struct ate_softc *sc = xsc; - - ATE_LOCK(sc); - ateinit_locked(sc); - ATE_UNLOCK(sc); -} - -static void -atestart(struct ifnet *ifp) -{ - struct ate_softc *sc = ifp->if_softc; - - ATE_LOCK(sc); - atestart_locked(ifp); - ATE_UNLOCK(sc); -} - -/* - * Turn off interrupts, and stop the NIC. Can be called with sc->ifp NULL, - * so be careful. - */ -static void -atestop(struct ate_softc *sc) -{ - struct ifnet *ifp; - int i; - - ATE_ASSERT_LOCKED(sc); - ifp = sc->ifp; - if (ifp) { - //ifp->if_timer = 0; - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - } - - callout_stop(&sc->tick_ch); - - /* - * Enable some parts of the MAC that are needed always (like the - * MII bus. This turns off the RE and TE bits, which will remain - * off until ateinit() is called to turn them on. With RE and TE - * turned off, there's no DMA to worry about after this write. - */ - WR4(sc, ETH_CTL, ETH_CTL_MPE); - - /* - * Turn off all the configured options and revert to defaults. - */ - - /* 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 - * the ISR. - */ - WR4(sc, ETH_IDR, 0xffffffff); - RD4(sc, ETH_ISR); - - /* - * Clear out the Transmit and Receiver Status registers of any - * errors they may be reporting - */ - WR4(sc, ETH_TSR, 0xffffffff); - WR4(sc, ETH_RSR, 0xffffffff); - - /* 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], - BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->mtag, sc->tx_map[i]); - m_freem(sc->sent_mbuf[i]); - sc->sent_mbuf[i] = NULL; - } - } - - /* 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 - * to the datasheet. - */ -} - -static void -ate_rxfilter(struct ate_softc *sc) -{ - struct ifnet *ifp; - uint32_t reg; - int enabled; - - KASSERT(sc != NULL, ("[ate, %d]: sc is NULL!", __LINE__)); - ATE_ASSERT_LOCKED(sc); - ifp = sc->ifp; - - /* 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. */ - if ((ifp->if_flags & IFF_BROADCAST) != 0) - reg &= ~ETH_CFG_NBC; - if ((ifp->if_flags & IFF_PROMISC) != 0) { - reg |= ETH_CFG_CAF; - } else { - enabled = ate_setmcast(sc); - if (enabled != 0) { - reg |= ETH_CFG_MTI; - sc->flags |= ATE_FLAG_MULTICAST; - } - } - WR4(sc, ETH_CFG, reg); -} - -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; - int drv_flags, flags; - int mask, error, enabled; - - error = 0; - flags = ifp->if_flags; - drv_flags = ifp->if_drv_flags; - switch (cmd) { - case SIOCSIFFLAGS: - ATE_LOCK(sc); - if ((flags & IFF_UP) != 0) { - if ((drv_flags & IFF_DRV_RUNNING) != 0) { - if (((flags ^ sc->if_flags) - & (IFF_PROMISC | IFF_ALLMULTI)) != 0) - ate_rxfilter(sc); - } else { - 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; - ATE_UNLOCK(sc); - break; - - case SIOCADDMULTI: - case SIOCDELMULTI: - if ((drv_flags & IFF_DRV_RUNNING) != 0) { - ATE_LOCK(sc); - enabled = ate_setmcast(sc); - if (enabled != (sc->flags & ATE_FLAG_MULTICAST)) - ate_rxfilter(sc); - ATE_UNLOCK(sc); - } - 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) { - ATE_LOCK(sc); - if (ifr->ifr_reqcap & IFCAP_VLAN_MTU) { - WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_BIG); - ifp->if_capenable |= IFCAP_VLAN_MTU; - } else { - WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) & ~ETH_CFG_BIG); - ifp->if_capenable &= ~IFCAP_VLAN_MTU; - } - ATE_UNLOCK(sc); - } - default: - error = ether_ioctl(ifp, cmd, data); - break; - } - return (error); -} - -static void -ate_child_detached(device_t dev, device_t child) -{ - struct ate_softc *sc; - - sc = device_get_softc(dev); - if (child == sc->miibus) - sc->miibus = NULL; -} - -/* - * MII bus support routines. - */ -static int -ate_miibus_readreg(device_t dev, int phy, int reg) -{ - struct ate_softc *sc; - int val; - - /* - * XXX if we implement aggressive power savings, then we need - * XXX to make sure that the clock to the emac is on here - */ - - sc = device_get_softc(dev); - DELAY(1); /* Hangs w/o this delay really 30.5us atm */ - WR4(sc, ETH_MAN, ETH_MAN_REG_RD(phy, reg)); - while ((RD4(sc, ETH_SR) & ETH_SR_IDLE) == 0) - continue; - val = RD4(sc, ETH_MAN) & ETH_MAN_VALUE_MASK; - - return (val); -} - -static int -ate_miibus_writereg(device_t dev, int phy, int reg, int data) -{ - struct ate_softc *sc; - - /* - * XXX if we implement aggressive power savings, then we need - * XXX to make sure that the clock to the emac is on here - */ - - sc = device_get_softc(dev); - WR4(sc, ETH_MAN, ETH_MAN_REG_WR(phy, reg, data)); - while ((RD4(sc, ETH_SR) & ETH_SR_IDLE) == 0) - continue; - return (0); -} - -static device_method_t ate_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, ate_probe), - DEVMETHOD(device_attach, ate_attach), - DEVMETHOD(device_detach, ate_detach), - - /* Bus interface */ - DEVMETHOD(bus_child_detached, ate_child_detached), - - /* MII interface */ - DEVMETHOD(miibus_readreg, ate_miibus_readreg), - DEVMETHOD(miibus_writereg, ate_miibus_writereg), - - DEVMETHOD_END -}; - -static driver_t ate_driver = { - "ate", - ate_methods, - sizeof(struct ate_softc), -}; - -#ifdef FDT -DRIVER_MODULE(ate, simplebus, ate_driver, ate_devclass, NULL, NULL); -#else -DRIVER_MODULE(ate, atmelarm, ate_driver, ate_devclass, NULL, NULL); -#endif -DRIVER_MODULE(miibus, ate, miibus_driver, miibus_devclass, NULL, NULL); -MODULE_DEPEND(ate, miibus, 1, 1, 1); -MODULE_DEPEND(ate, ether, 1, 1, 1); Index: head/sys/arm/at91/if_atereg.h =================================================================== --- head/sys/arm/at91/if_atereg.h +++ head/sys/arm/at91/if_atereg.h @@ -1,216 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2006 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $FreeBSD$ */ - -#ifndef ARM_AT91_IF_ATEREG_H -#define ARM_AT91_IF_ATEREG_H - -/* Defines beginning ETHB_ are EMACB (newer SAM9 hardware) versions only. */ - -#define ETH_CTL 0x00 /* EMAC Control Register */ -#define ETH_CFG 0x04 /* EMAC Configuration Register */ -#define ETH_SR 0x08 /* EMAC STatus Register */ -#define ETH_TAR 0x0c /* EMAC Transmit Address Register */ -#define ETH_TCR 0x10 /* EMAC Transmit Control Register */ -#define ETH_TSR 0x14 /* EMAC Transmit Status Register */ -#define ETH_RBQP 0x18 /* EMAC Receive Buffer Queue Pointer */ -#define ETHB_TBQP 0x1c /* reserved */ -#define ETH_RSR 0x20 /* EMAC Receive Status Register */ -#define ETH_ISR 0x24 /* EMAC Interrupt Status Register */ -#define ETH_IER 0x28 /* EMAC Interrupt Enable Register */ -#define ETH_IDR 0x2c /* EMAC Interrupt Disable Register */ -#define ETH_IMR 0x30 /* EMAC Interrupt Mask Register */ -#define ETH_MAN 0x34 /* EMAC PHY Maintenance Register */ - /* 0x38 reserved */ - /* 0x3c reserved */ -#define ETH_FRA 0x40 /* Frames Transmitted OK Register */ -#define ETH_SCOL 0x44 /* Single Collision Frame Register */ -#define ETH_MCOL 0x48 /* Multiple Collision Frame Register */ -#define ETH_OK 0x4c /* Frames Received OK Register */ -#define ETH_SEQE 0x50 /* Frame Check Sequence Error Reg */ -#define ETH_ALE 0x54 /* Alignment Error Register */ -#define ETH_DTE 0x58 /* Deferred Transmittion Frame Reg */ -#define ETH_LCOL 0x5c /* Late Collision Register */ -#define ETH_ECOL 0x60 /* Excessive Collision Register */ -#define ETH_TUE 0x64 /* Transmit Underrun Error Register */ -#define ETH_CSE 0x68 /* Carrier Sense Error Register */ -#define ETH_DRFC 0x6c /* Discarded RX Frame Register */ -#define ETH_ROV 0x68 /* Receive Overrun Register */ -#define ETH_CDE 0x64 /* Code Error Register */ -#define ETH_ELR 0x78 /* Excessive Length Error Register */ -#define ETH_RJB 0x7c /* Receive Jabber Register */ -#define ETH_USF 0x80 /* Undersize Frame Register */ -#define ETH_SQEE 0x84 /* SQE Test Error Register */ - /* 0x88 reserved */ - /* 0x8c reserved */ -#define ETH_HSL 0x90 /* EMAC Hash Address Low [31:0] */ -#define ETH_HSH 0x94 /* EMAC Hash Address High [63:32] */ -#define ETH_SA1L 0x98 /* EMAC Specific Address 1 Low */ -#define ETH_SA1H 0x9c /* EMAC Specific Address 1 High */ -#define ETH_SA2L 0xa0 /* EMAC Specific Address 2 Low */ -#define ETH_SA2H 0xa4 /* EMAC Specific Address 2 High */ -#define ETH_SA3L 0xa8 /* EMAC Specific Address 3 Low */ -#define ETH_SA3H 0xac /* EMAC Specific Address 3 High */ -#define ETH_SA4L 0xb0 /* EMAC Specific Address 4 Low */ -#define ETH_SA4H 0xb4 /* EMAC Specific Address 4 High */ -#define ETHB_TID 0xb8 /* EMAC Type ID Checking */ -#define ETHB_UIO 0xC0 /* EMAC User I/O Reg */ - - -/* ETH_CTL */ -#define ETH_CTL_LB (1U << 0) /* LB: Loopback */ -#define ETH_CTL_LBL (1U << 1) /* LBL: Loopback Local */ -#define ETH_CTL_RE (1U << 2) /* RE: Receive Enable */ -#define ETH_CTL_TE (1U << 3) /* TE: Transmit Enable */ -#define ETH_CTL_MPE (1U << 4) /* MPE: Management Port Enable */ -#define ETH_CTL_CSR (1U << 5) /* CSR: Clear Statistics Registers */ -#define ETH_CTL_ISR (1U << 6) /* ISR: Incremenet Statistics Regs */ -#define ETH_CTL_WES (1U << 7) /* WES: Write Enable Statistics regs */ -#define ETH_CTL_BP (1U << 8) /* BP: Back Pressure */ - -#define ETHB_CTL_TGO (1U << 9) /* TGO: Transmitter Start */ -#define ETHB_CTL_TSTP (1U << 10) /* TSTP: Transmitter Stop */ - -/* ETH_CFG */ -#define ETH_CFG_SPD (1U << 0) /* SPD: Speed 1 == 100: 0 == 10 */ -#define ETH_CFG_FD (1U << 1) /* FD: Full duplex */ -#define ETH_CFG_BR (1U << 2) /* BR: Bit Rate (optional?) */ - /* bit 3 reserved */ -#define ETH_CFG_CAF (1U << 4) /* CAF: Copy All Frames */ -#define ETH_CFG_NBC (1U << 5) /* NBC: No Broadcast */ -#define ETH_CFG_MTI (1U << 6) /* MTI: Multicast Hash Enable */ -#define ETH_CFG_UNI (1U << 7) /* UNI: Unicast Hash Enable */ -#define ETH_CFG_BIG (1U << 8) /* BIG: Receive 1522 Bytes */ -#define ETH_CFG_EAE (1U << 9) /* EAE: External Address Match En */ -#define ETH_CFG_CLK_8 (0U << 10) /* CLK: Clock / 8 */ -#define ETH_CFG_CLK_16 (1U << 10) /* CLK: Clock / 16 */ -#define ETH_CFG_CLK_32 (2U << 10) /* CLK: Clock / 32 */ -#define ETH_CFG_CLK_64 (3U << 10) /* CLK: Clock / 64 */ -#define ETH_CFG_RTY (1U << 12) /* RTY: Retry Test*/ -#define ETH_CFG_RMII (1U << 13) /* RMII: Reduce MII */ - -#define ETHB_CFG_JBO (1U << 3) /* JBO: Jumbo Frames */ -#define ETHB_CFG_PAE (1U << 13) /* PAE: Pause Enable */ -#define ETHB_CFG_RBOF_0 (0U << 14) /* RBOF: Rx Buffer Offset */ -#define ETHB_CFG_RBOF_1 (1U << 14) /* RBOF: Rx Buffer Offset */ -#define ETHB_CFG_RBOF_2 (3U << 14) /* RBOF: Rx Buffer Offset */ -#define ETHB_CFG_RBOF_3 (3U << 14) /* RBOF: Rx Buffer Offset */ -#define ETHB_CFG_RCLE (1U << 16) /* RCLE: Rx Length Check Enable */ -#define ETHB_CFG_DRFC (1U << 17) /* DRFC: Discard Rx FCS */ -#define ETHB_CFG_RHD (1U << 18) /* RHD: RX TX'ed frame in half-duplex */ -#define ETHB_CFG_IFCS (1U << 19) /* IFCS: Ignore bad RX FCS */ - -/* ETH_SR */ -#define ETH_SR_LINK (1U << 0) /* Reserved! */ -#define ETH_SR_MDIO (1U << 1) /* MDIO pin status */ -#define ETH_SR_IDLE (1U << 2) /* IDLE (PHY logic) */ - -/* ETH_TCR */ -#define ETH_TCR_NCRC (1U << 15) /* NCRC: No CRC */ - -/* ETH_TSR */ -#define ETH_TSR_OVR (1U << 0) /* OVR: Ethernet Transmit Overrun */ -#define ETH_TSR_COL (1U << 1) /* COL: Collision Occurred */ -#define ETH_TSR_RLE (1U << 2) /* RLE: Retry Limit Exceeded */ -#define ETH_TSR_IDLE (1U << 3) /* IDLE: Transmitter Idle */ -#define ETH_TSR_BNQ (1U << 4) /* BNQ: Enet Tran Buff not Queued */ -#define ETH_TSR_COMP (1U << 5) /* COMP: Transmit Complete */ -#define ETH_TSR_UND (1U << 6) /* UND: Transmit Underrun */ -#define ETH_TSR_WR_MASK (0x67) /* write 1 to clear bits */ - -/* ETH_RSR */ -#define ETH_RSR_BNA (1U << 0) /* BNA: Buffer Not Available */ -#define ETH_RSR_REC (1U << 1) /* REC: Frame Received */ -#define ETH_RSR_OVR (1U << 2) /* OVR: RX Overrun */ - -/* ETH_ISR */ -#define ETH_ISR_DONE (1U << 0) /* DONE: Management Done */ -#define ETH_ISR_RCOM (1U << 1) /* RCOM: Receive Complete */ -#define ETH_ISR_RBNA (1U << 2) /* RBNA: Receive Buffer Not Avail */ -#define ETH_ISR_TOVR (1U << 3) /* TOVR: Transmit Buffer Overrun */ -#define ETH_ISR_TUND (1U << 4) /* TUND: Transmit Buffer Underrun */ -#define ETH_ISR_RTRY (1U << 5) /* RTRY: Retry Limit */ -#define ETH_ISR_TBRE (1U << 6) /* TBRE: Trasnmit Buffer Reg empty */ -#define ETH_ISR_TCOM (1U << 7) /* TCOM: Transmit Complete */ -#define ETH_ISR_TIDLE (1U << 8) /* TIDLE: Transmit Idle */ -#define ETH_ISR_LINK (1U << 9) /* LINK: Link pin delta (optional) */ -#define ETH_ISR_ROVR (1U << 10) /* ROVR: RX Overrun */ -#define ETH_ISR_ABT (1U << 11) /* ABT: Abort */ - -/* ETHB_UIO */ -#define ETHB_UIO_RMII (1U << 0) /* RMII: Reduce MII */ -#define ETHB_UIO_CLKE (1U << 1) /* CLKE: Clock Enable */ - -/* ETH_MAN */ -#define ETH_MAN_BITS 0x40020000 /* HIGH and CODE bits */ -#define ETH_MAN_READ (2U << 28) -#define ETH_MAN_WRITE (1U << 28) -#define ETH_MAN_PHYA_BIT 23 -#define ETH_MAN_REGA_BIT 18 -#define ETH_MAN_VALUE_MASK 0xffffU -#define ETH_MAN_REG_WR(phy, reg, val) \ - (ETH_MAN_BITS | ETH_MAN_WRITE | ((phy) << ETH_MAN_PHYA_BIT) | \ - ((reg) << ETH_MAN_REGA_BIT) | ((val) & ETH_MAN_VALUE_MASK)) -#define ETH_MAN_REG_RD(phy, reg) \ - (ETH_MAN_BITS | ETH_MAN_READ | ((phy) << ETH_MAN_PHYA_BIT) | \ - ((reg) << ETH_MAN_REGA_BIT)) - -typedef struct { - uint32_t addr; -#define ETH_CPU_OWNER (1U << 0) -#define ETH_WRAP_BIT (1U << 1) -#define ETH_ADR_MASK ~(EHT_CPU_OWNER | ETH_WRAP_BIT) - uint32_t status; -#define ETH_LEN_MASK 0x7ff -#define ETH_BUF_FIRST (1U << 14) /* Packet matched addr 4 */ -#define ETH_BUF_LAST (1U << 15) /* Packet matched addr 4 */ -#define ETH_MAC_LOCAL_4 (1U << 23) /* Packet matched addr 4 */ -#define ETH_MAC_LOCAL_3 (1U << 24) /* Packet matched addr 3 */ -#define ETH_MAC_LOCAL_2 (1U << 25) /* Packet matched addr 2 */ -#define ETH_MAC_LOCAL_1 (1U << 26) /* Packet matched addr 1 */ -#define ETH_MAC_UNK (1U << 27) /* Unknown source address RFU */ -#define ETH_MAC_EXT (1U << 28) /* External Address */ -#define ETH_MAC_UCAST (1U << 29) /* Unicast hash match */ -#define ETH_MAC_MCAST (1U << 30) /* Multicast hash match */ -#define ETH_MAC_ONES (1U << 31) /* Global all ones bcast addr */ -} eth_rx_desc_t; - -typedef struct { - uint32_t addr; - uint32_t status; -#define ETHB_TX_LEN_MASK 0x7ff -#define ETHB_TX_BUF_LAST (1U << 15) /* Last buffer in packet */ -#define ETHB_TX_NOCRC (1U << 16) /* Don't xmit CRC*/ -#define ETHB_TX_BUFE (1U << 27) /* Buffers exhausted mid frame */ -#define ETHB_TX_TUND (1U << 28) /* Transmit Underrun */ -#define ETHB_TX_RTRYE (1U << 29) /* Re-try limit exceeded */ -#define ETHB_TX_WRAP (1U << 30) /* Last descritor in list */ -#define ETHB_TX_USED (1U << 31) /* Packet Transmitted */ -} eth_tx_desc_t; - -#endif /* ARM_AT91_IF_ATEREG_H */ Index: head/sys/arm/at91/if_macb.c =================================================================== --- head/sys/arm/at91/if_macb.c +++ head/sys/arm/at91/if_macb.c @@ -1,1618 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010 Yohanes Nugroho - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "opt_platform.h" -#include "opt_at91.h" - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifdef INET -#include -#include -#include -#include -#endif - -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include - -#ifdef FDT -#include -#include -#endif - -/* "device miibus" required. See GENERIC if you get errors here. */ -#include "miibus_if.h" - - -#define MACB_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) -#define MACB_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) -#define MACB_LOCK_INIT(_sc) \ - mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \ - MTX_NETWORK_LOCK, MTX_DEF) -#define MACB_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); -#define MACB_LOCK_ASSERT(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED); -#define MACB_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); - - -static inline uint32_t -read_4(struct macb_softc *sc, bus_size_t off) -{ - - return (bus_read_4(sc->mem_res, off)); -} - -static inline void -write_4(struct macb_softc *sc, bus_size_t off, uint32_t val) -{ - - bus_write_4(sc->mem_res, off, val); -} - - -static devclass_t macb_devclass; - -/* ifnet entry points */ - -static void macbinit_locked(void *); -static void macbstart_locked(struct ifnet *); - -static void macbinit(void *); -static void macbstart(struct ifnet *); -static void macbstop(struct macb_softc *); -static int macbioctl(struct ifnet * ifp, u_long, caddr_t); - -/* bus entry points */ - -static int macb_probe(device_t dev); -static int macb_attach(device_t dev); -static int macb_detach(device_t dev); - -/* helper functions */ -static int -macb_new_rxbuf(struct macb_softc *sc, int index); - -static void -macb_free_desc_dma_tx(struct macb_softc *sc); - -static void -macb_free_desc_dma_rx(struct macb_softc *sc); - -static void -macb_init_desc_dma_tx(struct macb_softc *sc); - -static void -macb_watchdog(struct macb_softc *sc); - -static int macb_intr_rx_locked(struct macb_softc *sc, int count); -static void macb_intr_task(void *arg, int pending __unused); -static void macb_intr(void *xsc); - -static void -macb_tx_cleanup(struct macb_softc *sc); - -static inline int -phy_write(struct macb_softc *sc, int phy, int reg, int data); - -static void macb_reset(struct macb_softc *sc); - -static void -macb_deactivate(device_t dev) -{ - struct macb_softc *sc; - - sc = device_get_softc(dev); - - macb_free_desc_dma_tx(sc); - macb_free_desc_dma_rx(sc); - -} - -static void -macb_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error) -{ - bus_addr_t *paddr; - - KASSERT(nsegs == 1, ("wrong number of segments, should be 1")); - paddr = arg; - *paddr = segs->ds_addr; -} - -static int -macb_alloc_desc_dma_tx(struct macb_softc *sc) -{ - int error, i; - - /* Allocate a busdma tag and DMA safe memory for TX/RX descriptors. */ - error = bus_dma_tag_create(sc->sc_parent_tag, /* parent */ - 16, 0, /* alignment, boundary */ - BUS_SPACE_MAXADDR, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filtfunc, filtfuncarg */ - sizeof(struct eth_tx_desc) * MACB_MAX_TX_BUFFERS, /* max size */ - 1, /* nsegments */ - sizeof(struct eth_tx_desc) * MACB_MAX_TX_BUFFERS, - 0, /* flags */ - NULL, NULL, /* lockfunc, lockfuncarg */ - &sc->dmatag_data_tx); /* dmat */ - if (error != 0) { - device_printf(sc->dev, - "Couldn't create TX descriptor dma tag\n"); - return (error); - } - /* Allocate memory for TX ring. */ - error = bus_dmamem_alloc(sc->dmatag_data_tx, - (void**)&(sc->desc_tx), BUS_DMA_NOWAIT | BUS_DMA_ZERO | - BUS_DMA_COHERENT, &sc->dmamap_ring_tx); - if (error != 0) { - device_printf(sc->dev, "failed to allocate TX dma memory\n"); - return (error); - } - /* Load Ring DMA. */ - error = bus_dmamap_load(sc->dmatag_data_tx, sc->dmamap_ring_tx, - sc->desc_tx, sizeof(struct eth_tx_desc) * MACB_MAX_TX_BUFFERS, - macb_getaddr, &sc->ring_paddr_tx, BUS_DMA_NOWAIT); - if (error != 0) { - device_printf(sc->dev, "can't load TX descriptor dma map\n"); - return (error); - } - /* Allocate a busdma tag for mbufs. No alignment restriction applys. */ - error = bus_dma_tag_create(sc->sc_parent_tag, /* parent */ - 1, 0, /* alignment, boundary */ - BUS_SPACE_MAXADDR, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filtfunc, filtfuncarg */ - MCLBYTES * MAX_FRAGMENT, /* maxsize */ - MAX_FRAGMENT, /* nsegments */ - MCLBYTES, 0, /* maxsegsz, flags */ - NULL, NULL, /* lockfunc, lockfuncarg */ - &sc->dmatag_ring_tx); /* dmat */ - if (error != 0) { - device_printf(sc->dev, "failed to create TX mbuf dma tag\n"); - return (error); - } - - for (i = 0; i < MACB_MAX_TX_BUFFERS; i++) { - /* Create dma map for each descriptor. */ - error = bus_dmamap_create(sc->dmatag_ring_tx, 0, - &sc->tx_desc[i].dmamap); - if (error != 0) { - device_printf(sc->dev, - "failed to create TX mbuf dma map\n"); - return (error); - } - } - return (0); -} - -static void -macb_free_desc_dma_tx(struct macb_softc *sc) -{ - struct tx_desc_info *td; - int i; - - /* TX buffers. */ - if (sc->dmatag_ring_tx != NULL) { - for (i = 0; i < MACB_MAX_TX_BUFFERS; i++) { - td = &sc->tx_desc[i]; - if (td->dmamap != NULL) { - bus_dmamap_destroy(sc->dmatag_ring_tx, - td->dmamap); - td->dmamap = NULL; - } - } - bus_dma_tag_destroy(sc->dmatag_ring_tx); - sc->dmatag_ring_tx = NULL; - } - - /* TX descriptor ring. */ - if (sc->dmatag_data_tx != NULL) { - if (sc->ring_paddr_tx != 0) - bus_dmamap_unload(sc->dmatag_data_tx, - sc->dmamap_ring_tx); - if (sc->desc_tx != NULL) - bus_dmamem_free(sc->dmatag_data_tx, sc->desc_tx, - sc->dmamap_ring_tx); - sc->ring_paddr_tx = 0; - sc->desc_tx = NULL; - bus_dma_tag_destroy(sc->dmatag_data_tx); - sc->dmatag_data_tx = NULL; - } -} - -static void -macb_init_desc_dma_tx(struct macb_softc *sc) -{ - struct eth_tx_desc *desc; - int i; - - MACB_LOCK_ASSERT(sc); - - sc->tx_prod = 0; - sc->tx_cons = 0; - sc->tx_cnt = 0; - - desc = &sc->desc_tx[0]; - bzero(desc, sizeof(struct eth_tx_desc) * MACB_MAX_TX_BUFFERS); - - for (i = 0; i < MACB_MAX_TX_BUFFERS; i++) { - desc = &sc->desc_tx[i]; - if (i == MACB_MAX_TX_BUFFERS - 1) - desc->flags = TD_OWN | TD_WRAP_MASK; - else - desc->flags = TD_OWN; - } - - bus_dmamap_sync(sc->dmatag_data_tx, sc->dmamap_ring_tx, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); -} - -static int -macb_alloc_desc_dma_rx(struct macb_softc *sc) -{ - int error, i; - - /* Allocate a busdma tag and DMA safe memory for RX descriptors. */ - error = bus_dma_tag_create(sc->sc_parent_tag, /* parent */ - 16, 0, /* alignment, boundary */ - BUS_SPACE_MAXADDR, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filtfunc, filtfuncarg */ - /* maxsize, nsegments */ - sizeof(struct eth_rx_desc) * MACB_MAX_RX_BUFFERS, 1, - /* maxsegsz, flags */ - sizeof(struct eth_rx_desc) * MACB_MAX_RX_BUFFERS, 0, - NULL, NULL, /* lockfunc, lockfuncarg */ - &sc->dmatag_data_rx); /* dmat */ - if (error != 0) { - device_printf(sc->dev, - "Couldn't create RX descriptor dma tag\n"); - return (error); - } - /* Allocate RX ring. */ - error = bus_dmamem_alloc(sc->dmatag_data_rx, (void**)&(sc->desc_rx), - BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT, - &sc->dmamap_ring_rx); - if (error != 0) { - device_printf(sc->dev, - "failed to allocate RX descriptor dma memory\n"); - return (error); - } - - /* Load dmamap. */ - error = bus_dmamap_load(sc->dmatag_data_rx, sc->dmamap_ring_rx, - sc->desc_rx, sizeof(struct eth_rx_desc) * MACB_MAX_RX_BUFFERS, - macb_getaddr, &sc->ring_paddr_rx, BUS_DMA_NOWAIT); - if (error != 0) { - device_printf(sc->dev, "can't load RX descriptor dma map\n"); - return (error); - } - - /* Allocate a busdma tag for mbufs. */ - error = bus_dma_tag_create(sc->sc_parent_tag,/* parent */ - 16, 0, /* alignment, boundary */ - BUS_SPACE_MAXADDR, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filtfunc, filtfuncarg */ - MCLBYTES, 1, /* maxsize, nsegments */ - MCLBYTES, 0, /* maxsegsz, flags */ - NULL, NULL, /* lockfunc, lockfuncarg */ - &sc->dmatag_ring_rx); /* dmat */ - - if (error != 0) { - device_printf(sc->dev, "failed to create RX mbuf dma tag\n"); - return (error); - } - - for (i = 0; i < MACB_MAX_RX_BUFFERS; i++) { - error = bus_dmamap_create(sc->dmatag_ring_rx, 0, - &sc->rx_desc[i].dmamap); - if (error != 0) { - device_printf(sc->dev, - "failed to create RX mbuf dmamap\n"); - return (error); - } - } - - return (0); -} - -static void -macb_free_desc_dma_rx(struct macb_softc *sc) -{ - struct rx_desc_info *rd; - int i; - - /* RX buffers. */ - if (sc->dmatag_ring_rx != NULL) { - for (i = 0; i < MACB_MAX_RX_BUFFERS; i++) { - rd = &sc->rx_desc[i]; - if (rd->dmamap != NULL) { - bus_dmamap_destroy(sc->dmatag_ring_rx, - rd->dmamap); - rd->dmamap = NULL; - } - } - bus_dma_tag_destroy(sc->dmatag_ring_rx); - sc->dmatag_ring_rx = NULL; - } - /* RX descriptor ring. */ - if (sc->dmatag_data_rx != NULL) { - if (sc->ring_paddr_rx != 0) - bus_dmamap_unload(sc->dmatag_data_rx, - sc->dmamap_ring_rx); - if (sc->desc_rx != NULL) - bus_dmamem_free(sc->dmatag_data_rx, sc->desc_rx, - sc->dmamap_ring_rx); - sc->ring_paddr_rx = 0; - sc->desc_rx = NULL; - bus_dma_tag_destroy(sc->dmatag_data_rx); - sc->dmatag_data_rx = NULL; - } -} - -static int -macb_init_desc_dma_rx(struct macb_softc *sc) -{ - struct eth_rx_desc *desc; - struct rx_desc_info *rd; - int i; - - MACB_LOCK_ASSERT(sc); - - sc->rx_cons = 0; - desc = &sc->desc_rx[0]; - bzero(desc, sizeof(struct eth_rx_desc) * MACB_MAX_RX_BUFFERS); - for (i = 0; i < MACB_MAX_RX_BUFFERS; i++) { - rd = &sc->rx_desc[i]; - rd->buff = NULL; - if (macb_new_rxbuf(sc, i) != 0) - return (ENOBUFS); - } - bus_dmamap_sync(sc->dmatag_ring_rx, sc->dmamap_ring_rx, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - return (0); -} - -static int -macb_new_rxbuf(struct macb_softc *sc, int index) -{ - struct rx_desc_info *rd; - struct eth_rx_desc *desc; - struct mbuf *m; - bus_dma_segment_t seg[1]; - int error, nsegs; - - m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); - if (m == NULL) - return (ENOBUFS); - m->m_len = m->m_pkthdr.len = MCLBYTES - ETHER_ALIGN; - rd = &sc->rx_desc[index]; - bus_dmamap_unload(sc->dmatag_ring_rx, rd->dmamap); - error = bus_dmamap_load_mbuf_sg(sc->dmatag_ring_rx, rd->dmamap, m, - seg, &nsegs, 0); - KASSERT(nsegs == 1, ("Too many segments returned!")); - if (error != 0) { - m_free(m); - return (error); - } - - bus_dmamap_sync(sc->dmatag_ring_rx, rd->dmamap, BUS_DMASYNC_PREREAD); - rd->buff = m; - - desc = &sc->desc_rx[index]; - desc->addr = seg[0].ds_addr; - - desc->flags = DATA_SIZE; - - if (index == MACB_MAX_RX_BUFFERS - 1) - desc->addr |= RD_WRAP_MASK; - - return (0); -} - -static int -macb_allocate_dma(struct macb_softc *sc) -{ - int error; - - /* Create parent tag for tx and rx */ - error = bus_dma_tag_create( - bus_get_dma_tag(sc->dev), /* parent */ - 1, 0, /* alignment, boundary */ - BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filter, filterarg */ - BUS_SPACE_MAXSIZE_32BIT, 0, /* maxsize, nsegments */ - BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ - 0, /* flags */ - NULL, NULL, /* lockfunc, lockarg */ - &sc->sc_parent_tag); - if (error != 0) { - device_printf(sc->dev, "Couldn't create parent DMA tag\n"); - return (error); - } - - if ((error = macb_alloc_desc_dma_tx(sc)) != 0) - return (error); - if ((error = macb_alloc_desc_dma_rx(sc)) != 0) - return (error); - return (0); -} - - -static void -macb_tick(void *xsc) -{ - struct macb_softc *sc; - struct mii_data *mii; - - sc = xsc; - mii = device_get_softc(sc->miibus); - mii_tick(mii); - macb_watchdog(sc); - /* - * Schedule another timeout one second from now. - */ - callout_reset(&sc->tick_ch, hz, macb_tick, sc); -} - - -static void -macb_watchdog(struct macb_softc *sc) -{ - struct ifnet *ifp; - - MACB_LOCK_ASSERT(sc); - - if (sc->macb_watchdog_timer == 0 || --sc->macb_watchdog_timer) - return; - - ifp = sc->ifp; - if ((sc->flags & MACB_FLAG_LINK) == 0) { - if_printf(ifp, "watchdog timeout (missed link)\n"); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - return; - } - - if_printf(ifp, "watchdog timeout\n"); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - macbinit_locked(sc); - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - macbstart_locked(ifp); -} - - - -static void -macbinit_locked(void *xsc) -{ - struct macb_softc *sc; - struct ifnet *ifp; - int err; - uint32_t config; - struct mii_data *mii; - - sc = xsc; - ifp = sc->ifp; - - MACB_LOCK_ASSERT(sc); - - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) - return; - - if ((err = macb_init_desc_dma_rx(sc)) != 0) { - device_printf(sc->dev, "no memory for RX buffers\n"); - //ecestop(sc); - return; - } - macb_init_desc_dma_tx(sc); - - config = read_4(sc, EMAC_NCFGR) | (sc->clock << 10); /*set clock*/ - config |= CFG_PAE; /* PAuse Enable */ - config |= CFG_DRFCS; /* Discard Rx FCS */ - config |= CFG_SPD; /* 100 mbps*/ - //config |= CFG_CAF; - config |= CFG_FD; - - config |= CFG_RBOF_2; /*offset +2*/ - - write_4(sc, EMAC_NCFGR, config); - - /* Initialize TX and RX buffers */ - write_4(sc, EMAC_RBQP, sc->ring_paddr_rx); - write_4(sc, EMAC_TBQP, sc->ring_paddr_tx); - - /* Enable TX and RX */ - write_4(sc, EMAC_NCR, RX_ENABLE | TX_ENABLE | MPE_ENABLE); - - - /* Enable interrupts */ - write_4(sc, EMAC_IER, (RCOMP_INTERRUPT | - RXUBR_INTERRUPT | - TUND_INTERRUPT | - RLE_INTERRUPT | - TXERR_INTERRUPT | - ROVR_INTERRUPT | - HRESP_INTERRUPT| - TCOMP_INTERRUPT - )); - - /* - * Set 'running' flag, and clear output active flag - * and attempt to start the output - */ - ifp->if_drv_flags |= IFF_DRV_RUNNING; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - - mii = device_get_softc(sc->miibus); - - sc->flags |= MACB_FLAG_LINK; - - mii_mediachg(mii); - - callout_reset(&sc->tick_ch, hz, macb_tick, sc); -} - - -static void -macb_tx_cleanup(struct macb_softc *sc) -{ - struct ifnet *ifp; - struct eth_tx_desc *desc; - struct tx_desc_info *td; - int flags; - int status; - int i; - - MACB_LOCK_ASSERT(sc); - - status = read_4(sc, EMAC_TSR); - - write_4(sc, EMAC_TSR, status); - - /*buffer underrun*/ - if ((status & TSR_UND) != 0) { - /*reset buffers*/ - printf("underrun\n"); - bus_dmamap_sync(sc->dmatag_data_tx, sc->dmamap_ring_tx, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - sc->tx_cons = sc->tx_prod = 0; - for (i = 0; i < MACB_MAX_TX_BUFFERS; i++) { - desc = &sc->desc_tx[i]; - desc->flags = TD_OWN; - } - - for (i = 0; i < MACB_MAX_TX_BUFFERS; i++) { - td = &sc->tx_desc[i]; - if (td->buff != NULL) { - /* We are finished with this descriptor. */ - bus_dmamap_sync(sc->dmatag_ring_tx, td->dmamap, - BUS_DMASYNC_POSTWRITE); - /* ... and unload, so we can reuse. */ - bus_dmamap_unload(sc->dmatag_data_tx, - td->dmamap); - m_freem(td->buff); - td->buff = NULL; - } - } - } - - if ((status & TSR_COMP) == 0) - return; - - - if (sc->tx_cons == sc->tx_prod) - return; - - ifp = sc->ifp; - - /* Prepare to read the ring (owner bit). */ - bus_dmamap_sync(sc->dmatag_data_tx, sc->dmamap_ring_tx, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - while (sc->tx_cons != sc->tx_prod) { - desc = &sc->desc_tx[sc->tx_cons]; - if ((desc->flags & TD_OWN) == 0) - break; - - td = &sc->tx_desc[sc->tx_cons]; - if (td->buff != NULL) { - /* We are finished with this descriptor. */ - bus_dmamap_sync(sc->dmatag_ring_tx, td->dmamap, - BUS_DMASYNC_POSTWRITE); - /* ... and unload, so we can reuse. */ - bus_dmamap_unload(sc->dmatag_data_tx, - td->dmamap); - m_freem(td->buff); - td->buff = NULL; - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - } - - do { - sc->tx_cnt--; - MACB_DESC_INC(sc->tx_cons, MACB_MAX_TX_BUFFERS); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - flags = desc->flags; - desc->flags = TD_OWN; - desc = &sc->desc_tx[sc->tx_cons]; - if (flags & TD_LAST) { - break; - } - } while (sc->tx_cons != sc->tx_prod); - } - - /* Unarm watchog timer when there is no pending descriptors in queue. */ - if (sc->tx_cnt == 0) - sc->macb_watchdog_timer = 0; -} - -static void -macb_rx(struct macb_softc *sc) -{ - struct eth_rx_desc *rxdesc; - struct ifnet *ifp; - struct mbuf *m; - int rxbytes; - int flags; - int nsegs; - int first; - - rxdesc = &(sc->desc_rx[sc->rx_cons]); - - ifp = sc->ifp; - - bus_dmamap_sync(sc->dmatag_ring_rx, sc->dmamap_ring_rx, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - - - nsegs = 0; - while (rxdesc->addr & RD_OWN) { - - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - break; - - flags = rxdesc->flags; - - rxbytes = flags & RD_LEN_MASK; - - m = sc->rx_desc[sc->rx_cons].buff; - - bus_dmamap_sync(sc->dmatag_ring_rx, - sc->rx_desc[sc->rx_cons].dmamap, BUS_DMASYNC_POSTREAD); - if (macb_new_rxbuf(sc, sc->rx_cons) != 0) { - if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); - first = sc->rx_cons; - - do { - rxdesc->flags = DATA_SIZE; - MACB_DESC_INC(sc->rx_cons, MACB_MAX_RX_BUFFERS); - if ((rxdesc->flags & RD_EOF) != 0) - break; - rxdesc = &(sc->desc_rx[sc->rx_cons]); - } while (sc->rx_cons != first); - - if (sc->macb_cdata.rxhead != NULL) { - m_freem(sc->macb_cdata.rxhead); - sc->macb_cdata.rxhead = NULL; - sc->macb_cdata.rxtail = NULL; - } - - break; - } - - nsegs++; - - /* Chain received mbufs. */ - if (sc->macb_cdata.rxhead == NULL) { - m->m_data += 2; - sc->macb_cdata.rxhead = m; - sc->macb_cdata.rxtail = m; - if (flags & RD_EOF) - m->m_len = rxbytes; - else - m->m_len = DATA_SIZE - 2; - } else { - m->m_flags &= ~M_PKTHDR; - m->m_len = DATA_SIZE; - sc->macb_cdata.rxtail->m_next = m; - sc->macb_cdata.rxtail = m; - } - - if (flags & RD_EOF) { - - if (nsegs > 1) { - sc->macb_cdata.rxtail->m_len = (rxbytes - - ((nsegs - 1) * DATA_SIZE)) + 2; - } - - m = sc->macb_cdata.rxhead; - m->m_flags |= M_PKTHDR; - m->m_pkthdr.len = rxbytes; - m->m_pkthdr.rcvif = ifp; - if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); - - nsegs = 0; - MACB_UNLOCK(sc); - (*ifp->if_input)(ifp, m); - MACB_LOCK(sc); - sc->macb_cdata.rxhead = NULL; - sc->macb_cdata.rxtail = NULL; - - } - - rxdesc->addr &= ~RD_OWN; - - MACB_DESC_INC(sc->rx_cons, MACB_MAX_RX_BUFFERS); - - rxdesc = &(sc->desc_rx[sc->rx_cons]); - } - - write_4(sc, EMAC_IER, (RCOMP_INTERRUPT|RXUBR_INTERRUPT)); - -} - -static int -macb_intr_rx_locked(struct macb_softc *sc, int count) -{ - macb_rx(sc); - return (0); -} - -static void -macb_intr_task(void *arg, int pending __unused) -{ - struct macb_softc *sc; - - sc = arg; - MACB_LOCK(sc); - macb_intr_rx_locked(sc, -1); - MACB_UNLOCK(sc); -} - -static void -macb_intr(void *xsc) -{ - struct macb_softc *sc; - struct ifnet *ifp; - uint32_t status; - - sc = xsc; - ifp = sc->ifp; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - printf("not running\n"); - return; - } - - MACB_LOCK(sc); - status = read_4(sc, EMAC_ISR); - - while (status) { - if (status & RCOMP_INTERRUPT) { - write_4(sc, EMAC_IDR, (RCOMP_INTERRUPT|RXUBR_INTERRUPT)); - taskqueue_enqueue(sc->sc_tq, &sc->sc_intr_task); - } - - if (status & TCOMP_INTERRUPT) { - macb_tx_cleanup(sc); - } - - status = read_4(sc, EMAC_ISR); - } - - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - macbstart_locked(ifp); - MACB_UNLOCK(sc); -} - -static inline int -macb_encap(struct macb_softc *sc, struct mbuf **m_head) -{ - struct eth_tx_desc *desc; - struct tx_desc_info *txd, *txd_last; - struct mbuf *m; - bus_dma_segment_t segs[MAX_FRAGMENT]; - bus_dmamap_t map; - uint32_t csum_flags; - int error, i, nsegs, prod, si; - - M_ASSERTPKTHDR((*m_head)); - - prod = sc->tx_prod; - - m = *m_head; - - txd = txd_last = &sc->tx_desc[prod]; - error = bus_dmamap_load_mbuf_sg(sc->dmatag_ring_tx, txd->dmamap, - *m_head, segs, &nsegs, 0); - if (error == EFBIG) { - m = m_collapse(*m_head, M_NOWAIT, MAX_FRAGMENT); - if (m == NULL) { - m_freem(*m_head); - *m_head = NULL; - return (ENOMEM); - } - *m_head = m; - error = bus_dmamap_load_mbuf_sg(sc->dmatag_ring_tx, txd->dmamap, - *m_head, segs, &nsegs, 0); - if (error != 0) { - m_freem(*m_head); - *m_head = NULL; - return (error); - } - } else if (error != 0) { - return (error); - } - /* Check for TX descriptor overruns. */ - if (sc->tx_cnt + nsegs > MACB_MAX_TX_BUFFERS - 1) { - bus_dmamap_unload(sc->dmatag_ring_tx, txd->dmamap); - return (ENOBUFS); - } - bus_dmamap_sync(sc->dmatag_ring_tx, txd->dmamap, BUS_DMASYNC_PREWRITE); - m = *m_head; - - /* TODO: VLAN hardware tag insertion. */ - - csum_flags = 0; - si = prod; - desc = NULL; - - for (i = 0; i < nsegs; i++) { - desc = &sc->desc_tx[prod]; - desc->addr = segs[i].ds_addr; - - if (i == 0 ) { - desc->flags = segs[i].ds_len | TD_OWN; - } else { - desc->flags = segs[i].ds_len; - } - - if (prod == MACB_MAX_TX_BUFFERS - 1) - desc->flags |= TD_WRAP_MASK; - - sc->tx_cnt++; - MACB_DESC_INC(prod, MACB_MAX_TX_BUFFERS); - } - /* - * Set EOP on the last fragment. - */ - - desc->flags |= TD_LAST; - desc = &sc->desc_tx[si]; - desc->flags &= ~TD_OWN; - - sc->tx_prod = prod; - - /* Swap the first dma map and the last. */ - map = txd_last->dmamap; - txd_last->dmamap = txd->dmamap; - txd->dmamap = map; - txd->buff = m; - - return (0); -} - - -static void -macbstart_locked(struct ifnet *ifp) -{ - - - - struct macb_softc *sc; - struct mbuf *m0; -#if 0 - struct mbuf *m_new; -#endif - int queued = 0; - - sc = ifp->if_softc; - - if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != - IFF_DRV_RUNNING || (sc->flags & MACB_FLAG_LINK) == 0) { - return; - } - - while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { - /* Get packet from the queue */ - IF_DEQUEUE(&ifp->if_snd, m0); - if (m0 == NULL) - break; -#if 0 - if (m0->m_next != NULL) { - /* Fragmented mbuf chain, collapse it. */ - m_new = m_defrag(m0, M_NOWAIT); - if (m_new != NULL) { - /* Original frame freed. */ - m0 = m_new; - } else { - /* Defragmentation failed, just use the chain. */ - } - } -#endif - if (macb_encap(sc, &m0)) { - if (m0 == NULL) - break; - IF_PREPEND(&ifp->if_snd, m0); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - queued++; - BPF_MTAP(ifp, m0); - } - if (IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - if (queued) { - bus_dmamap_sync(sc->dmatag_data_tx, sc->dmamap_ring_tx, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - write_4(sc, EMAC_NCR, read_4(sc, EMAC_NCR) | TRANSMIT_START); - sc->macb_watchdog_timer = MACB_TIMEOUT; - } -} - -static void -macbinit(void *xsc) -{ - struct macb_softc *sc = xsc; - - MACB_LOCK(sc); - macbinit_locked(sc); - MACB_UNLOCK(sc); -} - -static void -macbstart(struct ifnet *ifp) -{ - struct macb_softc *sc = ifp->if_softc; - MACB_ASSERT_UNLOCKED(sc); - MACB_LOCK(sc); - macbstart_locked(ifp); - MACB_UNLOCK(sc); - -} - - -static void -macbstop(struct macb_softc *sc) -{ - struct ifnet *ifp = sc->ifp; - struct rx_desc_info *rd; - struct tx_desc_info *td; - int i; - - ifp = sc->ifp; - - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - - macb_reset(sc); - - sc->flags &= ~MACB_FLAG_LINK; - callout_stop(&sc->tick_ch); - sc->macb_watchdog_timer = 0; - - /* Free TX/RX mbufs still in the queues. */ - for (i = 0; i < MACB_MAX_TX_BUFFERS; i++) { - td = &sc->tx_desc[i]; - if (td->buff != NULL) { - bus_dmamap_sync(sc->dmatag_ring_tx, td->dmamap, - BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->dmatag_data_tx, td->dmamap); - m_freem(td->buff); - td->buff = NULL; - } - } - for (i = 0; i < MACB_MAX_RX_BUFFERS; i++) { - rd = &sc->rx_desc[i]; - if (rd->buff != NULL) { - bus_dmamap_sync(sc->dmatag_ring_rx, rd->dmamap, - BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(sc->dmatag_data_rx, rd->dmamap); - m_freem(rd->buff); - rd->buff = NULL; - } - } -} - -static int -get_hash_index(uint8_t *mac) -{ - int i, j, k; - int result; - int bit; - - result = 0; - for (i = 0; i < 6; i++) { - bit = 0; - for (j = 0; j < 8; j++) { - k = j * 6 + i; - bit ^= (mac[k/8] & (1 << (k % 8)) ) != 0; - } - result |= bit; - } - return result; -} - -static void -set_mac_filter(uint32_t *filter, uint8_t *mac) -{ - int bits; - - bits = get_hash_index(mac); - filter[bits >> 5] |= 1 << (bits & 31); -} - -static void -set_filter(struct macb_softc *sc) -{ - struct ifnet *ifp; - struct ifmultiaddr *ifma; - int config; - int count; - uint32_t multicast_filter[2]; - - ifp = sc->ifp; - - config = read_4(sc, EMAC_NCFGR); - - config &= ~(CFG_CAF | CFG_MTI); - write_4(sc, EMAC_HRB, 0); - write_4(sc, EMAC_HRT, 0); - - if ((ifp->if_flags & (IFF_ALLMULTI |IFF_PROMISC)) != 0){ - if ((ifp->if_flags & IFF_ALLMULTI) != 0) { - write_4(sc, EMAC_HRB, ~0); - write_4(sc, EMAC_HRT, ~0); - config |= CFG_MTI; - } - if ((ifp->if_flags & IFF_PROMISC) != 0) { - config |= CFG_CAF; - } - write_4(sc, EMAC_NCFGR, config); - return; - } - - if_maddr_rlock(ifp); - count = 0; - multicast_filter[0] = 0; - multicast_filter[1] = 0; - - CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - count++; - set_mac_filter(multicast_filter, - LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); - } - if (count) { - write_4(sc, EMAC_HRB, multicast_filter[0]); - write_4(sc, EMAC_HRT, multicast_filter[1]); - write_4(sc, EMAC_NCFGR, config|CFG_MTI); - } - if_maddr_runlock(ifp); -} - -static int -macbioctl(struct ifnet * ifp, u_long cmd, caddr_t data) -{ - - struct macb_softc *sc = ifp->if_softc; - struct mii_data *mii; - struct ifreq *ifr = (struct ifreq *)data; - - int error = 0; - - switch (cmd) { - case SIOCSIFFLAGS: - MACB_LOCK(sc); - - if ((ifp->if_flags & IFF_UP) != 0) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) { - if (((ifp->if_flags ^ sc->if_flags) - & (IFF_PROMISC | IFF_ALLMULTI)) != 0) - set_filter(sc); - } else { - macbinit_locked(sc); - } - } else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) { - macbstop(sc); - } - sc->if_flags = ifp->if_flags; - MACB_UNLOCK(sc); - break; - case SIOCADDMULTI: - case SIOCDELMULTI: - MACB_LOCK(sc); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) - set_filter(sc); - - MACB_UNLOCK(sc); - break; - case SIOCSIFMEDIA: - case SIOCGIFMEDIA: - mii = device_get_softc(sc->miibus); - error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd); - break; - default: - error = ether_ioctl(ifp, cmd, data); - break; - } - return (error); - -} - -/* bus entry points */ - -static int -macb_probe(device_t dev) -{ -#ifdef FDT - if (!ofw_bus_is_compatible(dev, "cdns,at32ap7000-macb")) - return (ENXIO); -#endif - - device_set_desc(dev, "macb"); - return (0); -} - -/* - * Change media according to request. - */ -static int -macb_ifmedia_upd(struct ifnet *ifp) -{ - struct macb_softc *sc = ifp->if_softc; - struct mii_data *mii; - - mii = device_get_softc(sc->miibus); - MACB_LOCK(sc); - mii_mediachg(mii); - MACB_UNLOCK(sc); - return (0); -} - -/* - * Notify the world which media we're using. - */ -static void -macb_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) -{ - struct macb_softc *sc = ifp->if_softc; - struct mii_data *mii; - - mii = device_get_softc(sc->miibus); - - MACB_LOCK(sc); - /* Don't report link state if driver is not running. */ - if ((ifp->if_flags & IFF_UP) == 0) { - MACB_UNLOCK(sc); - return; - } - mii_pollstat(mii); - ifmr->ifm_active = mii->mii_media_active; - ifmr->ifm_status = mii->mii_media_status; - MACB_UNLOCK(sc); -} - -static void -macb_reset(struct macb_softc *sc) -{ - /* - * Disable RX and TX - */ - write_4(sc, EMAC_NCR, 0); - - write_4(sc, EMAC_NCR, CLEAR_STAT); - - /* Clear all status flags */ - write_4(sc, EMAC_TSR, ~0UL); - write_4(sc, EMAC_RSR, ~0UL); - - /* Disable all interrupts */ - write_4(sc, EMAC_IDR, ~0UL); - read_4(sc, EMAC_ISR); - -} - - -static int -macb_get_mac(struct macb_softc *sc, u_char *eaddr) -{ - uint32_t bottom; - uint16_t top; - - bottom = read_4(sc, EMAC_SA1B); - top = read_4(sc, EMAC_SA1T); - - eaddr[0] = bottom & 0xff; - eaddr[1] = (bottom >> 8) & 0xff; - eaddr[2] = (bottom >> 16) & 0xff; - eaddr[3] = (bottom >> 24) & 0xff; - eaddr[4] = top & 0xff; - eaddr[5] = (top >> 8) & 0xff; - - return (0); -} - - -#ifdef FDT -/* - * We have to know if we're using MII or RMII attachment - * for the MACB to talk to the PHY correctly. With FDT, - * we must use rmii if there's a proprety phy-mode - * equal to "rmii". Otherwise we MII mode is used. - */ -static void -macb_set_rmii(struct macb_softc *sc) -{ - phandle_t node; - char prop[10]; - ssize_t len; - - node = ofw_bus_get_node(sc->dev); - memset(prop, 0 ,sizeof(prop)); - len = OF_getproplen(node, "phy-mode"); - if (len != 4) - return; - if (OF_getprop(node, "phy-mode", prop, len) != len) - return; - if (strncmp(prop, "rmii", 4) == 0) - sc->use_rmii = USRIO_RMII; -} -#else -/* - * We have to know if we're using MII or RMII attachment - * for the MACB to talk to the PHY correctly. Without FDT, - * there's no good way to do this. So, if the config file - * has 'option AT91_MACB_USE_RMII', then we'll force RMII. - * Otherwise, we'll use what the bootloader setup. Either - * it setup RMII or MII, in which case we'll get it right, - * or it did nothing, and we'll fall back to MII and the - * option would override if present. - */ -static void -macb_set_rmii(struct macb_softc *sc) -{ -#ifdef AT91_MACB_USE_RMII - sc->use_rmii = USRIO_RMII; -#else - sc->use_rmii = read_4(sc, EMAC_USRIO) & USRIO_RMII; -#endif -} -#endif - -static int -macb_attach(device_t dev) -{ - struct macb_softc *sc; - struct ifnet *ifp = NULL; - struct sysctl_ctx_list *sctx; - struct sysctl_oid *soid; - int pclk_hz; - u_char eaddr[ETHER_ADDR_LEN]; - int rid; - int err; - struct at91_pmc_clock *master; - - - err = 0; - - sc = device_get_softc(dev); - sc->dev = dev; - - MACB_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); - 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); - if (sc->irq_res == NULL) { - device_printf(dev, "could not allocate interrupt resources.\n"); - err = ENOMEM; - goto out; - } - - /*setup clock*/ - sc->clk = at91_pmc_clock_ref(device_get_nameunit(sc->dev)); - at91_pmc_clock_enable(sc->clk); - - macb_reset(sc); - macb_get_mac(sc, eaddr); - - master = at91_pmc_clock_ref("mck"); - - pclk_hz = master->hz; - - sc->clock = CFG_CLK_8; - if (pclk_hz <= 20000000) - sc->clock = CFG_CLK_8; - else if (pclk_hz <= 40000000) - sc->clock = CFG_CLK_16; - else if (pclk_hz <= 80000000) - sc->clock = CFG_CLK_32; - else - sc->clock = CFG_CLK_64; - - sc->clock = sc->clock << 10; - - macb_set_rmii(sc); - write_4(sc, EMAC_NCFGR, sc->clock); - write_4(sc, EMAC_USRIO, USRIO_CLOCK | sc->use_rmii); //enable clock - - write_4(sc, EMAC_NCR, MPE_ENABLE); //enable MPE - - sc->ifp = ifp = if_alloc(IFT_ETHER); - err = mii_attach(dev, &sc->miibus, ifp, macb_ifmedia_upd, - macb_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0); - if (err != 0) { - device_printf(dev, "attaching PHYs failed\n"); - goto out; - } - - if (macb_allocate_dma(sc) != 0) - goto out; - - /* Sysctls */ - sctx = device_get_sysctl_ctx(dev); - soid = device_get_sysctl_tree(dev); - - ifp->if_softc = sc; - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_capabilities |= IFCAP_VLAN_MTU; - ifp->if_capenable |= IFCAP_VLAN_MTU; /* The hw bits already set. */ - ifp->if_start = macbstart; - ifp->if_ioctl = macbioctl; - ifp->if_init = macbinit; - IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); - ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; - IFQ_SET_READY(&ifp->if_snd); - sc->if_flags = ifp->if_flags; - - TASK_INIT(&sc->sc_intr_task, 0, macb_intr_task, sc); - - sc->sc_tq = taskqueue_create_fast("macb_taskq", M_WAITOK, - taskqueue_thread_enqueue, &sc->sc_tq); - if (sc->sc_tq == NULL) { - device_printf(sc->dev, "could not create taskqueue\n"); - goto out; - } - - ether_ifattach(ifp, eaddr); - - /* - * Activate the interrupt. - */ - err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE, - NULL, macb_intr, sc, &sc->intrhand); - if (err) { - device_printf(dev, "could not establish interrupt handler.\n"); - ether_ifdetach(ifp); - goto out; - } - - taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq", - device_get_nameunit(sc->dev)); - - sc->macb_cdata.rxhead = 0; - sc->macb_cdata.rxtail = 0; - - phy_write(sc, 0, 0, 0x3300); //force autoneg - - return (0); -out: - - return (err); -} - -static int -macb_detach(device_t dev) -{ - struct macb_softc *sc; - - sc = device_get_softc(dev); - ether_ifdetach(sc->ifp); - MACB_LOCK(sc); - macbstop(sc); - MACB_UNLOCK(sc); - callout_drain(&sc->tick_ch); - bus_teardown_intr(dev, sc->irq_res, sc->intrhand); - taskqueue_drain(sc->sc_tq, &sc->sc_intr_task); - taskqueue_free(sc->sc_tq); - macb_deactivate(dev); - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); - bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res); - MACB_LOCK_DESTROY(sc); - - return (0); -} - -/*PHY related functions*/ -static inline int -phy_read(struct macb_softc *sc, int phy, int reg) -{ - int val; - - write_4(sc, EMAC_MAN, EMAC_MAN_REG_RD(phy, reg)); - while ((read_4(sc, EMAC_SR) & EMAC_SR_IDLE) == 0) - continue; - val = read_4(sc, EMAC_MAN) & EMAC_MAN_VALUE_MASK; - - return (val); -} - -static inline int -phy_write(struct macb_softc *sc, int phy, int reg, int data) -{ - - write_4(sc, EMAC_MAN, EMAC_MAN_REG_WR(phy, reg, data)); - while ((read_4(sc, EMAC_SR) & EMAC_SR_IDLE) == 0) - continue; - - return (0); -} - -/* - * MII bus support routines. - */ -static int -macb_miibus_readreg(device_t dev, int phy, int reg) -{ - struct macb_softc *sc; - sc = device_get_softc(dev); - return (phy_read(sc, phy, reg)); -} - -static int -macb_miibus_writereg(device_t dev, int phy, int reg, int data) -{ - struct macb_softc *sc; - sc = device_get_softc(dev); - return (phy_write(sc, phy, reg, data)); -} - -static void -macb_child_detached(device_t dev, device_t child) -{ - struct macb_softc *sc; - sc = device_get_softc(dev); - -} - -static void -macb_miibus_statchg(device_t dev) -{ - struct macb_softc *sc; - struct mii_data *mii; - int config; - - sc = device_get_softc(dev); - - mii = device_get_softc(sc->miibus); - - sc->flags &= ~MACB_FLAG_LINK; - - config = read_4(sc, EMAC_NCFGR); - - if ((mii->mii_media_status & IFM_AVALID) != 0) { - switch (IFM_SUBTYPE(mii->mii_media_active)) { - case IFM_10_T: - config &= ~(CFG_SPD); - sc->flags |= MACB_FLAG_LINK; - break; - case IFM_100_TX: - config |= CFG_SPD; - sc->flags |= MACB_FLAG_LINK; - break; - default: - break; - } - } - - config |= CFG_FD; - write_4(sc, EMAC_NCFGR, config); -} - -static device_method_t macb_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, macb_probe), - DEVMETHOD(device_attach, macb_attach), - DEVMETHOD(device_detach, macb_detach), - - /* Bus interface */ - DEVMETHOD(bus_child_detached, macb_child_detached), - - /* MII interface */ - DEVMETHOD(miibus_readreg, macb_miibus_readreg), - DEVMETHOD(miibus_writereg, macb_miibus_writereg), - DEVMETHOD(miibus_statchg, macb_miibus_statchg), - { 0, 0 } -}; - -static driver_t macb_driver = { - "macb", - macb_methods, - sizeof(struct macb_softc), -}; - - -#ifdef FDT -DRIVER_MODULE(macb, simplebus, macb_driver, macb_devclass, NULL, NULL); -#else -DRIVER_MODULE(macb, atmelarm, macb_driver, macb_devclass, 0, 0); -#endif -DRIVER_MODULE(miibus, macb, miibus_driver, miibus_devclass, 0, 0); -MODULE_DEPEND(macb, miibus, 1, 1, 1); -MODULE_DEPEND(macb, ether, 1, 1, 1); Index: head/sys/arm/at91/if_macbreg.h =================================================================== --- head/sys/arm/at91/if_macbreg.h +++ head/sys/arm/at91/if_macbreg.h @@ -1,107 +0,0 @@ -/* - * $FreeBSD$ - */ - -#ifndef MACB_REG_H -#define MACB_REG_H - -#define EMAC_NCR 0x00 -#define EMAC_NCFGR 0x04 -#define EMAC_TSR 0x14 -#define EMAC_RSR 0x20 -#define EMAC_ISR 0x24 -#define EMAC_IER 0x28 -#define EMAC_IDR 0x2C -#define EMAC_IMR 0x30 - - - -#define EMAC_RBQP 0x18 -#define EMAC_TBQP 0x1C - -#define EMAC_HRB 0x90 -#define EMAC_HRT 0x94 - -#define EMAC_SA1B 0x98 -#define EMAC_SA1T 0x9C - -#define EMAC_USRIO 0xC0 - -#define EMAC_MAN 0x34 /* EMAC PHY Maintenance Register */ -#define EMAC_SR 0x08 /* EMAC STatus Register */ -#define EMAC_SR_LINK (1U << 0) /* Reserved! */ -#define EMAC_SR_MDIO (1U << 1) /* MDIO pin status */ -#define EMAC_SR_IDLE (1U << 2) /* IDLE (PHY logic) */ - -#define RX_ENABLE (1 << 2) -#define TX_ENABLE (1 << 3) -#define MPE_ENABLE (1 << 4) - - -/* EMAC_MAN */ -#define EMAC_MAN_BITS 0x40020000 /* HIGH and CODE bits */ -#define EMAC_MAN_READ (2U << 28) -#define EMAC_MAN_WRITE (1U << 28) -#define EMAC_MAN_PHYA_BIT 23 -#define EMAC_MAN_REGA_BIT 18 -#define EMAC_MAN_VALUE_MASK 0xffffU -#define EMAC_MAN_REG_WR(phy, reg, val) \ - (EMAC_MAN_BITS | EMAC_MAN_WRITE | ((phy) << EMAC_MAN_PHYA_BIT) | \ - ((reg) << EMAC_MAN_REGA_BIT) | ((val) & EMAC_MAN_VALUE_MASK)) - -#define EMAC_MAN_REG_RD(phy, reg) \ - (EMAC_MAN_BITS | EMAC_MAN_READ | ((phy) << EMAC_MAN_PHYA_BIT) | \ - ((reg) << EMAC_MAN_REGA_BIT)) - -#define RCOMP_INTERRUPT (1 << 1) -#define RXUBR_INTERRUPT (1 << 2) -#define TUBR_INTERRUPT (1 << 3) -#define TUND_INTERRUPT (1 << 4) -#define RLE_INTERRUPT (1 << 5) -#define TXERR_INTERRUPT (1 << 6) -#define ROVR_INTERRUPT (1 << 10) -#define HRESP_INTERRUPT (1 << 11) -#define TCOMP_INTERRUPT (1 << 7) - -#define CLEAR_STAT (1 << 5) - -#define TRANSMIT_START (1 << 9) -#define TRANSMIT_STOP (1 << 10) - -/*Transmit status register flags*/ -#define TSR_UND (1 << 6) -#define TSR_COMP (1 << 5) -#define TSR_BEX (1 << 4) -#define TSR_TGO (1 << 3) -#define TSR_RLE (1 << 2) -#define TSR_COL (1 << 1) -#define TSR_UBR (1 << 0) - -#define CFG_SPD (1 << 0) -#define CFG_FD (1 << 1) -#define CFG_CAF (1 << 4) -#define CFG_NBC (1 << 5) -#define CFG_MTI (1 << 6) -#define CFG_UNI (1 << 7) -#define CFG_BIG (1 << 8) - -#define CFG_CLK_8 (0) -#define CFG_CLK_16 (1) -#define CFG_CLK_32 (2) -#define CFG_CLK_64 (3) - -#define CFG_PAE (1 << 13) - -#define CFG_RBOF_0 (0 << 14) -#define CFG_RBOF_1 (1 << 14) -#define CFG_RBOF_2 (2 << 14) -#define CFG_RBOF_3 (3 << 14) - -#define CFG_DRFCS (1 << 17) - -#define USRIO_RMII (1 << 0) /* RMII vs MII pins */ -#define USRIO_CLOCK (1 << 1) /* Enable the clock! */ - - - -#endif Index: head/sys/arm/at91/if_macbvar.h =================================================================== --- head/sys/arm/at91/if_macbvar.h +++ head/sys/arm/at91/if_macbvar.h @@ -1,138 +0,0 @@ -/* - * $FreeBSD$ - */ - -#ifndef _IF_MACB_H -#define _IF_MACB_H - -#define MACB_MAX_TX_BUFFERS 64 -#define MACB_MAX_RX_BUFFERS 256 - -#define MAX_FRAGMENT 20 -#define DATA_SIZE 128 - -#define MACB_DESC_INC(x, y) ((x) = ((x) + 1) % (y)) - -#define MACB_TIMEOUT 1000 - -struct eth_tx_desc { - uint32_t addr; - uint32_t flags; -#define TD_OWN (1U << 31) -#define TD_LAST (1 << 15) -#define TD_WRAP_MASK (1 << 30) -}; - -struct eth_rx_desc { - uint32_t addr; -#define RD_LEN_MASK 0x7ff -#define RD_WRAP_MASK 0x00000002 -#define RD_OWN 0x00000001 - - uint32_t flags; -#define RD_BROADCAST (1U << 31) -#define RD_MULTICAST (1 << 30) -#define RD_UNICAST (1 << 29) -#define RD_EXTERNAL (1 << 28) -#define RD_TYPE_ID (1 << 22) -#define RD_PRIORITY (1 << 20) -#define RD_VLAN (1 << 21) -#define RD_CONCAT (1 << 16) -#define RD_EOF (1 << 15) -#define RD_SOF (1 << 14) -#define RD_OFFSET_MASK (1 << 13)|(1 << 12) -#define RD_LENGTH_MASK (0x00000FFF) - -}; - - -struct rx_desc_info { - struct mbuf *buff; - bus_dmamap_t dmamap; -}; - -struct tx_desc_info { - struct mbuf *buff; - bus_dmamap_t dmamap; -}; - - -struct macb_chain_data{ - struct mbuf *rxhead; - struct mbuf *rxtail; -}; - -struct macb_softc -{ - struct ifnet *ifp; /* ifnet pointer */ - struct mtx sc_mtx; /* global mutex */ - - bus_dma_tag_t sc_parent_tag; /* parent bus DMA tag */ - - device_t dev; /* Myself */ - device_t miibus; /* My child miibus */ - void *intrhand; /* Interrupt handle */ - void *intrhand_qf; /* queue full */ - void *intrhand_tx; /* tx complete */ - void *intrhand_status; /* error status */ - - struct resource *irq_res; /* transmit */ - struct resource *irq_res_rec; /* receive */ - struct resource *irq_res_qf; /* queue full */ - struct resource *irq_res_status; /* status */ - - struct resource *mem_res; /* Memory resource */ - - struct callout tick_ch; /* Tick callout */ - - struct taskqueue *sc_tq; - struct task sc_intr_task; - struct task sc_tx_task; - struct task sc_link_task; - - bus_dmamap_t dmamap_ring_tx; - bus_dmamap_t dmamap_ring_rx; - - /*dma tag for ring*/ - bus_dma_tag_t dmatag_ring_tx; - bus_dma_tag_t dmatag_ring_rx; - - /*dma tag for data*/ - bus_dma_tag_t dmatag_data_tx; - bus_dma_tag_t dmatag_data_rx; - - /*the ring*/ - struct eth_tx_desc *desc_tx; - struct eth_rx_desc *desc_rx; - - /*ring physical address*/ - bus_addr_t ring_paddr_tx; - bus_addr_t ring_paddr_rx; - - /*index of last received descriptor*/ - int rx_cons; - struct rx_desc_info rx_desc[MACB_MAX_RX_BUFFERS]; - - /* tx producer index */ - uint32_t tx_prod; - /* tx consumer index */ - uint32_t tx_cons; - int tx_cnt; - - struct tx_desc_info tx_desc[MACB_MAX_TX_BUFFERS]; - - int macb_watchdog_timer; - -#define MACB_FLAG_LINK 0x0001 - - int flags; - int if_flags; - struct at91_pmc_clock *clk; - - struct macb_chain_data macb_cdata; - int clock; - - uint32_t use_rmii; /* 0 or USRIO_RMII */ -}; - -#endif Index: head/sys/arm/at91/std.hl200 =================================================================== --- head/sys/arm/at91/std.hl200 +++ head/sys/arm/at91/std.hl200 @@ -1,8 +0,0 @@ -#$FreeBSD$ -include "../at91/std.at91" - -makeoptions KERNPHYSADDR=0x20100000 -makeoptions KERNVIRTADDR=0xc0100000 -options KERNVIRTADDR=0xc0100000 - -device at91_board_hl200 Index: head/sys/arm/at91/std.hl201 =================================================================== --- head/sys/arm/at91/std.hl201 +++ head/sys/arm/at91/std.hl201 @@ -1,9 +0,0 @@ -#$FreeBSD$ -include "../at91/std.at91sam9" - -makeoptions KERNPHYSADDR=0x20000000 -makeoptions KERNVIRTADDR=0xc0000000 -options KERNVIRTADDR=0xc0000000 - -device at91_board_hl201 -device at91sam9g20 Index: head/sys/arm/at91/std.at91 =================================================================== --- head/sys/arm/at91/std.at91 +++ head/sys/arm/at91/std.at91 @@ -1,11 +0,0 @@ -# $FreeBSD$ - -files "../at91/files.at91" -cpu CPU_ARM9 -machine arm -makeoptions CONF_CFLAGS=-mcpu=arm9 -options PHYSADDR=0x20000000 -options NO_EVENTTIMERS - -# For now, just do the AT91RM9200 -device at91rm9200 Index: head/sys/arm/at91/std.at91sam9 =================================================================== --- head/sys/arm/at91/std.at91sam9 +++ head/sys/arm/at91/std.at91sam9 @@ -1,11 +0,0 @@ -# $FreeBSD$ - -files "../at91/files.at91" -cpu CPU_ARM9 -machine arm -makeoptions CONF_CFLAGS=-mcpu=arm9 -options PHYSADDR=0x20000000 -options NO_EVENTTIMERS - -# bring in the sam specific timers and such -device at91sam9 Index: head/sys/arm/at91/std.at91sam9g45 =================================================================== --- head/sys/arm/at91/std.at91sam9g45 +++ head/sys/arm/at91/std.at91sam9g45 @@ -1,16 +0,0 @@ -# $FreeBSD$ -# -# Unlike other Atmel SoCs, which have their SDRAM at CS1, the -# at91sam9g45 family has it on CS6, so PHYSADDR must be adjusted -# accordingly. The at91sam9g45, at91sam9g46, at91sam9m10 and at91sam9m11 -# SoCs are members of this family. - -files "../at91/files.at91" -cpu CPU_ARM9 -machine arm -makeoptions CONF_CFLAGS=-mcpu=arm9 -options PHYSADDR=0x70000000 -options NO_EVENTTIMERS - -# bring in the sam specific timers and such -device at91sam9 Index: head/sys/arm/at91/std.atmel =================================================================== --- head/sys/arm/at91/std.atmel +++ head/sys/arm/at91/std.atmel @@ -1,14 +0,0 @@ -# $FreeBSD$ - -include "../at91/std.at91sam9" - -# Supported SoCs for the at91 platform -device at91rm9200 -device at91sam9260 -device at91sam9g20 -device at91sam9g45 -device at91sam9x5 - -# bring in the sam specific timers and such -device at91sam9 - Index: head/sys/arm/at91/std.bwct =================================================================== --- head/sys/arm/at91/std.bwct +++ head/sys/arm/at91/std.bwct @@ -1,8 +0,0 @@ -#$FreeBSD$ -include "../at91/std.at91" - -makeoptions KERNPHYSADDR=0x20000000 -makeoptions KERNVIRTADDR=0xc0000000 -options KERNVIRTADDR=0xc0000000 - -device at91_board_bwct Index: head/sys/arm/at91/std.eb9200 =================================================================== --- head/sys/arm/at91/std.eb9200 +++ head/sys/arm/at91/std.eb9200 @@ -1,8 +0,0 @@ -#$FreeBSD$ -include "../at91/std.at91" - -makeoptions KERNPHYSADDR=0x20000000 -makeoptions KERNVIRTADDR=0xc0000000 -options KERNVIRTADDR=0xc0000000 - -device at91_board_eb9200 Index: head/sys/arm/at91/std.ethernut5 =================================================================== --- head/sys/arm/at91/std.ethernut5 +++ head/sys/arm/at91/std.ethernut5 @@ -1,9 +0,0 @@ -# $FreeBSD$ -include "../at91/std.at91sam9" - -makeoptions KERNPHYSADDR=0x20000000 -makeoptions KERNVIRTADDR=0xc0000000 -options KERNVIRTADDR=0xc0000000 - -device at91_board_ethernut5 -device at91sam9260 Index: head/sys/arm/at91/std.kb920x =================================================================== --- head/sys/arm/at91/std.kb920x +++ head/sys/arm/at91/std.kb920x @@ -1,8 +0,0 @@ -#$FreeBSD$ -include "../at91/std.at91" - -makeoptions KERNPHYSADDR=0x20000000 -makeoptions KERNVIRTADDR=0xc0000000 -options KERNVIRTADDR=0xc0000000 - -device at91_board_kb920x Index: head/sys/arm/at91/std.qila9g20 =================================================================== --- head/sys/arm/at91/std.qila9g20 +++ head/sys/arm/at91/std.qila9g20 @@ -1,9 +0,0 @@ -#$FreeBSD$ -include "../at91/std.at91sam9" - -makeoptions KERNPHYSADDR=0x20000000 -makeoptions KERNVIRTADDR=0xc0000000 -options KERNVIRTADDR=0xc0000000 - -device at91_board_qila9g20 -device at91sam9g20 Index: head/sys/arm/at91/std.sam9260ek =================================================================== --- head/sys/arm/at91/std.sam9260ek +++ head/sys/arm/at91/std.sam9260ek @@ -1,9 +0,0 @@ -# $FreeBSD$ -include "../at91/std.at91sam9" - -makeoptions KERNPHYSADDR=0x20000000 -makeoptions KERNVIRTADDR=0xc0000000 -options KERNVIRTADDR=0xc0000000 - -device at91_board_sam9260ek -device at91sam9260 Index: head/sys/arm/at91/std.sam9g20ek =================================================================== --- head/sys/arm/at91/std.sam9g20ek +++ head/sys/arm/at91/std.sam9g20ek @@ -1,9 +0,0 @@ -#$FreeBSD$ -include "../at91/std.at91sam9" - -makeoptions KERNPHYSADDR=0x20000000 -makeoptions KERNVIRTADDR=0xc0000000 -options KERNVIRTADDR=0xc0000000 - -device at91_board_sam9g20ek -device at91sam9g20 Index: head/sys/arm/at91/std.sam9x25ek =================================================================== --- head/sys/arm/at91/std.sam9x25ek +++ head/sys/arm/at91/std.sam9x25ek @@ -1,9 +0,0 @@ -#$FreeBSD$ -include "../at91/std.at91sam9" - -makeoptions KERNPHYSADDR=0x20000000 -makeoptions KERNVIRTADDR=0xc0000000 -options KERNVIRTADDR=0xc0000000 - -device at91_board_sam9x25ek -device at91sam9x5 Index: head/sys/arm/at91/std.sn9g45 =================================================================== --- head/sys/arm/at91/std.sn9g45 +++ head/sys/arm/at91/std.sn9g45 @@ -1,10 +0,0 @@ -#$FreeBSD$ -include "../at91/std.at91sam9g45" - -makeoptions KERNPHYSADDR=0x70008000 -makeoptions KERNVIRTADDR=0xc0008000 -options KERNVIRTADDR=0xc0008000 - -device at91sam9g45 -device at91_board_sn9g45 - Index: head/sys/arm/at91/std.tsc4370 =================================================================== --- head/sys/arm/at91/std.tsc4370 +++ head/sys/arm/at91/std.tsc4370 @@ -1,8 +0,0 @@ -#$FreeBSD$ -include "../at91/std.at91" - -makeoptions KERNPHYSADDR=0x20000000 -makeoptions KERNVIRTADDR=0xc0000000 -options KERNVIRTADDR=0xc0000000 - -device at91_board_tsc4370 Index: head/sys/arm/at91/uart_bus_at91usart.c =================================================================== --- head/sys/arm/at91/uart_bus_at91usart.c +++ head/sys/arm/at91/uart_bus_at91usart.c @@ -1,113 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2005 Olivier Houchard. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "opt_uart.h" - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "uart_if.h" - -extern struct uart_class at91_usart_class; -static int usart_at91_probe(device_t dev); - -static device_method_t usart_at91_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, usart_at91_probe), - DEVMETHOD(device_attach, uart_bus_attach), - DEVMETHOD(device_detach, uart_bus_detach), - { 0, 0 } -}; - -static driver_t usart_at91_driver = { - uart_driver_name, - usart_at91_methods, - sizeof(struct uart_softc), -}; - -extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; - -static int -usart_at91_probe(device_t dev) -{ - struct uart_softc *sc; - - sc = device_get_softc(dev); - switch (device_get_unit(dev)) - { - case 0: - device_set_desc(dev, "DBGU"); - /* - * Setting sc_sysdev makes this device a 'system device' and - * indirectly makes it the system console. - */ - sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs); - bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); - break; - case 1: - device_set_desc(dev, "USART0"); - break; - case 2: - device_set_desc(dev, "USART1"); - break; - case 3: - device_set_desc(dev, "USART2"); - break; - case 4: - device_set_desc(dev, "USART3"); - break; - case 5: - device_set_desc(dev, "USART4"); - break; - case 6: - device_set_desc(dev, "USART5"); - break; - } - sc->sc_class = &at91_usart_class; - if (sc->sc_class->uc_rclk == 0) - sc->sc_class->uc_rclk = at91_master_clock; - return (uart_bus_probe(dev, 0, 0, 0, 0, device_get_unit(dev))); -} - - -DRIVER_MODULE(uart, atmelarm, usart_at91_driver, uart_devclass, 0, 0); Index: head/sys/arm/at91/uart_cpu_at91usart.c =================================================================== --- head/sys/arm/at91/uart_cpu_at91usart.c +++ head/sys/arm/at91/uart_cpu_at91usart.c @@ -1,92 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2003 Marcel Moolenaar - * Copyright (c) 2006 M. Warner Losh - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "opt_platform.h" -#include "opt_uart.h" - -#ifndef FDT -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -bus_space_tag_t uart_bus_space_io; -bus_space_tag_t uart_bus_space_mem; - -extern struct uart_class at91_usart_class; - -int -uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) -{ - return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0); -} - -int -uart_cpu_getdev(int devtype, struct uart_devinfo *di) -{ - struct uart_class *class; - - class = &at91_usart_class; - if (class->uc_rclk == 0 && at91_master_clock != 0) - class->uc_rclk = at91_master_clock; - di->ops = uart_getops(class); - di->bas.chan = 0; - di->bas.bst = arm_base_bs_tag; - /* - * XXX: Not pretty, but will work because we map the needed addresses - * early. At least we probed this so that the console will work on - * all flavors of Atmel we can detect. - */ - di->bas.bsh = soc_info.dbgu_base; - di->baudrate = 115200; - di->bas.regshft = 0; - di->bas.rclk = 0; - di->databits = 8; - di->stopbits = 1; - di->parity = UART_PARITY_NONE; - uart_bus_space_io = arm_base_bs_tag; - uart_bus_space_mem = NULL; - /* Check the environment for overrides */ - uart_getenv(devtype, di, class); - return (0); -} -#endif Index: head/sys/arm/at91/uart_dev_at91usart.c =================================================================== --- head/sys/arm/at91/uart_dev_at91usart.c +++ head/sys/arm/at91/uart_dev_at91usart.c @@ -1,877 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2005 M. Warner Losh - * Copyright (c) 2005 Olivier Houchard - * Copyright (c) 2012 Ian Lepore - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#ifdef FDT -#include -#endif -#include -#include -#include -#include -#include -#include -#include - -#include "uart_if.h" - -#define DEFAULT_RCLK at91_master_clock -#define USART_DEFAULT_FIFO_BYTES 128 - -#define USART_DCE_CHANGE_BITS (USART_CSR_CTSIC | USART_CSR_DCDIC | \ - USART_CSR_DSRIC | USART_CSR_RIIC) - -/* - * High-level UART interface. - */ -struct at91_usart_rx { - bus_addr_t pa; - uint8_t *buffer; - bus_dmamap_t map; -}; - -struct at91_usart_softc { - struct uart_softc base; - bus_dma_tag_t tx_tag; - bus_dmamap_t tx_map; - bus_addr_t tx_paddr; - uint32_t flags; -#define HAS_TIMEOUT 0x1 -#define USE_RTS0_WORKAROUND 0x2 - bus_dma_tag_t rx_tag; - struct at91_usart_rx ping_pong[2]; - struct at91_usart_rx *ping; - struct at91_usart_rx *pong; -}; - -#define RD4(bas, reg) \ - bus_space_read_4((bas)->bst, (bas)->bsh, uart_regofs(bas, reg)) -#define WR4(bas, reg, value) \ - bus_space_write_4((bas)->bst, (bas)->bsh, uart_regofs(bas, reg), value) - -#define SIGCHG(c, i, s, d) \ - do { \ - if (c) { \ - i |= (i & s) ? s : s | d; \ - } else { \ - i = (i & s) ? (i & ~s) | d : i; \ - } \ - } while (0); - -#define BAUD2DIVISOR(b) \ - ((((DEFAULT_RCLK * 10) / ((b) * 16)) + 5) / 10) - -/* - * Low-level UART interface. - */ -static int at91_usart_probe(struct uart_bas *bas); -static void at91_usart_init(struct uart_bas *bas, int, int, int, int); -static void at91_usart_term(struct uart_bas *bas); -static void at91_usart_putc(struct uart_bas *bas, int); -static int at91_usart_rxready(struct uart_bas *bas); -static int at91_usart_getc(struct uart_bas *bas, struct mtx *hwmtx); - -extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; - -static int -at91_usart_param(struct uart_bas *bas, int baudrate, int databits, - int stopbits, int parity) -{ - uint32_t mr; - - /* - * Assume 3-wire RS-232 configuration. - * XXX Not sure how uart will present the other modes to us, so - * XXX they are unimplemented. maybe ioctl? - */ - mr = USART_MR_MODE_NORMAL; - mr |= USART_MR_USCLKS_MCK; /* Assume MCK */ - - /* - * Or in the databits requested - */ - if (databits < 9) - mr &= ~USART_MR_MODE9; - switch (databits) { - case 5: - mr |= USART_MR_CHRL_5BITS; - break; - case 6: - mr |= USART_MR_CHRL_6BITS; - break; - case 7: - mr |= USART_MR_CHRL_7BITS; - break; - case 8: - mr |= USART_MR_CHRL_8BITS; - break; - case 9: - mr |= USART_MR_CHRL_8BITS | USART_MR_MODE9; - break; - default: - return (EINVAL); - } - - /* - * Or in the parity - */ - switch (parity) { - case UART_PARITY_NONE: - mr |= USART_MR_PAR_NONE; - break; - case UART_PARITY_ODD: - mr |= USART_MR_PAR_ODD; - break; - case UART_PARITY_EVEN: - mr |= USART_MR_PAR_EVEN; - break; - case UART_PARITY_MARK: - mr |= USART_MR_PAR_MARK; - break; - case UART_PARITY_SPACE: - mr |= USART_MR_PAR_SPACE; - break; - default: - return (EINVAL); - } - - /* - * Or in the stop bits. Note: The hardware supports 1.5 stop - * bits in async mode, but there's no way to specify that - * AFAICT. Instead, rely on the convention documented at - * http://www.lammertbies.nl/comm/info/RS-232_specs.html which - * states that 1.5 stop bits are used for 5 bit bytes and - * 2 stop bits only for longer bytes. - */ - if (stopbits == 1) - mr |= USART_MR_NBSTOP_1; - else if (databits > 5) - mr |= USART_MR_NBSTOP_2; - else - mr |= USART_MR_NBSTOP_1_5; - - /* - * We want normal plumbing mode too, none of this fancy - * loopback or echo mode. - */ - mr |= USART_MR_CHMODE_NORMAL; - - mr &= ~USART_MR_MSBF; /* lsb first */ - mr &= ~USART_MR_CKLO_SCK; /* Don't drive SCK */ - - WR4(bas, USART_MR, mr); - - /* - * Set the baud rate (only if we know our master clock rate) - */ - if (DEFAULT_RCLK != 0) - WR4(bas, USART_BRGR, BAUD2DIVISOR(baudrate)); - - /* - * Set the receive timeout based on the baud rate. The idea is to - * compromise between being responsive on an interactive connection and - * giving a bulk data sender a bit of time to queue up a new buffer - * without mistaking it for a stopping point in the transmission. For - * 19.2kbps and below, use 20 * bit time (2 characters). For faster - * connections use 500 microseconds worth of bits. - */ - if (baudrate <= 19200) - WR4(bas, USART_RTOR, 20); - else - WR4(bas, USART_RTOR, baudrate / 2000); - WR4(bas, USART_CR, USART_CR_STTTO); - - /* XXX Need to take possible synchronous mode into account */ - return (0); -} - -static struct uart_ops at91_usart_ops = { - .probe = at91_usart_probe, - .init = at91_usart_init, - .term = at91_usart_term, - .putc = at91_usart_putc, - .rxready = at91_usart_rxready, - .getc = at91_usart_getc, -}; - -#ifdef EARLY_PRINTF -/* - * Early printf support. This assumes that we have the SoC "system" devices - * mapped into AT91_BASE. To use this before we adjust the boostrap tables, - * you'll need to define SOCDEV_VA to be 0xdc000000 and SOCDEV_PA to be - * 0xfc000000 in your config file where you define EARLY_PRINTF - */ -volatile uint32_t *at91_dbgu = (volatile uint32_t *)(AT91_BASE + AT91_DBGU0); - -static void -eputc(int c) -{ - - while (!(at91_dbgu[USART_CSR / 4] & USART_CSR_TXRDY)) - continue; - at91_dbgu[USART_THR / 4] = c; -} - -early_putc_t * early_putc = eputc; -#endif - -static int -at91_usart_probe(struct uart_bas *bas) -{ - - /* We know that this is always here */ - return (0); -} - -/* - * Initialize this device for use as a console. - */ -static void -at91_usart_init(struct uart_bas *bas, int baudrate, int databits, int stopbits, - int parity) -{ - -#ifdef EARLY_PRINTF - if (early_putc != NULL) { - printf("Early printf yielding control to the real console.\n"); - early_putc = NULL; - } -#endif - - /* - * This routine is called multiple times, sometimes right after writing - * some output, and the last byte is still shifting out. If that's the - * case delay briefly before resetting, but don't loop on TXRDY because - * we don't want to hang here forever if the hardware is in a bad state. - */ - if (!(RD4(bas, USART_CSR) & USART_CSR_TXRDY)) - DELAY(10000); - - at91_usart_param(bas, baudrate, databits, stopbits, parity); - - /* Reset the rx and tx buffers and turn on rx and tx */ - WR4(bas, USART_CR, USART_CR_RSTSTA | USART_CR_RSTRX | USART_CR_RSTTX); - WR4(bas, USART_CR, USART_CR_RXEN | USART_CR_TXEN); - WR4(bas, USART_IDR, 0xffffffff); -} - -/* - * Free resources now that we're no longer the console. This appears to - * be never called, and I'm unsure quite what to do if I am called. - */ -static void -at91_usart_term(struct uart_bas *bas) -{ - - /* XXX */ -} - -/* - * Put a character of console output (so we do it here polling rather than - * interrupt driven). - */ -static void -at91_usart_putc(struct uart_bas *bas, int c) -{ - - while (!(RD4(bas, USART_CSR) & USART_CSR_TXRDY)) - continue; - WR4(bas, USART_THR, c); -} - -/* - * Check for a character available. - */ -static int -at91_usart_rxready(struct uart_bas *bas) -{ - - return ((RD4(bas, USART_CSR) & USART_CSR_RXRDY) != 0 ? 1 : 0); -} - -/* - * Block waiting for a character. - */ -static int -at91_usart_getc(struct uart_bas *bas, struct mtx *hwmtx) -{ - int c; - - uart_lock(hwmtx); - while (!(RD4(bas, USART_CSR) & USART_CSR_RXRDY)) { - uart_unlock(hwmtx); - DELAY(4); - uart_lock(hwmtx); - } - c = RD4(bas, USART_RHR) & 0xff; - uart_unlock(hwmtx); - return (c); -} - -static int at91_usart_bus_probe(struct uart_softc *sc); -static int at91_usart_bus_attach(struct uart_softc *sc); -static int at91_usart_bus_flush(struct uart_softc *, int); -static int at91_usart_bus_getsig(struct uart_softc *); -static int at91_usart_bus_ioctl(struct uart_softc *, int, intptr_t); -static int at91_usart_bus_ipend(struct uart_softc *); -static int at91_usart_bus_param(struct uart_softc *, int, int, int, int); -static int at91_usart_bus_receive(struct uart_softc *); -static int at91_usart_bus_setsig(struct uart_softc *, int); -static int at91_usart_bus_transmit(struct uart_softc *); -static void at91_usart_bus_grab(struct uart_softc *); -static void at91_usart_bus_ungrab(struct uart_softc *); - -static kobj_method_t at91_usart_methods[] = { - KOBJMETHOD(uart_probe, at91_usart_bus_probe), - KOBJMETHOD(uart_attach, at91_usart_bus_attach), - KOBJMETHOD(uart_flush, at91_usart_bus_flush), - KOBJMETHOD(uart_getsig, at91_usart_bus_getsig), - KOBJMETHOD(uart_ioctl, at91_usart_bus_ioctl), - KOBJMETHOD(uart_ipend, at91_usart_bus_ipend), - KOBJMETHOD(uart_param, at91_usart_bus_param), - KOBJMETHOD(uart_receive, at91_usart_bus_receive), - KOBJMETHOD(uart_setsig, at91_usart_bus_setsig), - KOBJMETHOD(uart_transmit, at91_usart_bus_transmit), - KOBJMETHOD(uart_grab, at91_usart_bus_grab), - KOBJMETHOD(uart_ungrab, at91_usart_bus_ungrab), - - KOBJMETHOD_END -}; - -int -at91_usart_bus_probe(struct uart_softc *sc) -{ - int value; - - value = USART_DEFAULT_FIFO_BYTES; - resource_int_value(device_get_name(sc->sc_dev), - device_get_unit(sc->sc_dev), "fifo_bytes", &value); - value = roundup2(value, arm_dcache_align); - sc->sc_txfifosz = value; - sc->sc_rxfifosz = value; - sc->sc_hwiflow = 0; - return (0); -} - -static void -at91_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error) -{ - - if (error != 0) - return; - *(bus_addr_t *)arg = segs[0].ds_addr; -} - -static int -at91_usart_requires_rts0_workaround(struct uart_softc *sc) -{ - int value; - int unit; - - unit = device_get_unit(sc->sc_dev); - - /* - * On the rm9200 chips, the PA21/RTS0 pin is not correctly wired to the - * usart device interally (so-called 'erratum 39', but it's 41.14 in rev - * I of the manual). This prevents use of the hardware flow control - * feature in the usart itself. It also means that if we are to - * implement RTS/CTS flow via the tty layer logic, we must use pin PA21 - * as a gpio and manually manipulate it in at91_usart_bus_setsig(). We - * can only safely do so if we've been given permission via a hint, - * otherwise we might manipulate a pin that's attached to who-knows-what - * and Bad Things could happen. - */ - if (at91_is_rm92() && unit == 1) { - value = 0; - resource_int_value(device_get_name(sc->sc_dev), unit, - "use_rts0_workaround", &value); - if (value != 0) { - at91_pio_use_gpio(AT91RM92_PIOA_BASE, AT91C_PIO_PA21); - at91_pio_gpio_output(AT91RM92_PIOA_BASE, - AT91C_PIO_PA21, 1); - at91_pio_use_periph_a(AT91RM92_PIOA_BASE, - AT91C_PIO_PA20, 0); - return (1); - } - } - return (0); -} - -static int -at91_usart_bus_attach(struct uart_softc *sc) -{ - int err; - int i; - struct at91_usart_softc *atsc; - - atsc = (struct at91_usart_softc *)sc; - - if (at91_usart_requires_rts0_workaround(sc)) - atsc->flags |= USE_RTS0_WORKAROUND; - - /* - * See if we have a TIMEOUT bit. We disable all interrupts as - * a side effect. Boot loaders may have enabled them. Since - * a TIMEOUT interrupt can't happen without other setup, the - * apparent race here can't actually happen. - */ - WR4(&sc->sc_bas, USART_IDR, 0xffffffff); - WR4(&sc->sc_bas, USART_IER, USART_CSR_TIMEOUT); - if (RD4(&sc->sc_bas, USART_IMR) & USART_CSR_TIMEOUT) - atsc->flags |= HAS_TIMEOUT; - WR4(&sc->sc_bas, USART_IDR, 0xffffffff); - - /* - * Allocate transmit DMA tag and map. We allow a transmit buffer - * to be any size, but it must map to a single contiguous physical - * extent. - */ - err = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, - BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, - BUS_SPACE_MAXSIZE_32BIT, 1, BUS_SPACE_MAXSIZE_32BIT, 0, NULL, - NULL, &atsc->tx_tag); - if (err != 0) - goto errout; - err = bus_dmamap_create(atsc->tx_tag, 0, &atsc->tx_map); - if (err != 0) - goto errout; - if (bus_dmamap_load(atsc->tx_tag, atsc->tx_map, sc->sc_txbuf, - sc->sc_txfifosz, at91_getaddr, &atsc->tx_paddr, 0) != 0) - goto errout; - - if (atsc->flags & HAS_TIMEOUT) { - /* - * Allocate receive DMA tags, maps, and buffers. - * The receive buffers should be aligned to arm_dcache_align, - * otherwise partial cache line flushes on every receive - * interrupt are pretty much guaranteed. - */ - err = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), - arm_dcache_align, 0, BUS_SPACE_MAXADDR_32BIT, - BUS_SPACE_MAXADDR, NULL, NULL, sc->sc_rxfifosz, 1, - sc->sc_rxfifosz, BUS_DMA_ALLOCNOW, NULL, NULL, - &atsc->rx_tag); - if (err != 0) - goto errout; - for (i = 0; i < 2; i++) { - err = bus_dmamem_alloc(atsc->rx_tag, - (void **)&atsc->ping_pong[i].buffer, - BUS_DMA_NOWAIT, &atsc->ping_pong[i].map); - if (err != 0) - goto errout; - err = bus_dmamap_load(atsc->rx_tag, - atsc->ping_pong[i].map, - atsc->ping_pong[i].buffer, sc->sc_rxfifosz, - at91_getaddr, &atsc->ping_pong[i].pa, 0); - if (err != 0) - goto errout; - bus_dmamap_sync(atsc->rx_tag, atsc->ping_pong[i].map, - BUS_DMASYNC_PREREAD); - } - atsc->ping = &atsc->ping_pong[0]; - atsc->pong = &atsc->ping_pong[1]; - } - - /* Turn on rx and tx */ - DELAY(1000); /* Give pending character a chance to drain. */ - WR4(&sc->sc_bas, USART_CR, USART_CR_RSTSTA | USART_CR_RSTRX | USART_CR_RSTTX); - WR4(&sc->sc_bas, USART_CR, USART_CR_RXEN | USART_CR_TXEN); - - /* - * Setup the PDC to receive data. We use the ping-pong buffers - * so that we can more easily bounce between the two and so that - * we get an interrupt 1/2 way through the software 'fifo' we have - * to avoid overruns. - */ - if (atsc->flags & HAS_TIMEOUT) { - WR4(&sc->sc_bas, PDC_RPR, atsc->ping->pa); - WR4(&sc->sc_bas, PDC_RCR, sc->sc_rxfifosz); - WR4(&sc->sc_bas, PDC_RNPR, atsc->pong->pa); - WR4(&sc->sc_bas, PDC_RNCR, sc->sc_rxfifosz); - WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_RXTEN); - - /* - * Set the receive timeout to be 1.5 character times - * assuming 8N1. - */ - WR4(&sc->sc_bas, USART_RTOR, 15); - WR4(&sc->sc_bas, USART_CR, USART_CR_STTTO); - WR4(&sc->sc_bas, USART_IER, USART_CSR_TIMEOUT | - USART_CSR_RXBUFF | USART_CSR_ENDRX); - } else { - WR4(&sc->sc_bas, USART_IER, USART_CSR_RXRDY); - } - WR4(&sc->sc_bas, USART_IER, USART_CSR_RXBRK | USART_DCE_CHANGE_BITS); - - /* Prime sc->hwsig with the initial hw line states. */ - at91_usart_bus_getsig(sc); - -errout: - return (err); -} - -static int -at91_usart_bus_transmit(struct uart_softc *sc) -{ - struct at91_usart_softc *atsc; - int err; - - err = 0; - atsc = (struct at91_usart_softc *)sc; - uart_lock(sc->sc_hwmtx); - bus_dmamap_sync(atsc->tx_tag, atsc->tx_map, BUS_DMASYNC_PREWRITE); - sc->sc_txbusy = 1; - /* - * Setup the PDC to transfer the data and interrupt us when it - * is done. We've already requested the interrupt. - */ - WR4(&sc->sc_bas, PDC_TPR, atsc->tx_paddr); - WR4(&sc->sc_bas, PDC_TCR, sc->sc_txdatasz); - WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_TXTEN); - WR4(&sc->sc_bas, USART_IER, USART_CSR_ENDTX); - uart_unlock(sc->sc_hwmtx); - return (err); -} - -static int -at91_usart_bus_setsig(struct uart_softc *sc, int sig) -{ - uint32_t new, old, cr; - struct at91_usart_softc *atsc; - - atsc = (struct at91_usart_softc *)sc; - - do { - old = sc->sc_hwsig; - new = old; - if (sig & SER_DDTR) - SIGCHG(sig & SER_DTR, new, SER_DTR, SER_DDTR); - if (sig & SER_DRTS) - SIGCHG(sig & SER_RTS, new, SER_RTS, SER_DRTS); - } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); - - cr = 0; - if (new & SER_DTR) - cr |= USART_CR_DTREN; - else - cr |= USART_CR_DTRDIS; - if (new & SER_RTS) - cr |= USART_CR_RTSEN; - else - cr |= USART_CR_RTSDIS; - - uart_lock(sc->sc_hwmtx); - WR4(&sc->sc_bas, USART_CR, cr); - if (atsc->flags & USE_RTS0_WORKAROUND) { - /* Signal is active-low. */ - if (new & SER_RTS) - at91_pio_gpio_clear(AT91RM92_PIOA_BASE, AT91C_PIO_PA21); - else - at91_pio_gpio_set(AT91RM92_PIOA_BASE,AT91C_PIO_PA21); - } - uart_unlock(sc->sc_hwmtx); - - return (0); -} - -static int -at91_usart_bus_receive(struct uart_softc *sc) -{ - - return (0); -} - -static int -at91_usart_bus_param(struct uart_softc *sc, int baudrate, int databits, - int stopbits, int parity) -{ - - return (at91_usart_param(&sc->sc_bas, baudrate, databits, stopbits, - parity)); -} - -static __inline void -at91_rx_put(struct uart_softc *sc, int key) -{ - -#if defined(KDB) - if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) - kdb_alt_break(key, &sc->sc_altbrk); -#endif - uart_rx_put(sc, key); -} - -static int -at91_usart_bus_ipend(struct uart_softc *sc) -{ - struct at91_usart_softc *atsc; - struct at91_usart_rx *p; - int i, ipend, len; - uint32_t csr; - - ipend = 0; - atsc = (struct at91_usart_softc *)sc; - uart_lock(sc->sc_hwmtx); - csr = RD4(&sc->sc_bas, USART_CSR); - - if (csr & USART_CSR_OVRE) { - WR4(&sc->sc_bas, USART_CR, USART_CR_RSTSTA); - ipend |= SER_INT_OVERRUN; - } - - if (csr & USART_DCE_CHANGE_BITS) - ipend |= SER_INT_SIGCHG; - - if (csr & USART_CSR_ENDTX) { - bus_dmamap_sync(atsc->tx_tag, atsc->tx_map, - BUS_DMASYNC_POSTWRITE); - } - if (csr & (USART_CSR_TXRDY | USART_CSR_ENDTX)) { - if (sc->sc_txbusy) - ipend |= SER_INT_TXIDLE; - WR4(&sc->sc_bas, USART_IDR, csr & (USART_CSR_TXRDY | - USART_CSR_ENDTX)); - } - - /* - * Due to the contraints of the DMA engine present in the - * atmel chip, I can't just say I have a rx interrupt pending - * and do all the work elsewhere. I need to look at the CSR - * bits right now and do things based on them to avoid races. - */ - if (atsc->flags & HAS_TIMEOUT) { - if (csr & USART_CSR_RXBUFF) { - /* - * We have a buffer overflow. Consume data from ping - * and give it back to the hardware before worrying - * about pong, to minimze data loss. Insert an overrun - * marker after the contents of the pong buffer. - */ - WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_RXTDIS); - bus_dmamap_sync(atsc->rx_tag, atsc->ping->map, - BUS_DMASYNC_POSTREAD); - for (i = 0; i < sc->sc_rxfifosz; i++) - at91_rx_put(sc, atsc->ping->buffer[i]); - bus_dmamap_sync(atsc->rx_tag, atsc->ping->map, - BUS_DMASYNC_PREREAD); - WR4(&sc->sc_bas, PDC_RPR, atsc->ping->pa); - WR4(&sc->sc_bas, PDC_RCR, sc->sc_rxfifosz); - WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_RXTEN); - bus_dmamap_sync(atsc->rx_tag, atsc->pong->map, - BUS_DMASYNC_POSTREAD); - for (i = 0; i < sc->sc_rxfifosz; i++) - at91_rx_put(sc, atsc->pong->buffer[i]); - uart_rx_put(sc, UART_STAT_OVERRUN); - bus_dmamap_sync(atsc->rx_tag, atsc->pong->map, - BUS_DMASYNC_PREREAD); - WR4(&sc->sc_bas, PDC_RNPR, atsc->pong->pa); - WR4(&sc->sc_bas, PDC_RNCR, sc->sc_rxfifosz); - ipend |= SER_INT_RXREADY; - } else if (csr & USART_CSR_ENDRX) { - /* - * Consume data from ping of ping pong buffer, but leave - * current pong in place, as it has become the new ping. - * We need to copy data and setup the old ping as the - * new pong when we're done. - */ - bus_dmamap_sync(atsc->rx_tag, atsc->ping->map, - BUS_DMASYNC_POSTREAD); - for (i = 0; i < sc->sc_rxfifosz; i++) - at91_rx_put(sc, atsc->ping->buffer[i]); - p = atsc->ping; - atsc->ping = atsc->pong; - atsc->pong = p; - bus_dmamap_sync(atsc->rx_tag, atsc->pong->map, - BUS_DMASYNC_PREREAD); - WR4(&sc->sc_bas, PDC_RNPR, atsc->pong->pa); - WR4(&sc->sc_bas, PDC_RNCR, sc->sc_rxfifosz); - ipend |= SER_INT_RXREADY; - } else if (csr & USART_CSR_TIMEOUT) { - /* - * On a timeout, one of the following applies: - * 1. Two empty buffers. The last received byte exactly - * filled a buffer, causing an ENDTX that got - * processed earlier; no new bytes have arrived. - * 2. Ping buffer contains some data and pong is empty. - * This should be the most common timeout condition. - * 3. Ping buffer is full and pong is now being filled. - * This is exceedingly rare; it can happen only if - * the ping buffer is almost full when a timeout is - * signaled, and then dataflow resumes and the ping - * buffer filled up between the time we read the - * status register above and the point where the - * RXTDIS takes effect here. Yes, it can happen. - * Because dataflow can resume at any time following a - * timeout (it may have already resumed before we get - * here), it's important to minimize the time the PDC is - * disabled -- just long enough to take the ping buffer - * out of service (so we can consume it) and install the - * pong buffer as the active one. Note that in case 3 - * the hardware has already done the ping-pong swap. - */ - WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_RXTDIS); - if (RD4(&sc->sc_bas, PDC_RNCR) == 0) { - len = sc->sc_rxfifosz; - } else { - len = sc->sc_rxfifosz - RD4(&sc->sc_bas, PDC_RCR); - WR4(&sc->sc_bas, PDC_RPR, atsc->pong->pa); - WR4(&sc->sc_bas, PDC_RCR, sc->sc_rxfifosz); - WR4(&sc->sc_bas, PDC_RNCR, 0); - } - WR4(&sc->sc_bas, USART_CR, USART_CR_STTTO); - WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_RXTEN); - bus_dmamap_sync(atsc->rx_tag, atsc->ping->map, - BUS_DMASYNC_POSTREAD); - for (i = 0; i < len; i++) - at91_rx_put(sc, atsc->ping->buffer[i]); - bus_dmamap_sync(atsc->rx_tag, atsc->ping->map, - BUS_DMASYNC_PREREAD); - p = atsc->ping; - atsc->ping = atsc->pong; - atsc->pong = p; - WR4(&sc->sc_bas, PDC_RNPR, atsc->pong->pa); - WR4(&sc->sc_bas, PDC_RNCR, sc->sc_rxfifosz); - ipend |= SER_INT_RXREADY; - } - } else if (csr & USART_CSR_RXRDY) { - /* - * We have another charater in a device that doesn't support - * timeouts, so we do it one character at a time. - */ - at91_rx_put(sc, RD4(&sc->sc_bas, USART_RHR) & 0xff); - ipend |= SER_INT_RXREADY; - } - - if (csr & USART_CSR_RXBRK) { - ipend |= SER_INT_BREAK; - WR4(&sc->sc_bas, USART_CR, USART_CR_RSTSTA); - } - uart_unlock(sc->sc_hwmtx); - return (ipend); -} - -static int -at91_usart_bus_flush(struct uart_softc *sc, int what) -{ - - return (0); -} - -static int -at91_usart_bus_getsig(struct uart_softc *sc) -{ - uint32_t csr, new, old, sig; - - /* - * Note that the atmel channel status register DCE status bits reflect - * the electrical state of the lines, not the logical state. Since they - * are logically active-low signals, we invert the tests here. - */ - do { - old = sc->sc_hwsig; - sig = old; - csr = RD4(&sc->sc_bas, USART_CSR); - SIGCHG(!(csr & USART_CSR_DSR), sig, SER_DSR, SER_DDSR); - SIGCHG(!(csr & USART_CSR_CTS), sig, SER_CTS, SER_DCTS); - SIGCHG(!(csr & USART_CSR_DCD), sig, SER_DCD, SER_DDCD); - SIGCHG(!(csr & USART_CSR_RI), sig, SER_RI, SER_DRI); - new = sig & ~SER_MASK_DELTA; - } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); - - return (sig); -} - -static int -at91_usart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data) -{ - - switch (request) { - case UART_IOCTL_BREAK: - case UART_IOCTL_IFLOW: - case UART_IOCTL_OFLOW: - break; - case UART_IOCTL_BAUD: - /* only if we know our master clock rate */ - if (DEFAULT_RCLK != 0) - WR4(&sc->sc_bas, USART_BRGR, - BAUD2DIVISOR(*(int *)data)); - return (0); - } - return (EINVAL); -} - - -static void -at91_usart_bus_grab(struct uart_softc *sc) -{ - - uart_lock(sc->sc_hwmtx); - WR4(&sc->sc_bas, USART_IDR, USART_CSR_RXRDY); - uart_unlock(sc->sc_hwmtx); -} - -static void -at91_usart_bus_ungrab(struct uart_softc *sc) -{ - - uart_lock(sc->sc_hwmtx); - WR4(&sc->sc_bas, USART_IER, USART_CSR_RXRDY); - uart_unlock(sc->sc_hwmtx); -} - -struct uart_class at91_usart_class = { - "at91_usart", - at91_usart_methods, - sizeof(struct at91_usart_softc), - .uc_ops = &at91_usart_ops, - .uc_range = 8 -}; - -#ifdef FDT -static struct ofw_compat_data compat_data[] = { - {"atmel,at91rm9200-usart",(uintptr_t)&at91_usart_class}, - {"atmel,at91sam9260-usart",(uintptr_t)&at91_usart_class}, - {NULL, (uintptr_t)NULL}, -}; -UART_FDT_CLASS_AND_DEVICE(compat_data); -#endif Index: head/sys/arm/conf/ATMEL =================================================================== --- head/sys/arm/conf/ATMEL +++ head/sys/arm/conf/ATMEL @@ -1,159 +0,0 @@ -# Kernel configuration to test compile all the atmel bits with one -# configuration. This kernel will not (presently) boot. Do not copy -# it to create your own custom config file. -# -# $FreeBSD$ - -ident ATMEL - -include "std.arm" -include "../at91/std.atmel" - -# Typical values for most SoCs and board configurations. Will not work for -# at91sam9g45 or on some boards with non u-boot boot loaders. -makeoptions KERNPHYSADDR=0x20000000 -makeoptions KERNVIRTADDR=0xc0000000 -options KERNVIRTADDR=0xc0000000 - -makeoptions MODULES_OVERRIDE="dtb/atmel" - -# list all boards here, but not just yet (no multiboard in mainline). -options ARM_MANY_BOARD -device at91_board_bwct -device at91_board_ethernut5 -device at91_board_hl200 -device at91_board_hl201 -device at91_board_kb920x -device at91_board_qila9g20 -device at91_board_sam9260ek -device at91_board_sam9g20ek -device at91_board_sam9x25ek -device at91_board_sn9g45 -device at91_board_tsc4370 - -options SCHED_4BSD # 4BSD scheduler -#options PREEMPTION # Enable kernel thread preemption -options INET # InterNETworking -options INET6 # IPv6 communications protocols -options TCP_HHOOK # hhook(9) framework for TCP -options SCTP # Stream Control Transmission Protocol -options FFS # Berkeley Fast Filesystem -options SOFTUPDATES # Enable FFS soft updates support -options UFS_ACL # Support for access control lists -options UFS_DIRHASH # Improve performance on big directories -options UFS_GJOURNAL # Enable gjournal-based UFS journaling -options MD_ROOT # MD is a potential root device -options NFSCL # Network Filesystem Client -options NFSD # Network Filesystem Server -options NFSLOCKD # Network Lock Manager -options NFS_ROOT # NFS usable as /, requires NFSCL -options TMPFS # Efficient memory filesystem -options MSDOSFS # MSDOS Filesystem -options CD9660 # ISO 9660 Filesystem -options PROCFS # Process filesystem (requires PSEUDOFS) -options PSEUDOFS # Pseudo-filesystem framework -options GEOM_PART_BSD # BSD partition scheme -options GEOM_PART_MBR # MBR partition scheme -options GEOM_PART_GPT # GUID Partition Tables. -options GEOM_LABEL # Provides labelization -options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI -options KTRACE # ktrace(1) support -options STACK # stack(9) support -options SYSVSHM # SYSV-style shared memory -options SYSVMSG # SYSV-style message queues -options SYSVSEM # SYSV-style semaphores -options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions -options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed. -#options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4) -#options AUDIT # Security event auditing -#options CAPABILITY_MODE # Capsicum capability mode -#options CAPABILITIES # Capsicum capabilities -#options MAC # TrustedBSD MAC Framework -#options INCLUDE_CONFIG_FILE # Include this file in kernel - -# NFS root from boopt/dhcp -options BOOTP -options BOOTP_NFSROOT -options BOOTP_COMPAT -options BOOTP_NFSV3 -options BOOTP_WIRED_TO=ate0 - -# alternatively, boot from a MMC/SD memory card -#options ROOTDEVNAME=\"ufs:/dev/mmcsd0a\" - -# kernel/memory size reduction -options MUTEX_NOINLINE -options NO_FFS_SNAPSHOT -options NO_SWAPPING -options NO_SYSCTL_DESCR -options RWLOCK_NOINLINE - -# The `bpf' device enables the Berkeley Packet Filter. -# Be aware of the administrative consequences of enabling this! -# Note that 'bpf' is required for DHCP. -device bpf # Berkeley packet filter - -# Ethernet -device mii # Minimal MII support -device ate # Atmel AT91 Ethernet driver - -# I2C -device at91_twi # Atmel AT91 Two-wire Interface -device iic # I2C generic I/O device driver -device iicbus # I2C bus system -device pcf8563 # NXP PCF8563 clock/calendar - -# MMC/SD -device at91_mci # Atmel AT91 Multimedia Card Interface -options AT91_MCI_HAS_4WIRE -device mmc # MMC/SD bus -device mmcsd # MMC/SD memory card - -# DataFlash -device at91_spi # Atmel AT91 Serial Peripheral Interface -device spibus # SPI bus -device at45d # Atmel AT45D -device geom_map # GEOM partition mapping - -# Pseudo devices. -device loop # Network loopback -device random # Entropy device -device ether # Ethernet support -device vlan # 802.1Q VLAN support -device tun # Packet tunnel. -device md # Memory "disks" -device gif # IPv6 and IPv4 tunneling -#device firmware # firmware assist module - -# SCSI peripherals -device scbus # SCSI bus (required for ATA/SCSI) -device ch # SCSI media changers -device da # Direct Access (disks) -device sa # Sequential Access (tape etc) -device cd # CD -device pass # Passthrough device (direct ATA/SCSI access) -device ses # Enclosure Services (SES and SAF-TE) -#device ctl # CAM Target Layer - -# Serial (COM) ports -device uart # Multi-uart driver - -# USB support -device ohci # OHCI USB interface -device usb # USB Bus (required) -device umass # Disks/Mass storage - Requires scbus and da - -# USB device (gadget) support -device at91_dci # Atmel's usb device -device cdce # emulate an ethernet -device usb_template # Control of the gadget - -# watchdog -device at91_wdt # Atmel AT91 Watchdog Timer - -device at91_rtc -device at91_ssc -#device at91_tc # missing? - -# NAND Flash - Reference design has Samsung 256MB but others possible -device nand # NAND interface on CS3 Index: head/sys/arm/conf/NOTES =================================================================== --- head/sys/arm/conf/NOTES +++ head/sys/arm/conf/NOTES @@ -8,7 +8,6 @@ cpu CPU_XSCALE_81342 cpu CPU_XSCALE_PXA2X0 -files "../at91/files.at91" files "../cavium/cns11xx/files.econa" files "../mv/files.mv" files "../mv/discovery/files.db78xxx" @@ -31,17 +30,6 @@ options SOC_MV_ORION options ARM_MANY_BOARD -device at91_board_bwct -device at91_board_ethernut5 -device at91_board_hl200 -device at91_board_hl201 -device at91_board_kb920x -device at91_board_qila9g20 -device at91_board_sam9260ek -device at91_board_sam9g20ek -device at91_board_sam9x25ek -device at91_board_tsc4370 -device at91rm9200 device nand # IIC Index: head/sys/arm/conf/SAM9G20EK =================================================================== --- head/sys/arm/conf/SAM9G20EK +++ head/sys/arm/conf/SAM9G20EK @@ -1,172 +0,0 @@ -# Kernel configuration for Atmel AT91SAM9G20EK Rev B. development card -# Many after-market boards follow its conventions. -# -# For more information on this file, please read the handbook section on -# Kernel Configuration Files: -# -# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html -# -# The handbook is also available locally in /usr/share/doc/handbook -# if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the -# latest information. -# -# An exhaustive list of options and more detailed explanations of the -# device lines is also present in the ../../conf/NOTES and NOTES files. -# If you are in doubt as to the purpose or necessity of a line, check first -# in NOTES. -# -# $FreeBSD$ - -ident SAM9G20EK - -include "std.arm" -include "../at91/std.sam9g20ek" - -#options FDT -#options FDT_DTB_STATIC -#makeoptions FDT_DTS_FILE=at91sam9g20ek.dts - -options EARLY_PRINTF -options SOCDEV_PA=0xfc000000 -options SOCDEV_VA=0xdc000000 - -#To statically compile in device wiring instead of /boot/device.hints -hints "SAM9G20EK.hints" -makeoptions MODULES_OVERRIDE="" - -options ARM_USE_V6_BUSDMA # Use v6 to track down unaligned I/O issues - -options SCHED_4BSD # 4BSD scheduler -options INET # InterNETworking -#options INET6 # IPv6 communications protocols -options TCP_HHOOK # hhook(9) framework for TCP -options TMPFS # Efficient memory filesystem -options FFS # Berkeley Fast Filesystem -#options SOFTUPDATES # Enable FFS soft updates support -#options UFS_ACL # Support for access control lists -#options UFS_DIRHASH # Improve performance on big directories -#options MD_ROOT # MD is a potential root device -#options MD_ROOT_SIZE=4096 # 4MB ram disk -options NANDFS # NAND file system -options NFSCL # Network Filesystem Client -options NFSD # Network Filesystem Server -options NFSLOCKD # Network Lock Manager -#options NFS_ROOT # NFS usable as /, requires NFSCL -#options MSDOSFS # MSDOS Filesystem -#options CD9660 # ISO 9660 Filesystem -#options PROCFS # Process filesystem (requires PSEUDOFS) -#options PSEUDOFS # Pseudo-filesystem framework -options GEOM_PART_BSD # BSD partition scheme -options GEOM_PART_MBR # MBR partition scheme -#options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI -#options KTRACE # ktrace(1) support -options SYSVSHM # SYSV-style shared memory -options SYSVMSG # SYSV-style message queues -options SYSVSEM # SYSV-style semaphores -options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions - -# NFS root from boopt/dhcp -#options BOOTP -#options BOOTP_NFSROOT -#options BOOTP_COMPAT -#options BOOTP_NFSV3 -#options BOOTP_WIRED_TO=ate0 - -# s3 because s1 is reserved for the DOS parittions sometimes needed to -# boot off SD cards on the G20 and newer chips. s2 is reserved for -# nanobsd's config partition. s3 and s4 are for the ping-pong upgrade -# path. -options ROOTDEVNAME=\"ufs:/dev/mmcsd0s3a\" - -# kernel/memory size reduction -options MUTEX_NOINLINE -options NO_FFS_SNAPSHOT -options NO_SWAPPING -options NO_SYSCTL_DESCR -options RWLOCK_NOINLINE - -# The `bpf' device enables the Berkeley Packet Filter. -# Be aware of the administrative consequences of enabling this! -# Note that 'bpf' is required for DHCP. -device bpf # Berkeley packet filter - -# Ethernet -device mii # Minimal MII support -#device ate # Atmel AT91 Ethernet driver -#options AT91_ATE_USE_RMII -device macb # Atmel AT91 Ethernet driver -options AT91_MACB_USE_RMII - -# I2C -device at91_twi # Atmel AT91 Two-wire Interface -device iic # I2C generic I/O device driver -device iicbus # I2C bus system -device icee - -# MMC/SD -device at91_mci # Atmel AT91 Multimedia Card Interface -options AT91_MCI_HAS_4WIRE -options AT91_MCI_SLOT_B -device mmc # MMC/SD bus -device mmcsd # MMC/SD memory card - -# DataFlash -# NOTE: SPI DataFlash and mci/mmc/mmcsd have hardware -# confilict on this card. Use one or the other. -# see board_sam9g20ek.c -#device at91_spi # Atmel AT91 Serial Peripheral Interface -#device spibus # SPI bus -#device at45d # at45db642 and maybe others - -# Pseudo devices. -device loop # Network loopback -device random # Entropy device -device ether # Ethernet support -device md # Memory "disks" - -# SCSI peripherals -device scbus # SCSI bus (required for ATA/SCSI) -device da # Direct Access (disks) -device cd # CD -device pass # Passthrough device (direct ATA/SCSI access) - -# Serial (COM) ports -device uart # Multi-uart driver - -# USB support -device ohci # OHCI USB interface -device usb # USB Bus (required) -device umass # Disks/Mass storage - Requires scbus and da -device uhid # "Human Interface Devices" -#device ulpt # Printer -#device udbp # USB Double Bulk Pipe devices - -# USB Ethernet, requires miibus -#device miibus -#device aue # ADMtek USB Ethernet -#device axe # ASIX Electronics USB Ethernet -#device cdce # Generic USB over Ethernet -#device cue # CATC USB Ethernet -#device kue # Kawasaki LSI USB Ethernet -#device rue # RealTek RTL8150 USB Ethernet -#device udav # Davicom DM9601E USB - -# USB Wireless -#device rum # Ralink Technology RT2501USB wireless NICs -#device uath # Atheros AR5523 wireless NICs -#device ural # Ralink Technology RT2500USB wireless NICs -#device zyd # ZyDAS zd1211/zd1211b wireless NICs - -# Wireless NIC cards -#device wlan # 802.11 support -#device wlan_wep # 802.11 WEP support -#device wlan_ccmp # 802.11 CCMP support -#device wlan_tkip # 802.11 TKIP support -#device wlan_amrr # AMRR transmit rate control algorithm - -# watchdog -device at91_wdt # Atmel AT91 Watchdog Timer - -# NAND Flash - Reference design has Samsung 256MB but others possible -device nand # NAND interface on CS3 Index: head/sys/arm/include/at91_gpio.h =================================================================== --- head/sys/arm/include/at91_gpio.h +++ head/sys/arm/include/at91_gpio.h @@ -1,110 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2006 M. Warner Losh. - * Copyright (C) 2012 Ian Lepore. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _ARM_AT91_GPIO_H -#define _ARM_AT91_GPIO_H - -#ifndef _KERNEL -#include -#endif -#include - -/* Userland GPIO API for Atmel AT91 series SOC. - * - * Open /dev/pioN (where N is 0 for PIOA, 1 for PIOB, etc), and use ioctl(2) - * calls to configure the pin(s) as needed. - * - * The userland interrupt support allows you to use read(2) and/or select(2) to - * get notified of interrupts on PIO pins for which you enabled interrupt - * notifications. Each time an interrupt occurs on a given pin, that pin number - * is written into a buffer as a uint8_t. Thus, reading from /dev/pioN delivers - * info on which interrupt(s) have occurred since the last read. You can also - * use select() to block until an interrupt occurs (you still need to read() to - * consume the interrupt number bytes from the buffer.) - */ - -struct at91_gpio_info -{ - uint32_t output_status; /* Current state of output pins */ - uint32_t input_status; /* 1->out 0->in bitmask */ - uint32_t highz_status; /* 1->highz 0->driven bitmask */ - uint32_t pullup_status; /* 1->floating 0->pullup engaged */ - uint32_t glitch_status; /* 0-> no glitch filter 1->gf */ - uint32_t enabled_status; /* 1->used for pio 0->other */ - uint32_t periph_status; /* 0->A periph 1->B periph */ - uint32_t intr_status; /* 1-> ISR enabled, 0->disabled */ - uint32_t extra_status[8];/* Extra status info, device depend */ -}; - -struct at91_gpio_cfg -{ - uint32_t cfgmask; /* which things change */ -#define AT91_GPIO_CFG_INPUT 0x01 /* configure input/output pins */ -#define AT91_GPIO_CFG_HI_Z 0x02 /* HiZ */ -#define AT91_GPIO_CFG_PULLUP 0x04 /* Enable/disable pullup resistors */ -#define AT91_GPIO_CFG_GLITCH 0x08 /* Glitch filtering */ -#define AT91_GPIO_CFG_GPIO 0x10 /* Use pin for PIO or peripheral */ -#define AT91_GPIO_CFG_PERIPH 0x20 /* Select which peripheral to use */ -#define AT91_GPIO_CFG_INTR 0x40 /* Select pin for interrupts */ - uint32_t iomask; /* Mask of bits to change */ - uint32_t input; /* or output */ - uint32_t hi_z; /* Disable output */ - uint32_t pullup; /* Enable pullup resistor */ - uint32_t glitch; /* Glitch filtering */ - uint32_t gpio; /* Enabled for PIO (1) or periph (0) */ - uint32_t periph; /* Select periph A (0) or periph B (1) */ - uint32_t intr; /* Enable interrupt (1), or not (0) */ -}; - -struct at91_gpio_bang -{ - uint32_t clockpin; /* clock pin MASK */ - uint32_t datapin; /* Data pin MASK */ - uint32_t bits; /* bits to clock out (all 32) */ -}; - -struct at91_gpio_bang_many -{ - uint32_t clockpin; /* clock pin MASK */ - uint32_t datapin; /* Data pin MASK */ - void *bits; /* bits to clock out */ - uint32_t numbits; /* Number of bits to clock out */ -}; - -#define AT91_GPIO_SET _IOW('g', 0, uint32_t) /* Turn bits on */ -#define AT91_GPIO_CLR _IOW('g', 1, uint32_t) /* Turn bits off */ -#define AT91_GPIO_READ _IOR('g', 2, uint32_t) /* Read input bit state */ -#define AT91_GPIO_INFO _IOR('g', 3, struct at91_gpio_info) /* State of pio cfg */ -#define AT91_GPIO_CFG _IOW('g', 4, struct at91_gpio_cfg) /* Configure pio */ -#define AT91_GPIO_BANG _IOW('g', 5, struct at91_gpio_bang) /* bit bang 32 bits */ -#define AT91_GPIO_BANG_MANY _IOW('g', 6, struct at91_gpio_bang_many)/* bit bang >32 bits */ - -#endif /* _ARM_AT91_GPIO_H */ - Index: head/sys/conf/files =================================================================== --- head/sys/conf/files +++ head/sys/conf/files @@ -3237,10 +3237,7 @@ # # USB controller drivers # -dev/usb/controller/at91dci.c optional at91dci -dev/usb/controller/at91dci_atmelarm.c optional at91dci at91rm9200 dev/usb/controller/musb_otg.c optional musb -dev/usb/controller/musb_otg_atmelarm.c optional musb at91rm9200 dev/usb/controller/dwc_otg.c optional dwcotg dev/usb/controller/dwc_otg_fdt.c optional dwcotg fdt dev/usb/controller/ehci.c optional ehci @@ -3255,7 +3252,6 @@ dev/usb/controller/saf1761_otg.c optional saf1761otg dev/usb/controller/saf1761_otg_fdt.c optional saf1761otg fdt dev/usb/controller/uss820dci.c optional uss820dci -dev/usb/controller/uss820dci_atmelarm.c optional uss820dci at91rm9200 dev/usb/controller/usb_controller.c optional usb # # USB storage drivers Index: head/sys/conf/options.arm =================================================================== --- head/sys/conf/options.arm +++ head/sys/conf/options.arm @@ -70,13 +70,7 @@ XSACLE_DISABLE_CCNT opt_timer.h VERBOSE_INIT_ARM opt_global.h VM_MAXUSER_ADDRESS opt_global.h -AT91_ATE_USE_RMII opt_at91.h -AT91_MACB_USE_RMII opt_at91.h -AT91_MCI_ALLOW_OVERCLOCK opt_at91.h -AT91_MCI_HAS_4WIRE opt_at91.h -AT91_MCI_SLOT_B opt_at91.h GFB_DEBUG opt_gfb.h GFB_NO_FONT_LOADING opt_gfb.h GFB_NO_MODE_CHANGE opt_gfb.h -AT91C_MAIN_CLOCK opt_at91.h VFP opt_global.h Index: head/sys/dev/nand/nfc_at91.h =================================================================== --- head/sys/dev/nand/nfc_at91.h +++ head/sys/dev/nand/nfc_at91.h @@ -1,51 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2014 M. Warner Losh. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* - * Atmel at91-family integrated NAND controller driver. - * - * Interface to board setup code to set parameters. - */ - -#ifndef DEV_NAND_NFC_AT91_H -#define DEV_NAND_NFC_AT91_H 1 - -struct at91_nand_params -{ - uint32_t ale; /* Address for ALE (address) NAND cycles */ - uint32_t cle; /* Address for CLE (command) NAND cycles */ - uint32_t width; /* 8 or 16 bits (specify in bits) */ - uint32_t cs; /* Chip Select NAND is connected to */ - uint32_t rnb_pin; /* GPIO pin # for Read/notBusy */ - uint32_t nce_pin; /* GPIO pin # for CE (active low) */ -}; - -void at91_enable_nand(const struct at91_nand_params *); - -#endif /* DEV_NAND_NFC_AT91_H */ Index: head/sys/dev/nand/nfc_at91.c =================================================================== --- head/sys/dev/nand/nfc_at91.c +++ head/sys/dev/nand/nfc_at91.c @@ -1,295 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2013 Ian Lepore. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Atmel at91-family integrated NAND controller driver. - * - * This code relies on the board setup code (in at91/board_whatever.c) having - * set up the EBI and SMC registers appropriately for whatever type of nand part - * is on the board. - */ - -#include "opt_platform.h" - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include "nfc_if.h" - -#include -#include - -#ifdef FDT -#include -#include -#include -#endif - -/* - * Data cycles are triggered by access to any address within the EBI CS3 region - * that has A21 and A22 clear. Command cycles are any access with bit A21 - * asserted. Address cycles are any access with bit A22 asserted. Or vice versa. - * We get these parameters from the nand_param that the board is required to - * call at91_enable_nand, and enable the GPIO lines properly (that will be moved - * into at91_enable_nand when the great GPIO pin renumbering happens). We use - * ale (Address Latch Enable) and cle (Comand Latch Enable) to match the hardware - * names used in NAND. - */ -#define AT91_NAND_DATA 0 - -struct at91_nand_softc { - struct nand_softc nand_sc; - struct resource *res; - struct at91_nand_params *nand_param; -}; - -static struct at91_nand_params nand_param; - -static int at91_nand_attach(device_t); -static int at91_nand_probe(device_t); -static uint8_t at91_nand_read_byte(device_t); -static void at91_nand_read_buf(device_t, void *, uint32_t); -static int at91_nand_read_rnb(device_t); -static int at91_nand_select_cs(device_t, uint8_t); -static int at91_nand_send_command(device_t, uint8_t); -static int at91_nand_send_address(device_t, uint8_t); -static void at91_nand_write_buf(device_t, void *, uint32_t); - -void -at91_enable_nand(const struct at91_nand_params *np) -{ - nand_param = *np; -} - -static inline u_int8_t -dev_read_1(struct at91_nand_softc *sc, bus_size_t offset) -{ - return bus_read_1(sc->res, offset); -} - -static inline void -dev_write_1(struct at91_nand_softc *sc, bus_size_t offset, u_int8_t value) -{ - bus_write_1(sc->res, offset, value); -} - -static int -at91_nand_probe(device_t dev) -{ -#ifdef FDT - if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-nand")) - return (ENXIO); -#endif - device_set_desc(dev, "AT91 Integrated NAND controller"); - return (BUS_PROBE_DEFAULT); -} - -static int -at91_nand_attach(device_t dev) -{ - struct at91_nand_softc *sc; - int err, rid; - - sc = device_get_softc(dev); - sc->nand_param = &nand_param; - if (sc->nand_param->width != 8 && sc->nand_param->width != 16) { - device_printf(dev, "Bad bus width (%d) defaulting to 8 bits\n", - sc->nand_param->width); - sc->nand_param->width = 8; - } - at91_ebi_enable(sc->nand_param->cs); - - rid = 0; - sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - if (sc->res == NULL) { - device_printf(dev, "could not allocate resources!\n"); - return (ENXIO); - } - - nand_init(&sc->nand_sc, dev, NAND_ECC_SOFT, 0, 0, NULL, NULL); - - err = nandbus_create(dev); - - return (err); -} - -static int -at91_nand_send_command(device_t dev, uint8_t command) -{ - struct at91_nand_softc *sc; - - nand_debug(NDBG_DRV,"at91_nand_send_command: 0x%02x", command); - - sc = device_get_softc(dev); - dev_write_1(sc, sc->nand_param->cle, command); - return (0); -} - -static int -at91_nand_send_address(device_t dev, uint8_t addr) -{ - struct at91_nand_softc *sc; - - nand_debug(NDBG_DRV,"at91_nand_send_address: x%02x", addr); - - sc = device_get_softc(dev); - dev_write_1(sc, sc->nand_param->ale, addr); - return (0); -} - -static uint8_t -at91_nand_read_byte(device_t dev) -{ - struct at91_nand_softc *sc; - uint8_t data; - - sc = device_get_softc(dev); - data = dev_read_1(sc, AT91_NAND_DATA); - - nand_debug(NDBG_DRV,"at91_nand_read_byte: 0x%02x", data); - - return (data); -} - - -static void -at91_nand_dump_buf(const char *op, void* buf, uint32_t len) -{ - int i; - uint8_t *b = buf; - - printf("at91_nand_%s_buf (hex):", op); - for (i = 0; i < len; i++) { - if ((i & 0x01f) == 0) - printf("\n"); - printf(" %02x", b[i]); - } - printf("\n"); -} - -static void -at91_nand_read_buf(device_t dev, void* buf, uint32_t len) -{ - struct at91_nand_softc *sc; - - sc = device_get_softc(dev); - - bus_read_multi_1(sc->res, AT91_NAND_DATA, buf, len); - - if (nand_debug_flag & NDBG_DRV) - at91_nand_dump_buf("read", buf, len); -} - -static void -at91_nand_write_buf(device_t dev, void* buf, uint32_t len) -{ - struct at91_nand_softc *sc; - - sc = device_get_softc(dev); - - if (nand_debug_flag & NDBG_DRV) - at91_nand_dump_buf("write", buf, len); - - bus_write_multi_1(sc->res, AT91_NAND_DATA, buf, len); -} - -static int -at91_nand_select_cs(device_t dev, uint8_t cs) -{ - - if (cs > 0) - return (ENODEV); - - return (0); -} - -static int -at91_nand_read_rnb(device_t dev) -{ -#if 0 - /* - * XXX There's no way for this code to know which GPIO pin (if any) is - * attached to the chip's RNB line. Not to worry, nothing calls this; - * at higher layers, all the nand code uses status commands. - */ - uint32_t bits; - - bits = at91_pio_gpio_get(AT91RM92_PIOD_BASE, AT91C_PIO_PD15); - nand_debug(NDBG_DRV,"at91_nand: read_rnb: %#x", bits); - return (bits != 0); /* ready */ -#endif - panic("at91_nand_read_rnb() is not implemented\n"); - return (0); -} - -static device_method_t at91_nand_methods[] = { - DEVMETHOD(device_probe, at91_nand_probe), - DEVMETHOD(device_attach, at91_nand_attach), - - DEVMETHOD(nfc_send_command, at91_nand_send_command), - DEVMETHOD(nfc_send_address, at91_nand_send_address), - DEVMETHOD(nfc_read_byte, at91_nand_read_byte), - DEVMETHOD(nfc_read_buf, at91_nand_read_buf), - DEVMETHOD(nfc_write_buf, at91_nand_write_buf), - DEVMETHOD(nfc_select_cs, at91_nand_select_cs), - DEVMETHOD(nfc_read_rnb, at91_nand_read_rnb), - - DEVMETHOD_END -}; - -static driver_t at91_nand_driver = { - "nand", - at91_nand_methods, - sizeof(struct at91_nand_softc), -}; - -static devclass_t at91_nand_devclass; - -#ifdef FDT -DRIVER_MODULE(at91_nand, simplebus, at91_nand_driver, at91_nand_devclass, 0, 0); -#else -DRIVER_MODULE(at91_nand, atmelarm, at91_nand_driver, at91_nand_devclass, 0, 0); -#endif Index: head/sys/dev/usb/controller/at91dci.h =================================================================== --- head/sys/dev/usb/controller/at91dci.h +++ head/sys/dev/usb/controller/at91dci.h @@ -1,245 +0,0 @@ -/* $FreeBSD$ */ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2006 ATMEL - * Copyright (c) 2007 Hans Petter Selasky - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * USB Device Port (UDP) register definition, based on "AT91RM9200.h" provided - * by ATMEL. - */ - -#ifndef _AT9100_DCI_H_ -#define _AT9100_DCI_H_ - -#define AT91_MAX_DEVICES (USB_MIN_DEVICES + 1) - -#define AT91_UDP_FRM 0x00 /* Frame number register */ -#define AT91_UDP_FRM_MASK (0x7FF << 0) /* Frame Number as Defined in - * the Packet Field Formats */ -#define AT91_UDP_FRM_ERR (0x1 << 16) /* Frame Error */ -#define AT91_UDP_FRM_OK (0x1 << 17) /* Frame OK */ - -#define AT91_UDP_GSTATE 0x04 /* Global state register */ -#define AT91_UDP_GSTATE_ADDR (0x1 << 0) /* Addressed state */ -#define AT91_UDP_GSTATE_CONFG (0x1 << 1) /* Configured */ -#define AT91_UDP_GSTATE_ESR (0x1 << 2) /* Enable Send Resume */ -#define AT91_UDP_GSTATE_RSM (0x1 << 3) /* A Resume Has Been Sent to - * the Host */ -#define AT91_UDP_GSTATE_RMW (0x1 << 4) /* Remote Wake Up Enable */ - -#define AT91_UDP_FADDR 0x08 /* Function Address Register */ -#define AT91_UDP_FADDR_MASK (0x7F << 0)/* Function Address Mask */ -#define AT91_UDP_FADDR_EN (0x1 << 8)/* Function Enable */ - -#define AT91_UDP_RES0 0x0C /* Reserved 0 */ - -#define AT91_UDP_IER 0x10 /* Interrupt Enable Register */ -#define AT91_UDP_IDR 0x14 /* Interrupt Disable Register */ -#define AT91_UDP_IMR 0x18 /* Interrupt Mask Register */ -#define AT91_UDP_ISR 0x1C /* Interrupt Status Register */ -#define AT91_UDP_ICR 0x20 /* Interrupt Clear Register */ -#define AT91_UDP_INT_EP(n) (0x1 <<(n))/* Endpoint "n" Interrupt */ -#define AT91_UDP_INT_RXSUSP (0x1 << 8)/* USB Suspend Interrupt */ -#define AT91_UDP_INT_RXRSM (0x1 << 9)/* USB Resume Interrupt */ -#define AT91_UDP_INT_EXTRSM (0x1 << 10)/* USB External Resume Interrupt */ -#define AT91_UDP_INT_SOFINT (0x1 << 11)/* USB Start Of frame Interrupt */ -#define AT91_UDP_INT_END_BR (0x1 << 12)/* USB End Of Bus Reset Interrupt */ -#define AT91_UDP_INT_WAKEUP (0x1 << 13)/* USB Resume Interrupt */ - -#define AT91_UDP_INT_BUS \ - (AT91_UDP_INT_RXSUSP|AT91_UDP_INT_RXRSM| \ - AT91_UDP_INT_END_BR) - -#define AT91_UDP_INT_EPS \ - (AT91_UDP_INT_EP(0)|AT91_UDP_INT_EP(1)| \ - AT91_UDP_INT_EP(2)|AT91_UDP_INT_EP(3)| \ - AT91_UDP_INT_EP(4)|AT91_UDP_INT_EP(5)) - -#define AT91_UDP_INT_DEFAULT \ - (AT91_UDP_INT_EPS|AT91_UDP_INT_BUS) - -#define AT91_UDP_RES1 0x24 /* Reserved 1 */ -#define AT91_UDP_RST 0x28 /* Reset Endpoint Register */ -#define AT91_UDP_RST_EP(n) (0x1 << (n))/* Reset Endpoint "n" */ - -#define AT91_UDP_RES2 0x2C /* Reserved 2 */ - -#define AT91_UDP_CSR(n) (0x30 + (4*(n)))/* Endpoint Control and Status - * Register */ -#define AT91_UDP_CSR_TXCOMP (0x1 << 0) /* Generates an IN packet with data - * previously written in the DPR */ -#define AT91_UDP_CSR_RX_DATA_BK0 (0x1 << 1) /* Receive Data Bank 0 */ -#define AT91_UDP_CSR_RXSETUP (0x1 << 2) /* Sends STALL to the Host - * (Control endpoints) */ -#define AT91_UDP_CSR_ISOERROR (0x1 << 3) /* Isochronous error - * (Isochronous endpoints) */ -#define AT91_UDP_CSR_STALLSENT (0x1 << 3) /* Stall sent (Control, bulk, - * interrupt endpoints) */ -#define AT91_UDP_CSR_TXPKTRDY (0x1 << 4) /* Transmit Packet Ready */ -#define AT91_UDP_CSR_FORCESTALL (0x1 << 5) /* Force Stall (used by - * Control, Bulk and - * Isochronous endpoints). */ -#define AT91_UDP_CSR_RX_DATA_BK1 (0x1 << 6) /* Receive Data Bank 1 (only - * used by endpoints with - * ping-pong attributes). */ -#define AT91_UDP_CSR_DIR (0x1 << 7) /* Transfer Direction */ -#define AT91_UDP_CSR_ET_MASK (0x7 << 8) /* Endpoint transfer type mask */ -#define AT91_UDP_CSR_ET_CTRL (0x0 << 8) /* Control IN+OUT */ -#define AT91_UDP_CSR_ET_ISO (0x1 << 8) /* Isochronous */ -#define AT91_UDP_CSR_ET_BULK (0x2 << 8) /* Bulk */ -#define AT91_UDP_CSR_ET_INT (0x3 << 8) /* Interrupt */ -#define AT91_UDP_CSR_ET_DIR_OUT (0x0 << 8) /* OUT tokens */ -#define AT91_UDP_CSR_ET_DIR_IN (0x4 << 8) /* IN tokens */ -#define AT91_UDP_CSR_DTGLE (0x1 << 11) /* Data Toggle */ -#define AT91_UDP_CSR_EPEDS (0x1 << 15) /* Endpoint Enable Disable */ -#define AT91_UDP_CSR_RXBYTECNT (0x7FF << 16) /* Number Of Bytes Available - * in the FIFO */ - -#define AT91_UDP_FDR(n) (0x50 + (4*(n)))/* Endpoint FIFO Data Register */ -#define AT91_UDP_RES3 0x70 /* Reserved 3 */ -#define AT91_UDP_TXVC 0x74 /* Transceiver Control Register */ -#define AT91_UDP_TXVC_DIS (0x1 << 8) - -#define AT91_UDP_EP_MAX 6 /* maximum number of endpoints - * supported */ - -#define AT91_UDP_READ_4(sc, reg) \ - bus_space_read_4((sc)->sc_io_tag, (sc)->sc_io_hdl, reg) - -#define AT91_UDP_WRITE_4(sc, reg, data) \ - bus_space_write_4((sc)->sc_io_tag, (sc)->sc_io_hdl, reg, data) - -struct at91dci_td; -struct at91dci_softc; - -typedef uint8_t (at91dci_cmd_t)(struct at91dci_softc *sc, struct at91dci_td *td); - -struct at91dci_td { - struct at91dci_td *obj_next; - at91dci_cmd_t *func; - struct usb_page_cache *pc; - uint32_t offset; - uint32_t remainder; - uint16_t max_packet_size; - uint8_t status_reg; - uint8_t fifo_reg; - uint8_t fifo_bank:1; - uint8_t error:1; - uint8_t alt_next:1; - uint8_t short_pkt:1; - uint8_t support_multi_buffer:1; - uint8_t did_stall:1; -}; - -struct at91dci_std_temp { - at91dci_cmd_t *func; - struct usb_page_cache *pc; - struct at91dci_td *td; - struct at91dci_td *td_next; - uint32_t len; - uint32_t offset; - uint16_t max_frame_size; - uint8_t short_pkt; - /* - * short_pkt = 0: transfer should be short terminated - * short_pkt = 1: transfer should not be short terminated - */ - uint8_t setup_alt_next; - uint8_t did_stall; -}; - -struct at91dci_config_desc { - struct usb_config_descriptor confd; - struct usb_interface_descriptor ifcd; - struct usb_endpoint_descriptor endpd; -} __packed; - -union at91dci_hub_temp { - uWord wValue; - struct usb_port_status ps; -}; - -struct at91dci_ep_flags { - uint8_t fifo_bank:1; /* hardware specific */ -}; - -struct at91dci_flags { - uint8_t change_connect:1; - uint8_t change_suspend:1; - uint8_t status_suspend:1; /* set if suspended */ - uint8_t status_vbus:1; /* set if present */ - uint8_t status_bus_reset:1; /* set if reset complete */ - uint8_t remote_wakeup:1; - uint8_t self_powered:1; - uint8_t clocks_off:1; - uint8_t port_powered:1; - uint8_t port_enabled:1; - uint8_t d_pulled_up:1; -}; - -struct at91dci_softc { - struct usb_bus sc_bus; - union at91dci_hub_temp sc_hub_temp; - - struct usb_device *sc_devices[AT91_MAX_DEVICES]; - struct resource *sc_io_res; - struct resource *sc_irq_res; - void *sc_intr_hdl; - bus_size_t sc_io_size; - bus_space_tag_t sc_io_tag; - bus_space_handle_t sc_io_hdl; - - void (*sc_clocks_on) (void *arg); - void (*sc_clocks_off) (void *arg); - void *sc_clocks_arg; - - void (*sc_pull_up) (void *arg); - void (*sc_pull_down) (void *arg); - void *sc_pull_arg; - - uint32_t sc_xfer_complete; - - uint8_t sc_rt_addr; /* root HUB address */ - uint8_t sc_dv_addr; /* device address */ - uint8_t sc_conf; /* root HUB config */ - - uint8_t sc_hub_idata[1]; - - struct at91dci_flags sc_flags; - struct at91dci_ep_flags sc_ep_flags[AT91_UDP_EP_MAX]; -}; - -/* prototypes */ - -usb_error_t at91dci_init(struct at91dci_softc *sc); -void at91dci_uninit(struct at91dci_softc *sc); -driver_filter_t at91dci_filter_interrupt; -driver_intr_t at91dci_interrupt; -void at91dci_vbus_interrupt(struct at91dci_softc *sc, uint8_t is_on); - -#endif /* _AT9100_DCI_H_ */ Index: head/sys/dev/usb/controller/at91dci.c =================================================================== --- head/sys/dev/usb/controller/at91dci.c +++ head/sys/dev/usb/controller/at91dci.c @@ -1,2382 +0,0 @@ -/* $FreeBSD$ */ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2007-2008 Hans Petter Selasky. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * This file contains the driver for the AT91 series USB Device - * Controller - */ - -/* - * Thanks to "David Brownell" for helping out regarding the hardware - * endpoint profiles. - */ - -/* - * NOTE: The "fifo_bank" is not reset in hardware when the endpoint is - * reset. - * - * NOTE: When the chip detects BUS-reset it will also reset the - * endpoints, Function-address and more. - */ - -#ifdef USB_GLOBAL_INCLUDE_FILE -#include USB_GLOBAL_INCLUDE_FILE -#else -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define USB_DEBUG_VAR at91dcidebug - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#endif /* USB_GLOBAL_INCLUDE_FILE */ - -#include - -#define AT9100_DCI_BUS2SC(bus) \ - ((struct at91dci_softc *)(((uint8_t *)(bus)) - \ - ((uint8_t *)&(((struct at91dci_softc *)0)->sc_bus)))) - -#define AT9100_DCI_PC2SC(pc) \ - AT9100_DCI_BUS2SC(USB_DMATAG_TO_XROOT((pc)->tag_parent)->bus) - -#define AT9100_DCI_THREAD_IRQ \ - (AT91_UDP_INT_BUS | AT91_UDP_INT_END_BR | AT91_UDP_INT_RXRSM | AT91_UDP_INT_RXSUSP) - -#ifdef USB_DEBUG -static int at91dcidebug = 0; - -static SYSCTL_NODE(_hw_usb, OID_AUTO, at91dci, CTLFLAG_RW, 0, "USB at91dci"); -SYSCTL_INT(_hw_usb_at91dci, OID_AUTO, debug, CTLFLAG_RWTUN, - &at91dcidebug, 0, "at91dci debug level"); -#endif - -#define AT9100_DCI_INTR_ENDPT 1 - -/* prototypes */ - -static const struct usb_bus_methods at91dci_bus_methods; -static const struct usb_pipe_methods at91dci_device_bulk_methods; -static const struct usb_pipe_methods at91dci_device_ctrl_methods; -static const struct usb_pipe_methods at91dci_device_intr_methods; -static const struct usb_pipe_methods at91dci_device_isoc_fs_methods; - -static at91dci_cmd_t at91dci_setup_rx; -static at91dci_cmd_t at91dci_data_rx; -static at91dci_cmd_t at91dci_data_tx; -static at91dci_cmd_t at91dci_data_tx_sync; -static void at91dci_device_done(struct usb_xfer *, usb_error_t); -static void at91dci_do_poll(struct usb_bus *); -static void at91dci_standard_done(struct usb_xfer *); -static void at91dci_root_intr(struct at91dci_softc *sc); - -/* - * NOTE: Some of the bits in the CSR register have inverse meaning so - * we need a helper macro when acknowledging events: - */ -#define AT91_CSR_ACK(csr, what) do { \ - (csr) &= ~((AT91_UDP_CSR_FORCESTALL| \ - AT91_UDP_CSR_TXPKTRDY| \ - AT91_UDP_CSR_RXBYTECNT) ^ (what));\ - (csr) |= ((AT91_UDP_CSR_RX_DATA_BK0| \ - AT91_UDP_CSR_RX_DATA_BK1| \ - AT91_UDP_CSR_TXCOMP| \ - AT91_UDP_CSR_RXSETUP| \ - AT91_UDP_CSR_STALLSENT) ^ (what)); \ -} while (0) - -/* - * Here is a list of what the chip supports. - * Probably it supports more than listed here! - */ -static const struct usb_hw_ep_profile - at91dci_ep_profile[AT91_UDP_EP_MAX] = { - - [0] = { - .max_in_frame_size = 8, - .max_out_frame_size = 8, - .is_simplex = 1, - .support_control = 1, - }, - [1] = { - .max_in_frame_size = 64, - .max_out_frame_size = 64, - .is_simplex = 1, - .support_multi_buffer = 1, - .support_bulk = 1, - .support_interrupt = 1, - .support_isochronous = 1, - .support_in = 1, - .support_out = 1, - }, - [2] = { - .max_in_frame_size = 64, - .max_out_frame_size = 64, - .is_simplex = 1, - .support_multi_buffer = 1, - .support_bulk = 1, - .support_interrupt = 1, - .support_isochronous = 1, - .support_in = 1, - .support_out = 1, - }, - [3] = { - /* can also do BULK */ - .max_in_frame_size = 8, - .max_out_frame_size = 8, - .is_simplex = 1, - .support_interrupt = 1, - .support_in = 1, - .support_out = 1, - }, - [4] = { - .max_in_frame_size = 256, - .max_out_frame_size = 256, - .is_simplex = 1, - .support_multi_buffer = 1, - .support_bulk = 1, - .support_interrupt = 1, - .support_isochronous = 1, - .support_in = 1, - .support_out = 1, - }, - [5] = { - .max_in_frame_size = 256, - .max_out_frame_size = 256, - .is_simplex = 1, - .support_multi_buffer = 1, - .support_bulk = 1, - .support_interrupt = 1, - .support_isochronous = 1, - .support_in = 1, - .support_out = 1, - }, -}; - -static void -at91dci_get_hw_ep_profile(struct usb_device *udev, - const struct usb_hw_ep_profile **ppf, uint8_t ep_addr) -{ - if (ep_addr < AT91_UDP_EP_MAX) { - *ppf = (at91dci_ep_profile + ep_addr); - } else { - *ppf = NULL; - } -} - -static void -at91dci_clocks_on(struct at91dci_softc *sc) -{ - if (sc->sc_flags.clocks_off && - sc->sc_flags.port_powered) { - - DPRINTFN(5, "\n"); - - if (sc->sc_clocks_on) { - (sc->sc_clocks_on) (sc->sc_clocks_arg); - } - sc->sc_flags.clocks_off = 0; - - /* enable Transceiver */ - AT91_UDP_WRITE_4(sc, AT91_UDP_TXVC, 0); - } -} - -static void -at91dci_clocks_off(struct at91dci_softc *sc) -{ - if (!sc->sc_flags.clocks_off) { - - DPRINTFN(5, "\n"); - - /* disable Transceiver */ - AT91_UDP_WRITE_4(sc, AT91_UDP_TXVC, AT91_UDP_TXVC_DIS); - - if (sc->sc_clocks_off) { - (sc->sc_clocks_off) (sc->sc_clocks_arg); - } - sc->sc_flags.clocks_off = 1; - } -} - -static void -at91dci_pull_up(struct at91dci_softc *sc) -{ - /* pullup D+, if possible */ - - if (!sc->sc_flags.d_pulled_up && - sc->sc_flags.port_powered) { - sc->sc_flags.d_pulled_up = 1; - (sc->sc_pull_up) (sc->sc_pull_arg); - } -} - -static void -at91dci_pull_down(struct at91dci_softc *sc) -{ - /* pulldown D+, if possible */ - - if (sc->sc_flags.d_pulled_up) { - sc->sc_flags.d_pulled_up = 0; - (sc->sc_pull_down) (sc->sc_pull_arg); - } -} - -static void -at91dci_wakeup_peer(struct at91dci_softc *sc) -{ - if (!(sc->sc_flags.status_suspend)) { - return; - } - - AT91_UDP_WRITE_4(sc, AT91_UDP_GSTATE, AT91_UDP_GSTATE_ESR); - - /* wait 8 milliseconds */ - /* Wait for reset to complete. */ - usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 125); - - AT91_UDP_WRITE_4(sc, AT91_UDP_GSTATE, 0); -} - -static void -at91dci_set_address(struct at91dci_softc *sc, uint8_t addr) -{ - DPRINTFN(5, "addr=%d\n", addr); - - AT91_UDP_WRITE_4(sc, AT91_UDP_FADDR, addr | - AT91_UDP_FADDR_EN); -} - -static uint8_t -at91dci_setup_rx(struct at91dci_softc *sc, struct at91dci_td *td) -{ - struct usb_device_request req; - uint32_t csr; - uint32_t temp; - uint16_t count; - - /* read out FIFO status */ - csr = AT91_UDP_READ_4(sc, td->status_reg); - - DPRINTFN(5, "csr=0x%08x rem=%u\n", csr, td->remainder); - - temp = csr; - temp &= (AT91_UDP_CSR_RX_DATA_BK0 | - AT91_UDP_CSR_RX_DATA_BK1 | - AT91_UDP_CSR_STALLSENT | - AT91_UDP_CSR_RXSETUP | - AT91_UDP_CSR_TXCOMP); - - if (!(csr & AT91_UDP_CSR_RXSETUP)) { - goto not_complete; - } - /* clear did stall */ - td->did_stall = 0; - - /* get the packet byte count */ - count = (csr & AT91_UDP_CSR_RXBYTECNT) >> 16; - - /* verify data length */ - if (count != td->remainder) { - DPRINTFN(0, "Invalid SETUP packet " - "length, %d bytes\n", count); - goto not_complete; - } - if (count != sizeof(req)) { - DPRINTFN(0, "Unsupported SETUP packet " - "length, %d bytes\n", count); - goto not_complete; - } - /* receive data */ - bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl, - td->fifo_reg, (void *)&req, sizeof(req)); - - /* copy data into real buffer */ - usbd_copy_in(td->pc, 0, &req, sizeof(req)); - - td->offset = sizeof(req); - td->remainder = 0; - - /* sneak peek the set address */ - if ((req.bmRequestType == UT_WRITE_DEVICE) && - (req.bRequest == UR_SET_ADDRESS)) { - sc->sc_dv_addr = req.wValue[0] & 0x7F; - } else { - sc->sc_dv_addr = 0xFF; - } - - /* sneak peek the endpoint direction */ - if (req.bmRequestType & UE_DIR_IN) { - csr |= AT91_UDP_CSR_DIR; - } else { - csr &= ~AT91_UDP_CSR_DIR; - } - - /* write the direction of the control transfer */ - AT91_CSR_ACK(csr, temp); - AT91_UDP_WRITE_4(sc, td->status_reg, csr); - return (0); /* complete */ - -not_complete: - /* abort any ongoing transfer */ - if (!td->did_stall) { - DPRINTFN(5, "stalling\n"); - temp |= AT91_UDP_CSR_FORCESTALL; - td->did_stall = 1; - } - - /* clear interrupts, if any */ - if (temp) { - DPRINTFN(5, "clearing 0x%08x\n", temp); - AT91_CSR_ACK(csr, temp); - AT91_UDP_WRITE_4(sc, td->status_reg, csr); - } - return (1); /* not complete */ -} - -static uint8_t -at91dci_data_rx(struct at91dci_softc *sc, struct at91dci_td *td) -{ - struct usb_page_search buf_res; - uint32_t csr; - uint32_t temp; - uint16_t count; - uint8_t to; - uint8_t got_short; - - to = 2; /* don't loop forever! */ - got_short = 0; - - /* check if any of the FIFO banks have data */ -repeat: - /* read out FIFO status */ - csr = AT91_UDP_READ_4(sc, td->status_reg); - - DPRINTFN(5, "csr=0x%08x rem=%u\n", csr, td->remainder); - - if (csr & AT91_UDP_CSR_RXSETUP) { - if (td->remainder == 0) { - /* - * We are actually complete and have - * received the next SETUP - */ - DPRINTFN(5, "faking complete\n"); - return (0); /* complete */ - } - /* - * USB Host Aborted the transfer. - */ - td->error = 1; - return (0); /* complete */ - } - /* Make sure that "STALLSENT" gets cleared */ - temp = csr; - temp &= AT91_UDP_CSR_STALLSENT; - - /* check status */ - if (!(csr & (AT91_UDP_CSR_RX_DATA_BK0 | - AT91_UDP_CSR_RX_DATA_BK1))) { - if (temp) { - /* write command */ - AT91_CSR_ACK(csr, temp); - AT91_UDP_WRITE_4(sc, td->status_reg, csr); - } - return (1); /* not complete */ - } - /* get the packet byte count */ - count = (csr & AT91_UDP_CSR_RXBYTECNT) >> 16; - - /* verify the packet byte count */ - if (count != td->max_packet_size) { - if (count < td->max_packet_size) { - /* we have a short packet */ - td->short_pkt = 1; - got_short = 1; - } else { - /* invalid USB packet */ - td->error = 1; - return (0); /* we are complete */ - } - } - /* verify the packet byte count */ - if (count > td->remainder) { - /* invalid USB packet */ - td->error = 1; - return (0); /* we are complete */ - } - while (count > 0) { - usbd_get_page(td->pc, td->offset, &buf_res); - - /* get correct length */ - if (buf_res.length > count) { - buf_res.length = count; - } - /* receive data */ - bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl, - td->fifo_reg, buf_res.buffer, buf_res.length); - - /* update counters */ - count -= buf_res.length; - td->offset += buf_res.length; - td->remainder -= buf_res.length; - } - - /* clear status bits */ - if (td->support_multi_buffer) { - if (td->fifo_bank) { - td->fifo_bank = 0; - temp |= AT91_UDP_CSR_RX_DATA_BK1; - } else { - td->fifo_bank = 1; - temp |= AT91_UDP_CSR_RX_DATA_BK0; - } - } else { - temp |= (AT91_UDP_CSR_RX_DATA_BK0 | - AT91_UDP_CSR_RX_DATA_BK1); - } - - /* write command */ - AT91_CSR_ACK(csr, temp); - AT91_UDP_WRITE_4(sc, td->status_reg, csr); - - /* - * NOTE: We may have to delay a little bit before - * proceeding after clearing the DATA_BK bits. - */ - - /* check if we are complete */ - if ((td->remainder == 0) || got_short) { - if (td->short_pkt) { - /* we are complete */ - return (0); - } - /* else need to receive a zero length packet */ - } - if (--to) { - goto repeat; - } - return (1); /* not complete */ -} - -static uint8_t -at91dci_data_tx(struct at91dci_softc *sc, struct at91dci_td *td) -{ - struct usb_page_search buf_res; - uint32_t csr; - uint32_t temp; - uint16_t count; - uint8_t to; - - to = 2; /* don't loop forever! */ - -repeat: - - /* read out FIFO status */ - csr = AT91_UDP_READ_4(sc, td->status_reg); - - DPRINTFN(5, "csr=0x%08x rem=%u\n", csr, td->remainder); - - if (csr & AT91_UDP_CSR_RXSETUP) { - /* - * The current transfer was aborted - * by the USB Host - */ - td->error = 1; - return (0); /* complete */ - } - /* Make sure that "STALLSENT" gets cleared */ - temp = csr; - temp &= AT91_UDP_CSR_STALLSENT; - - if (csr & AT91_UDP_CSR_TXPKTRDY) { - if (temp) { - /* write command */ - AT91_CSR_ACK(csr, temp); - AT91_UDP_WRITE_4(sc, td->status_reg, csr); - } - return (1); /* not complete */ - } else { - /* clear TXCOMP and set TXPKTRDY */ - temp |= (AT91_UDP_CSR_TXCOMP | - AT91_UDP_CSR_TXPKTRDY); - } - - count = td->max_packet_size; - if (td->remainder < count) { - /* we have a short packet */ - td->short_pkt = 1; - count = td->remainder; - } - while (count > 0) { - usbd_get_page(td->pc, td->offset, &buf_res); - - /* get correct length */ - if (buf_res.length > count) { - buf_res.length = count; - } - /* transmit data */ - bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl, - td->fifo_reg, buf_res.buffer, buf_res.length); - - /* update counters */ - count -= buf_res.length; - td->offset += buf_res.length; - td->remainder -= buf_res.length; - } - - /* write command */ - AT91_CSR_ACK(csr, temp); - AT91_UDP_WRITE_4(sc, td->status_reg, csr); - - /* check remainder */ - if (td->remainder == 0) { - if (td->short_pkt) { - return (0); /* complete */ - } - /* else we need to transmit a short packet */ - } - if (--to) { - goto repeat; - } - return (1); /* not complete */ -} - -static uint8_t -at91dci_data_tx_sync(struct at91dci_softc *sc, struct at91dci_td *td) -{ - uint32_t csr; - uint32_t temp; - - /* read out FIFO status */ - csr = AT91_UDP_READ_4(sc, td->status_reg); - - DPRINTFN(5, "csr=0x%08x\n", csr); - - if (csr & AT91_UDP_CSR_RXSETUP) { - DPRINTFN(5, "faking complete\n"); - /* Race condition */ - return (0); /* complete */ - } - temp = csr; - temp &= (AT91_UDP_CSR_STALLSENT | - AT91_UDP_CSR_TXCOMP); - - /* check status */ - if (csr & AT91_UDP_CSR_TXPKTRDY) { - goto not_complete; - } - if (!(csr & AT91_UDP_CSR_TXCOMP)) { - goto not_complete; - } - if (td->status_reg == AT91_UDP_CSR(0) && sc->sc_dv_addr != 0xFF) { - /* - * The AT91 has a special requirement with regard to - * setting the address and that is to write the new - * address before clearing TXCOMP: - */ - at91dci_set_address(sc, sc->sc_dv_addr); - } - /* write command */ - AT91_CSR_ACK(csr, temp); - AT91_UDP_WRITE_4(sc, td->status_reg, csr); - - return (0); /* complete */ - -not_complete: - if (temp) { - /* write command */ - AT91_CSR_ACK(csr, temp); - AT91_UDP_WRITE_4(sc, td->status_reg, csr); - } - return (1); /* not complete */ -} - -static void -at91dci_xfer_do_fifo(struct usb_xfer *xfer) -{ - struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus); - struct at91dci_td *td; - uint8_t temp; - - DPRINTFN(9, "\n"); - - td = xfer->td_transfer_cache; - if (td == NULL) - return; - - while (1) { - if ((td->func) (sc, td)) { - /* operation in progress */ - break; - } - if (((void *)td) == xfer->td_transfer_last) { - goto done; - } - if (td->error) { - goto done; - } else if (td->remainder > 0) { - /* - * We had a short transfer. If there is no alternate - * next, stop processing ! - */ - if (!td->alt_next) { - goto done; - } - } - /* - * Fetch the next transfer descriptor and transfer - * some flags to the next transfer descriptor - */ - temp = 0; - if (td->fifo_bank) - temp |= 1; - td = td->obj_next; - xfer->td_transfer_cache = td; - if (temp & 1) - td->fifo_bank = 1; - } - return; - -done: - temp = (xfer->endpointno & UE_ADDR); - - /* update FIFO bank flag and multi buffer */ - if (td->fifo_bank) { - sc->sc_ep_flags[temp].fifo_bank = 1; - } else { - sc->sc_ep_flags[temp].fifo_bank = 0; - } - - /* compute all actual lengths */ - xfer->td_transfer_cache = NULL; - sc->sc_xfer_complete = 1; -} - -static uint8_t -at91dci_xfer_do_complete(struct usb_xfer *xfer) -{ - struct at91dci_td *td; - - DPRINTFN(9, "\n"); - td = xfer->td_transfer_cache; - if (td == NULL) { - /* compute all actual lengths */ - at91dci_standard_done(xfer); - return(1); - } - return (0); -} - -static void -at91dci_interrupt_poll_locked(struct at91dci_softc *sc) -{ - struct usb_xfer *xfer; - - TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) - at91dci_xfer_do_fifo(xfer); -} - -static void -at91dci_interrupt_complete_locked(struct at91dci_softc *sc) -{ - struct usb_xfer *xfer; -repeat: - TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) { - if (at91dci_xfer_do_complete(xfer)) - goto repeat; - } -} - -void -at91dci_vbus_interrupt(struct at91dci_softc *sc, uint8_t is_on) -{ - DPRINTFN(5, "vbus = %u\n", is_on); - - if (is_on) { - if (!sc->sc_flags.status_vbus) { - sc->sc_flags.status_vbus = 1; - - /* complete root HUB interrupt endpoint */ - at91dci_root_intr(sc); - } - } else { - if (sc->sc_flags.status_vbus) { - sc->sc_flags.status_vbus = 0; - sc->sc_flags.status_bus_reset = 0; - sc->sc_flags.status_suspend = 0; - sc->sc_flags.change_suspend = 0; - sc->sc_flags.change_connect = 1; - - /* complete root HUB interrupt endpoint */ - at91dci_root_intr(sc); - } - } -} - -int -at91dci_filter_interrupt(void *arg) -{ - struct at91dci_softc *sc = arg; - int retval = FILTER_HANDLED; - uint32_t status; - - USB_BUS_SPIN_LOCK(&sc->sc_bus); - - status = AT91_UDP_READ_4(sc, AT91_UDP_ISR); - status &= AT91_UDP_INT_DEFAULT; - - if (status & AT9100_DCI_THREAD_IRQ) - retval = FILTER_SCHEDULE_THREAD; - - /* acknowledge interrupts */ - AT91_UDP_WRITE_4(sc, AT91_UDP_ICR, status & ~AT9100_DCI_THREAD_IRQ); - - /* poll FIFOs, if any */ - at91dci_interrupt_poll_locked(sc); - - if (sc->sc_xfer_complete != 0) - retval = FILTER_SCHEDULE_THREAD; - - USB_BUS_SPIN_UNLOCK(&sc->sc_bus); - - return (retval); -} - -void -at91dci_interrupt(void *arg) -{ - struct at91dci_softc *sc = arg; - uint32_t status; - - USB_BUS_LOCK(&sc->sc_bus); - USB_BUS_SPIN_LOCK(&sc->sc_bus); - - status = AT91_UDP_READ_4(sc, AT91_UDP_ISR); - status &= AT9100_DCI_THREAD_IRQ; - - /* acknowledge interrupts */ - - AT91_UDP_WRITE_4(sc, AT91_UDP_ICR, status); - - /* check for any bus state change interrupts */ - - if (status & AT91_UDP_INT_BUS) { - - DPRINTFN(5, "real bus interrupt 0x%08x\n", status); - - if (status & AT91_UDP_INT_END_BR) { - - /* set correct state */ - sc->sc_flags.status_bus_reset = 1; - sc->sc_flags.status_suspend = 0; - sc->sc_flags.change_suspend = 0; - sc->sc_flags.change_connect = 1; - - /* disable resume interrupt */ - AT91_UDP_WRITE_4(sc, AT91_UDP_IDR, - AT91_UDP_INT_RXRSM); - /* enable suspend interrupt */ - AT91_UDP_WRITE_4(sc, AT91_UDP_IER, - AT91_UDP_INT_RXSUSP); - } - /* - * If RXRSM and RXSUSP is set at the same time we interpret - * that like RESUME. Resume is set when there is at least 3 - * milliseconds of inactivity on the USB BUS. - */ - if (status & AT91_UDP_INT_RXRSM) { - if (sc->sc_flags.status_suspend) { - sc->sc_flags.status_suspend = 0; - sc->sc_flags.change_suspend = 1; - - /* disable resume interrupt */ - AT91_UDP_WRITE_4(sc, AT91_UDP_IDR, - AT91_UDP_INT_RXRSM); - /* enable suspend interrupt */ - AT91_UDP_WRITE_4(sc, AT91_UDP_IER, - AT91_UDP_INT_RXSUSP); - } - } else if (status & AT91_UDP_INT_RXSUSP) { - if (!sc->sc_flags.status_suspend) { - sc->sc_flags.status_suspend = 1; - sc->sc_flags.change_suspend = 1; - - /* disable suspend interrupt */ - AT91_UDP_WRITE_4(sc, AT91_UDP_IDR, - AT91_UDP_INT_RXSUSP); - - /* enable resume interrupt */ - AT91_UDP_WRITE_4(sc, AT91_UDP_IER, - AT91_UDP_INT_RXRSM); - } - } - /* complete root HUB interrupt endpoint */ - at91dci_root_intr(sc); - } - - if (sc->sc_xfer_complete != 0) { - sc->sc_xfer_complete = 0; - at91dci_interrupt_complete_locked(sc); - } - USB_BUS_SPIN_UNLOCK(&sc->sc_bus); - USB_BUS_UNLOCK(&sc->sc_bus); -} - -static void -at91dci_setup_standard_chain_sub(struct at91dci_std_temp *temp) -{ - struct at91dci_td *td; - - /* get current Transfer Descriptor */ - td = temp->td_next; - temp->td = td; - - /* prepare for next TD */ - temp->td_next = td->obj_next; - - /* fill out the Transfer Descriptor */ - td->func = temp->func; - td->pc = temp->pc; - td->offset = temp->offset; - td->remainder = temp->len; - td->fifo_bank = 0; - td->error = 0; - td->did_stall = temp->did_stall; - td->short_pkt = temp->short_pkt; - td->alt_next = temp->setup_alt_next; -} - -static void -at91dci_setup_standard_chain(struct usb_xfer *xfer) -{ - struct at91dci_std_temp temp; - struct at91dci_softc *sc; - struct at91dci_td *td; - uint32_t x; - uint8_t ep_no; - uint8_t need_sync; - - DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n", - xfer->address, UE_GET_ADDR(xfer->endpointno), - xfer->sumlen, usbd_get_speed(xfer->xroot->udev)); - - temp.max_frame_size = xfer->max_frame_size; - - td = xfer->td_start[0]; - xfer->td_transfer_first = td; - xfer->td_transfer_cache = td; - - /* setup temp */ - - temp.pc = NULL; - temp.td = NULL; - temp.td_next = xfer->td_start[0]; - temp.offset = 0; - temp.setup_alt_next = xfer->flags_int.short_frames_ok || - xfer->flags_int.isochronous_xfr; - temp.did_stall = !xfer->flags_int.control_stall; - - sc = AT9100_DCI_BUS2SC(xfer->xroot->bus); - ep_no = (xfer->endpointno & UE_ADDR); - - /* check if we should prepend a setup message */ - - if (xfer->flags_int.control_xfr) { - if (xfer->flags_int.control_hdr) { - - temp.func = &at91dci_setup_rx; - temp.len = xfer->frlengths[0]; - temp.pc = xfer->frbuffers + 0; - temp.short_pkt = temp.len ? 1 : 0; - /* check for last frame */ - if (xfer->nframes == 1) { - /* no STATUS stage yet, SETUP is last */ - if (xfer->flags_int.control_act) - temp.setup_alt_next = 0; - } - - at91dci_setup_standard_chain_sub(&temp); - } - x = 1; - } else { - x = 0; - } - - if (x != xfer->nframes) { - if (xfer->endpointno & UE_DIR_IN) { - temp.func = &at91dci_data_tx; - need_sync = 1; - } else { - temp.func = &at91dci_data_rx; - need_sync = 0; - } - - /* setup "pc" pointer */ - temp.pc = xfer->frbuffers + x; - } else { - need_sync = 0; - } - while (x != xfer->nframes) { - - /* DATA0 / DATA1 message */ - - temp.len = xfer->frlengths[x]; - - x++; - - if (x == xfer->nframes) { - if (xfer->flags_int.control_xfr) { - if (xfer->flags_int.control_act) { - temp.setup_alt_next = 0; - } - } else { - temp.setup_alt_next = 0; - } - } - if (temp.len == 0) { - - /* make sure that we send an USB packet */ - - temp.short_pkt = 0; - - } else { - - /* regular data transfer */ - - temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1; - } - - at91dci_setup_standard_chain_sub(&temp); - - if (xfer->flags_int.isochronous_xfr) { - temp.offset += temp.len; - } else { - /* get next Page Cache pointer */ - temp.pc = xfer->frbuffers + x; - } - } - - /* check for control transfer */ - if (xfer->flags_int.control_xfr) { - - /* always setup a valid "pc" pointer for status and sync */ - temp.pc = xfer->frbuffers + 0; - temp.len = 0; - temp.short_pkt = 0; - temp.setup_alt_next = 0; - - /* check if we need to sync */ - if (need_sync) { - /* we need a SYNC point after TX */ - temp.func = &at91dci_data_tx_sync; - at91dci_setup_standard_chain_sub(&temp); - } - - /* check if we should append a status stage */ - if (!xfer->flags_int.control_act) { - - /* - * Send a DATA1 message and invert the current - * endpoint direction. - */ - if (xfer->endpointno & UE_DIR_IN) { - temp.func = &at91dci_data_rx; - need_sync = 0; - } else { - temp.func = &at91dci_data_tx; - need_sync = 1; - } - - at91dci_setup_standard_chain_sub(&temp); - if (need_sync) { - /* we need a SYNC point after TX */ - temp.func = &at91dci_data_tx_sync; - at91dci_setup_standard_chain_sub(&temp); - } - } - } - - /* must have at least one frame! */ - td = temp.td; - xfer->td_transfer_last = td; - - /* setup the correct fifo bank */ - if (sc->sc_ep_flags[ep_no].fifo_bank) { - td = xfer->td_transfer_first; - td->fifo_bank = 1; - } -} - -static void -at91dci_timeout(void *arg) -{ - struct usb_xfer *xfer = arg; - - DPRINTF("xfer=%p\n", xfer); - - USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED); - - /* transfer is transferred */ - at91dci_device_done(xfer, USB_ERR_TIMEOUT); -} - -static void -at91dci_start_standard_chain(struct usb_xfer *xfer) -{ - struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus); - - DPRINTFN(9, "\n"); - - USB_BUS_SPIN_LOCK(&sc->sc_bus); - - /* poll one time */ - at91dci_xfer_do_fifo(xfer); - - if (at91dci_xfer_do_complete(xfer) == 0) { - - uint8_t ep_no = xfer->endpointno & UE_ADDR; - - /* - * Only enable the endpoint interrupt when we are actually - * waiting for data, hence we are dealing with level - * triggered interrupts ! - */ - AT91_UDP_WRITE_4(sc, AT91_UDP_IER, AT91_UDP_INT_EP(ep_no)); - - DPRINTFN(15, "enable interrupts on endpoint %d\n", ep_no); - - /* put transfer on interrupt queue */ - usbd_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer); - - /* start timeout, if any */ - if (xfer->timeout != 0) { - usbd_transfer_timeout_ms(xfer, - &at91dci_timeout, xfer->timeout); - } - } - USB_BUS_SPIN_UNLOCK(&sc->sc_bus); -} - -static void -at91dci_root_intr(struct at91dci_softc *sc) -{ - DPRINTFN(9, "\n"); - - USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); - - /* set port bit */ - sc->sc_hub_idata[0] = 0x02; /* we only have one port */ - - uhub_root_intr(&sc->sc_bus, sc->sc_hub_idata, - sizeof(sc->sc_hub_idata)); -} - -static usb_error_t -at91dci_standard_done_sub(struct usb_xfer *xfer) -{ - struct at91dci_td *td; - uint32_t len; - uint8_t error; - - DPRINTFN(9, "\n"); - - td = xfer->td_transfer_cache; - - do { - len = td->remainder; - - if (xfer->aframes != xfer->nframes) { - /* - * Verify the length and subtract - * the remainder from "frlengths[]": - */ - if (len > xfer->frlengths[xfer->aframes]) { - td->error = 1; - } else { - xfer->frlengths[xfer->aframes] -= len; - } - } - /* Check for transfer error */ - if (td->error) { - /* the transfer is finished */ - error = 1; - td = NULL; - break; - } - /* Check for short transfer */ - if (len > 0) { - if (xfer->flags_int.short_frames_ok || - xfer->flags_int.isochronous_xfr) { - /* follow alt next */ - if (td->alt_next) { - td = td->obj_next; - } else { - td = NULL; - } - } else { - /* the transfer is finished */ - td = NULL; - } - error = 0; - break; - } - td = td->obj_next; - - /* this USB frame is complete */ - error = 0; - break; - - } while (0); - - /* update transfer cache */ - - xfer->td_transfer_cache = td; - - return (error ? - USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION); -} - -static void -at91dci_standard_done(struct usb_xfer *xfer) -{ - usb_error_t err = 0; - - DPRINTFN(13, "xfer=%p endpoint=%p transfer done\n", - xfer, xfer->endpoint); - - /* reset scanner */ - - xfer->td_transfer_cache = xfer->td_transfer_first; - - if (xfer->flags_int.control_xfr) { - - if (xfer->flags_int.control_hdr) { - - err = at91dci_standard_done_sub(xfer); - } - xfer->aframes = 1; - - if (xfer->td_transfer_cache == NULL) { - goto done; - } - } - while (xfer->aframes != xfer->nframes) { - - err = at91dci_standard_done_sub(xfer); - xfer->aframes++; - - if (xfer->td_transfer_cache == NULL) { - goto done; - } - } - - if (xfer->flags_int.control_xfr && - !xfer->flags_int.control_act) { - - err = at91dci_standard_done_sub(xfer); - } -done: - at91dci_device_done(xfer, err); -} - -/*------------------------------------------------------------------------* - * at91dci_device_done - * - * NOTE: this function can be called more than one time on the - * same USB transfer! - *------------------------------------------------------------------------*/ -static void -at91dci_device_done(struct usb_xfer *xfer, usb_error_t error) -{ - struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus); - uint8_t ep_no; - - USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); - - DPRINTFN(2, "xfer=%p, endpoint=%p, error=%d\n", - xfer, xfer->endpoint, error); - - USB_BUS_SPIN_LOCK(&sc->sc_bus); - - if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) { - ep_no = (xfer->endpointno & UE_ADDR); - - /* disable endpoint interrupt */ - AT91_UDP_WRITE_4(sc, AT91_UDP_IDR, AT91_UDP_INT_EP(ep_no)); - - DPRINTFN(15, "disable interrupts on endpoint %d\n", ep_no); - } - - /* dequeue transfer and start next transfer */ - usbd_transfer_done(xfer, error); - - USB_BUS_SPIN_UNLOCK(&sc->sc_bus); -} - -static void -at91dci_xfer_stall(struct usb_xfer *xfer) -{ - at91dci_device_done(xfer, USB_ERR_STALLED); -} - -static void -at91dci_set_stall(struct usb_device *udev, - struct usb_endpoint *ep, uint8_t *did_stall) -{ - struct at91dci_softc *sc; - uint32_t csr_val; - uint8_t csr_reg; - - USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED); - - DPRINTFN(5, "endpoint=%p\n", ep); - - /* set FORCESTALL */ - sc = AT9100_DCI_BUS2SC(udev->bus); - - USB_BUS_SPIN_LOCK(&sc->sc_bus); - csr_reg = (ep->edesc->bEndpointAddress & UE_ADDR); - csr_reg = AT91_UDP_CSR(csr_reg); - csr_val = AT91_UDP_READ_4(sc, csr_reg); - AT91_CSR_ACK(csr_val, AT91_UDP_CSR_FORCESTALL); - AT91_UDP_WRITE_4(sc, csr_reg, csr_val); - USB_BUS_SPIN_UNLOCK(&sc->sc_bus); -} - -static void -at91dci_clear_stall_sub(struct at91dci_softc *sc, uint8_t ep_no, - uint8_t ep_type, uint8_t ep_dir) -{ - const struct usb_hw_ep_profile *pf; - uint32_t csr_val; - uint32_t temp; - uint8_t csr_reg; - uint8_t to; - - if (ep_type == UE_CONTROL) { - /* clearing stall is not needed */ - return; - } - - USB_BUS_SPIN_LOCK(&sc->sc_bus); - - /* compute CSR register offset */ - csr_reg = AT91_UDP_CSR(ep_no); - - /* compute default CSR value */ - csr_val = 0; - AT91_CSR_ACK(csr_val, 0); - - /* disable endpoint */ - AT91_UDP_WRITE_4(sc, csr_reg, csr_val); - - /* get endpoint profile */ - at91dci_get_hw_ep_profile(NULL, &pf, ep_no); - - /* reset FIFO */ - AT91_UDP_WRITE_4(sc, AT91_UDP_RST, AT91_UDP_RST_EP(ep_no)); - AT91_UDP_WRITE_4(sc, AT91_UDP_RST, 0); - - /* - * NOTE: One would assume that a FIFO reset would release the - * FIFO banks as well, but it doesn't! We have to do this - * manually! - */ - - /* release FIFO banks, if any */ - for (to = 0; to != 2; to++) { - - /* get csr value */ - csr_val = AT91_UDP_READ_4(sc, csr_reg); - - if (csr_val & (AT91_UDP_CSR_RX_DATA_BK0 | - AT91_UDP_CSR_RX_DATA_BK1)) { - /* clear status bits */ - if (pf->support_multi_buffer) { - if (sc->sc_ep_flags[ep_no].fifo_bank) { - sc->sc_ep_flags[ep_no].fifo_bank = 0; - temp = AT91_UDP_CSR_RX_DATA_BK1; - } else { - sc->sc_ep_flags[ep_no].fifo_bank = 1; - temp = AT91_UDP_CSR_RX_DATA_BK0; - } - } else { - temp = (AT91_UDP_CSR_RX_DATA_BK0 | - AT91_UDP_CSR_RX_DATA_BK1); - } - } else { - temp = 0; - } - - /* clear FORCESTALL */ - temp |= AT91_UDP_CSR_STALLSENT; - - AT91_CSR_ACK(csr_val, temp); - AT91_UDP_WRITE_4(sc, csr_reg, csr_val); - } - - /* compute default CSR value */ - csr_val = 0; - AT91_CSR_ACK(csr_val, 0); - - /* enable endpoint */ - csr_val &= ~AT91_UDP_CSR_ET_MASK; - csr_val |= AT91_UDP_CSR_EPEDS; - - if (ep_type == UE_CONTROL) { - csr_val |= AT91_UDP_CSR_ET_CTRL; - } else { - if (ep_type == UE_BULK) { - csr_val |= AT91_UDP_CSR_ET_BULK; - } else if (ep_type == UE_INTERRUPT) { - csr_val |= AT91_UDP_CSR_ET_INT; - } else { - csr_val |= AT91_UDP_CSR_ET_ISO; - } - if (ep_dir & UE_DIR_IN) { - csr_val |= AT91_UDP_CSR_ET_DIR_IN; - } - } - - /* enable endpoint */ - AT91_UDP_WRITE_4(sc, AT91_UDP_CSR(ep_no), csr_val); - - USB_BUS_SPIN_UNLOCK(&sc->sc_bus); -} - -static void -at91dci_clear_stall(struct usb_device *udev, struct usb_endpoint *ep) -{ - struct at91dci_softc *sc; - struct usb_endpoint_descriptor *ed; - - DPRINTFN(5, "endpoint=%p\n", ep); - - USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED); - - /* check mode */ - if (udev->flags.usb_mode != USB_MODE_DEVICE) { - /* not supported */ - return; - } - /* get softc */ - sc = AT9100_DCI_BUS2SC(udev->bus); - - /* get endpoint descriptor */ - ed = ep->edesc; - - /* reset endpoint */ - at91dci_clear_stall_sub(sc, - (ed->bEndpointAddress & UE_ADDR), - (ed->bmAttributes & UE_XFERTYPE), - (ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT))); -} - -usb_error_t -at91dci_init(struct at91dci_softc *sc) -{ - uint32_t csr_val; - uint8_t n; - - DPRINTF("start\n"); - - /* set up the bus structure */ - sc->sc_bus.usbrev = USB_REV_1_1; - sc->sc_bus.methods = &at91dci_bus_methods; - - USB_BUS_LOCK(&sc->sc_bus); - - /* turn on clocks */ - - if (sc->sc_clocks_on) { - (sc->sc_clocks_on) (sc->sc_clocks_arg); - } - /* wait a little for things to stabilise */ - usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000); - - /* disable and clear all interrupts */ - - AT91_UDP_WRITE_4(sc, AT91_UDP_IDR, 0xFFFFFFFF); - AT91_UDP_WRITE_4(sc, AT91_UDP_ICR, 0xFFFFFFFF); - - /* compute default CSR value */ - - csr_val = 0; - AT91_CSR_ACK(csr_val, 0); - - /* disable all endpoints */ - - for (n = 0; n != AT91_UDP_EP_MAX; n++) { - - /* disable endpoint */ - AT91_UDP_WRITE_4(sc, AT91_UDP_CSR(n), csr_val); - } - - /* enable the control endpoint */ - - AT91_CSR_ACK(csr_val, AT91_UDP_CSR_ET_CTRL | - AT91_UDP_CSR_EPEDS); - - /* write to FIFO control register */ - - AT91_UDP_WRITE_4(sc, AT91_UDP_CSR(0), csr_val); - - /* enable the interrupts we want */ - - AT91_UDP_WRITE_4(sc, AT91_UDP_IER, AT91_UDP_INT_BUS); - - /* turn off clocks */ - - at91dci_clocks_off(sc); - - USB_BUS_UNLOCK(&sc->sc_bus); - - /* catch any lost interrupts */ - - at91dci_do_poll(&sc->sc_bus); - - return (0); /* success */ -} - -void -at91dci_uninit(struct at91dci_softc *sc) -{ - USB_BUS_LOCK(&sc->sc_bus); - - /* disable and clear all interrupts */ - AT91_UDP_WRITE_4(sc, AT91_UDP_IDR, 0xFFFFFFFF); - AT91_UDP_WRITE_4(sc, AT91_UDP_ICR, 0xFFFFFFFF); - - sc->sc_flags.port_powered = 0; - sc->sc_flags.status_vbus = 0; - sc->sc_flags.status_bus_reset = 0; - sc->sc_flags.status_suspend = 0; - sc->sc_flags.change_suspend = 0; - sc->sc_flags.change_connect = 1; - - at91dci_pull_down(sc); - at91dci_clocks_off(sc); - USB_BUS_UNLOCK(&sc->sc_bus); -} - -static void -at91dci_suspend(struct at91dci_softc *sc) -{ - /* TODO */ -} - -static void -at91dci_resume(struct at91dci_softc *sc) -{ - /* TODO */ -} - -static void -at91dci_do_poll(struct usb_bus *bus) -{ - struct at91dci_softc *sc = AT9100_DCI_BUS2SC(bus); - - USB_BUS_LOCK(&sc->sc_bus); - USB_BUS_SPIN_LOCK(&sc->sc_bus); - at91dci_interrupt_poll_locked(sc); - at91dci_interrupt_complete_locked(sc); - USB_BUS_SPIN_UNLOCK(&sc->sc_bus); - USB_BUS_UNLOCK(&sc->sc_bus); -} - -/*------------------------------------------------------------------------* - * at91dci bulk support - *------------------------------------------------------------------------*/ -static void -at91dci_device_bulk_open(struct usb_xfer *xfer) -{ - return; -} - -static void -at91dci_device_bulk_close(struct usb_xfer *xfer) -{ - at91dci_device_done(xfer, USB_ERR_CANCELLED); -} - -static void -at91dci_device_bulk_enter(struct usb_xfer *xfer) -{ - return; -} - -static void -at91dci_device_bulk_start(struct usb_xfer *xfer) -{ - /* setup TDs */ - at91dci_setup_standard_chain(xfer); - at91dci_start_standard_chain(xfer); -} - -static const struct usb_pipe_methods at91dci_device_bulk_methods = -{ - .open = at91dci_device_bulk_open, - .close = at91dci_device_bulk_close, - .enter = at91dci_device_bulk_enter, - .start = at91dci_device_bulk_start, -}; - -/*------------------------------------------------------------------------* - * at91dci control support - *------------------------------------------------------------------------*/ -static void -at91dci_device_ctrl_open(struct usb_xfer *xfer) -{ - return; -} - -static void -at91dci_device_ctrl_close(struct usb_xfer *xfer) -{ - at91dci_device_done(xfer, USB_ERR_CANCELLED); -} - -static void -at91dci_device_ctrl_enter(struct usb_xfer *xfer) -{ - return; -} - -static void -at91dci_device_ctrl_start(struct usb_xfer *xfer) -{ - /* setup TDs */ - at91dci_setup_standard_chain(xfer); - at91dci_start_standard_chain(xfer); -} - -static const struct usb_pipe_methods at91dci_device_ctrl_methods = -{ - .open = at91dci_device_ctrl_open, - .close = at91dci_device_ctrl_close, - .enter = at91dci_device_ctrl_enter, - .start = at91dci_device_ctrl_start, -}; - -/*------------------------------------------------------------------------* - * at91dci interrupt support - *------------------------------------------------------------------------*/ -static void -at91dci_device_intr_open(struct usb_xfer *xfer) -{ - return; -} - -static void -at91dci_device_intr_close(struct usb_xfer *xfer) -{ - at91dci_device_done(xfer, USB_ERR_CANCELLED); -} - -static void -at91dci_device_intr_enter(struct usb_xfer *xfer) -{ - return; -} - -static void -at91dci_device_intr_start(struct usb_xfer *xfer) -{ - /* setup TDs */ - at91dci_setup_standard_chain(xfer); - at91dci_start_standard_chain(xfer); -} - -static const struct usb_pipe_methods at91dci_device_intr_methods = -{ - .open = at91dci_device_intr_open, - .close = at91dci_device_intr_close, - .enter = at91dci_device_intr_enter, - .start = at91dci_device_intr_start, -}; - -/*------------------------------------------------------------------------* - * at91dci full speed isochronous support - *------------------------------------------------------------------------*/ -static void -at91dci_device_isoc_fs_open(struct usb_xfer *xfer) -{ - return; -} - -static void -at91dci_device_isoc_fs_close(struct usb_xfer *xfer) -{ - at91dci_device_done(xfer, USB_ERR_CANCELLED); -} - -static void -at91dci_device_isoc_fs_enter(struct usb_xfer *xfer) -{ - struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus); - uint32_t temp; - uint32_t nframes; - - DPRINTFN(6, "xfer=%p next=%d nframes=%d\n", - xfer, xfer->endpoint->isoc_next, xfer->nframes); - - /* get the current frame index */ - - nframes = AT91_UDP_READ_4(sc, AT91_UDP_FRM); - - /* - * check if the frame index is within the window where the frames - * will be inserted - */ - temp = (nframes - xfer->endpoint->isoc_next) & AT91_UDP_FRM_MASK; - - if ((xfer->endpoint->is_synced == 0) || - (temp < xfer->nframes)) { - /* - * If there is data underflow or the endpoint queue is - * empty we schedule the transfer a few frames ahead - * of the current frame position. Else two isochronous - * transfers might overlap. - */ - xfer->endpoint->isoc_next = (nframes + 3) & AT91_UDP_FRM_MASK; - xfer->endpoint->is_synced = 1; - DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next); - } - /* - * compute how many milliseconds the insertion is ahead of the - * current frame position: - */ - temp = (xfer->endpoint->isoc_next - nframes) & AT91_UDP_FRM_MASK; - - /* - * pre-compute when the isochronous transfer will be finished: - */ - xfer->isoc_time_complete = - usb_isoc_time_expand(&sc->sc_bus, nframes) + temp + - xfer->nframes; - - /* compute frame number for next insertion */ - xfer->endpoint->isoc_next += xfer->nframes; - - /* setup TDs */ - at91dci_setup_standard_chain(xfer); -} - -static void -at91dci_device_isoc_fs_start(struct usb_xfer *xfer) -{ - /* start TD chain */ - at91dci_start_standard_chain(xfer); -} - -static const struct usb_pipe_methods at91dci_device_isoc_fs_methods = -{ - .open = at91dci_device_isoc_fs_open, - .close = at91dci_device_isoc_fs_close, - .enter = at91dci_device_isoc_fs_enter, - .start = at91dci_device_isoc_fs_start, -}; - -/*------------------------------------------------------------------------* - * at91dci root control support - *------------------------------------------------------------------------* - * Simulate a hardware HUB by handling all the necessary requests. - *------------------------------------------------------------------------*/ - -static const struct usb_device_descriptor at91dci_devd = { - .bLength = sizeof(struct usb_device_descriptor), - .bDescriptorType = UDESC_DEVICE, - .bcdUSB = {0x00, 0x02}, - .bDeviceClass = UDCLASS_HUB, - .bDeviceSubClass = UDSUBCLASS_HUB, - .bDeviceProtocol = UDPROTO_FSHUB, - .bMaxPacketSize = 64, - .bcdDevice = {0x00, 0x01}, - .iManufacturer = 1, - .iProduct = 2, - .bNumConfigurations = 1, -}; - -static const struct at91dci_config_desc at91dci_confd = { - .confd = { - .bLength = sizeof(struct usb_config_descriptor), - .bDescriptorType = UDESC_CONFIG, - .wTotalLength[0] = sizeof(at91dci_confd), - .bNumInterface = 1, - .bConfigurationValue = 1, - .iConfiguration = 0, - .bmAttributes = UC_SELF_POWERED, - .bMaxPower = 0, - }, - .ifcd = { - .bLength = sizeof(struct usb_interface_descriptor), - .bDescriptorType = UDESC_INTERFACE, - .bNumEndpoints = 1, - .bInterfaceClass = UICLASS_HUB, - .bInterfaceSubClass = UISUBCLASS_HUB, - .bInterfaceProtocol = 0, - }, - .endpd = { - .bLength = sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = UDESC_ENDPOINT, - .bEndpointAddress = (UE_DIR_IN | AT9100_DCI_INTR_ENDPT), - .bmAttributes = UE_INTERRUPT, - .wMaxPacketSize[0] = 8, - .bInterval = 255, - }, -}; - -#define HSETW(ptr, val) ptr = { (uint8_t)(val), (uint8_t)((val) >> 8) } - -static const struct usb_hub_descriptor_min at91dci_hubd = { - .bDescLength = sizeof(at91dci_hubd), - .bDescriptorType = UDESC_HUB, - .bNbrPorts = 1, - HSETW(.wHubCharacteristics, (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL)), - .bPwrOn2PwrGood = 50, - .bHubContrCurrent = 0, - .DeviceRemovable = {0}, /* port is removable */ -}; - -#define STRING_VENDOR \ - "A\0T\0M\0E\0L" - -#define STRING_PRODUCT \ - "D\0C\0I\0 \0R\0o\0o\0t\0 \0H\0U\0B" - -USB_MAKE_STRING_DESC(STRING_VENDOR, at91dci_vendor); -USB_MAKE_STRING_DESC(STRING_PRODUCT, at91dci_product); - -static usb_error_t -at91dci_roothub_exec(struct usb_device *udev, - struct usb_device_request *req, const void **pptr, uint16_t *plength) -{ - struct at91dci_softc *sc = AT9100_DCI_BUS2SC(udev->bus); - const void *ptr; - uint16_t len; - uint16_t value; - uint16_t index; - usb_error_t err; - - USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); - - /* buffer reset */ - ptr = (const void *)&sc->sc_hub_temp; - len = 0; - err = 0; - - value = UGETW(req->wValue); - index = UGETW(req->wIndex); - - /* demultiplex the control request */ - - switch (req->bmRequestType) { - case UT_READ_DEVICE: - switch (req->bRequest) { - case UR_GET_DESCRIPTOR: - goto tr_handle_get_descriptor; - case UR_GET_CONFIG: - goto tr_handle_get_config; - case UR_GET_STATUS: - goto tr_handle_get_status; - default: - goto tr_stalled; - } - break; - - case UT_WRITE_DEVICE: - switch (req->bRequest) { - case UR_SET_ADDRESS: - goto tr_handle_set_address; - case UR_SET_CONFIG: - goto tr_handle_set_config; - case UR_CLEAR_FEATURE: - goto tr_valid; /* nop */ - case UR_SET_DESCRIPTOR: - goto tr_valid; /* nop */ - case UR_SET_FEATURE: - default: - goto tr_stalled; - } - break; - - case UT_WRITE_ENDPOINT: - switch (req->bRequest) { - case UR_CLEAR_FEATURE: - switch (UGETW(req->wValue)) { - case UF_ENDPOINT_HALT: - goto tr_handle_clear_halt; - case UF_DEVICE_REMOTE_WAKEUP: - goto tr_handle_clear_wakeup; - default: - goto tr_stalled; - } - break; - case UR_SET_FEATURE: - switch (UGETW(req->wValue)) { - case UF_ENDPOINT_HALT: - goto tr_handle_set_halt; - case UF_DEVICE_REMOTE_WAKEUP: - goto tr_handle_set_wakeup; - default: - goto tr_stalled; - } - break; - case UR_SYNCH_FRAME: - goto tr_valid; /* nop */ - default: - goto tr_stalled; - } - break; - - case UT_READ_ENDPOINT: - switch (req->bRequest) { - case UR_GET_STATUS: - goto tr_handle_get_ep_status; - default: - goto tr_stalled; - } - break; - - case UT_WRITE_INTERFACE: - switch (req->bRequest) { - case UR_SET_INTERFACE: - goto tr_handle_set_interface; - case UR_CLEAR_FEATURE: - goto tr_valid; /* nop */ - case UR_SET_FEATURE: - default: - goto tr_stalled; - } - break; - - case UT_READ_INTERFACE: - switch (req->bRequest) { - case UR_GET_INTERFACE: - goto tr_handle_get_interface; - case UR_GET_STATUS: - goto tr_handle_get_iface_status; - default: - goto tr_stalled; - } - break; - - case UT_WRITE_CLASS_INTERFACE: - case UT_WRITE_VENDOR_INTERFACE: - /* XXX forward */ - break; - - case UT_READ_CLASS_INTERFACE: - case UT_READ_VENDOR_INTERFACE: - /* XXX forward */ - break; - - case UT_WRITE_CLASS_DEVICE: - switch (req->bRequest) { - case UR_CLEAR_FEATURE: - goto tr_valid; - case UR_SET_DESCRIPTOR: - case UR_SET_FEATURE: - break; - default: - goto tr_stalled; - } - break; - - case UT_WRITE_CLASS_OTHER: - switch (req->bRequest) { - case UR_CLEAR_FEATURE: - goto tr_handle_clear_port_feature; - case UR_SET_FEATURE: - goto tr_handle_set_port_feature; - case UR_CLEAR_TT_BUFFER: - case UR_RESET_TT: - case UR_STOP_TT: - goto tr_valid; - - default: - goto tr_stalled; - } - break; - - case UT_READ_CLASS_OTHER: - switch (req->bRequest) { - case UR_GET_TT_STATE: - goto tr_handle_get_tt_state; - case UR_GET_STATUS: - goto tr_handle_get_port_status; - default: - goto tr_stalled; - } - break; - - case UT_READ_CLASS_DEVICE: - switch (req->bRequest) { - case UR_GET_DESCRIPTOR: - goto tr_handle_get_class_descriptor; - case UR_GET_STATUS: - goto tr_handle_get_class_status; - - default: - goto tr_stalled; - } - break; - default: - goto tr_stalled; - } - goto tr_valid; - -tr_handle_get_descriptor: - switch (value >> 8) { - case UDESC_DEVICE: - if (value & 0xff) { - goto tr_stalled; - } - len = sizeof(at91dci_devd); - ptr = (const void *)&at91dci_devd; - goto tr_valid; - case UDESC_CONFIG: - if (value & 0xff) { - goto tr_stalled; - } - len = sizeof(at91dci_confd); - ptr = (const void *)&at91dci_confd; - goto tr_valid; - case UDESC_STRING: - switch (value & 0xff) { - case 0: /* Language table */ - len = sizeof(usb_string_lang_en); - ptr = (const void *)&usb_string_lang_en; - goto tr_valid; - - case 1: /* Vendor */ - len = sizeof(at91dci_vendor); - ptr = (const void *)&at91dci_vendor; - goto tr_valid; - - case 2: /* Product */ - len = sizeof(at91dci_product); - ptr = (const void *)&at91dci_product; - goto tr_valid; - default: - break; - } - break; - default: - goto tr_stalled; - } - goto tr_stalled; - -tr_handle_get_config: - len = 1; - sc->sc_hub_temp.wValue[0] = sc->sc_conf; - goto tr_valid; - -tr_handle_get_status: - len = 2; - USETW(sc->sc_hub_temp.wValue, UDS_SELF_POWERED); - goto tr_valid; - -tr_handle_set_address: - if (value & 0xFF00) { - goto tr_stalled; - } - sc->sc_rt_addr = value; - goto tr_valid; - -tr_handle_set_config: - if (value >= 2) { - goto tr_stalled; - } - sc->sc_conf = value; - goto tr_valid; - -tr_handle_get_interface: - len = 1; - sc->sc_hub_temp.wValue[0] = 0; - goto tr_valid; - -tr_handle_get_tt_state: -tr_handle_get_class_status: -tr_handle_get_iface_status: -tr_handle_get_ep_status: - len = 2; - USETW(sc->sc_hub_temp.wValue, 0); - goto tr_valid; - -tr_handle_set_halt: -tr_handle_set_interface: -tr_handle_set_wakeup: -tr_handle_clear_wakeup: -tr_handle_clear_halt: - goto tr_valid; - -tr_handle_clear_port_feature: - if (index != 1) { - goto tr_stalled; - } - DPRINTFN(9, "UR_CLEAR_PORT_FEATURE on port %d\n", index); - - switch (value) { - case UHF_PORT_SUSPEND: - at91dci_wakeup_peer(sc); - break; - - case UHF_PORT_ENABLE: - sc->sc_flags.port_enabled = 0; - break; - - case UHF_PORT_TEST: - case UHF_PORT_INDICATOR: - case UHF_C_PORT_ENABLE: - case UHF_C_PORT_OVER_CURRENT: - case UHF_C_PORT_RESET: - /* nops */ - break; - case UHF_PORT_POWER: - sc->sc_flags.port_powered = 0; - at91dci_pull_down(sc); - at91dci_clocks_off(sc); - break; - case UHF_C_PORT_CONNECTION: - sc->sc_flags.change_connect = 0; - break; - case UHF_C_PORT_SUSPEND: - sc->sc_flags.change_suspend = 0; - break; - default: - err = USB_ERR_IOERROR; - goto done; - } - goto tr_valid; - -tr_handle_set_port_feature: - if (index != 1) { - goto tr_stalled; - } - DPRINTFN(9, "UR_SET_PORT_FEATURE\n"); - - switch (value) { - case UHF_PORT_ENABLE: - sc->sc_flags.port_enabled = 1; - break; - case UHF_PORT_SUSPEND: - case UHF_PORT_RESET: - case UHF_PORT_TEST: - case UHF_PORT_INDICATOR: - /* nops */ - break; - case UHF_PORT_POWER: - sc->sc_flags.port_powered = 1; - break; - default: - err = USB_ERR_IOERROR; - goto done; - } - goto tr_valid; - -tr_handle_get_port_status: - - DPRINTFN(9, "UR_GET_PORT_STATUS\n"); - - if (index != 1) { - goto tr_stalled; - } - if (sc->sc_flags.status_vbus) { - at91dci_clocks_on(sc); - at91dci_pull_up(sc); - } else { - at91dci_pull_down(sc); - at91dci_clocks_off(sc); - } - - /* Select FULL-speed and Device Side Mode */ - - value = UPS_PORT_MODE_DEVICE; - - if (sc->sc_flags.port_powered) { - value |= UPS_PORT_POWER; - } - if (sc->sc_flags.port_enabled) { - value |= UPS_PORT_ENABLED; - } - if (sc->sc_flags.status_vbus && - sc->sc_flags.status_bus_reset) { - value |= UPS_CURRENT_CONNECT_STATUS; - } - if (sc->sc_flags.status_suspend) { - value |= UPS_SUSPEND; - } - USETW(sc->sc_hub_temp.ps.wPortStatus, value); - - value = 0; - - if (sc->sc_flags.change_connect) { - value |= UPS_C_CONNECT_STATUS; - - if (sc->sc_flags.status_vbus && - sc->sc_flags.status_bus_reset) { - /* reset endpoint flags */ - memset(sc->sc_ep_flags, 0, sizeof(sc->sc_ep_flags)); - } - } - if (sc->sc_flags.change_suspend) { - value |= UPS_C_SUSPEND; - } - USETW(sc->sc_hub_temp.ps.wPortChange, value); - len = sizeof(sc->sc_hub_temp.ps); - goto tr_valid; - -tr_handle_get_class_descriptor: - if (value & 0xFF) { - goto tr_stalled; - } - ptr = (const void *)&at91dci_hubd; - len = sizeof(at91dci_hubd); - goto tr_valid; - -tr_stalled: - err = USB_ERR_STALLED; -tr_valid: -done: - *plength = len; - *pptr = ptr; - return (err); -} - -static void -at91dci_xfer_setup(struct usb_setup_params *parm) -{ - const struct usb_hw_ep_profile *pf; - struct at91dci_softc *sc; - struct usb_xfer *xfer; - void *last_obj; - uint32_t ntd; - uint32_t n; - uint8_t ep_no; - - sc = AT9100_DCI_BUS2SC(parm->udev->bus); - xfer = parm->curr_xfer; - - /* - * NOTE: This driver does not use any of the parameters that - * are computed from the following values. Just set some - * reasonable dummies: - */ - parm->hc_max_packet_size = 0x500; - parm->hc_max_packet_count = 1; - parm->hc_max_frame_size = 0x500; - - usbd_transfer_setup_sub(parm); - - /* - * compute maximum number of TDs - */ - if (parm->methods == &at91dci_device_ctrl_methods) { - - ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC 1 */ - + 1 /* SYNC 2 */ ; - - } else if (parm->methods == &at91dci_device_bulk_methods) { - - ntd = xfer->nframes + 1 /* SYNC */ ; - - } else if (parm->methods == &at91dci_device_intr_methods) { - - ntd = xfer->nframes + 1 /* SYNC */ ; - - } else if (parm->methods == &at91dci_device_isoc_fs_methods) { - - ntd = xfer->nframes + 1 /* SYNC */ ; - - } else { - - ntd = 0; - } - - /* - * check if "usbd_transfer_setup_sub" set an error - */ - if (parm->err) { - return; - } - /* - * allocate transfer descriptors - */ - last_obj = NULL; - - /* - * get profile stuff - */ - if (ntd) { - - ep_no = xfer->endpointno & UE_ADDR; - at91dci_get_hw_ep_profile(parm->udev, &pf, ep_no); - - if (pf == NULL) { - /* should not happen */ - parm->err = USB_ERR_INVAL; - return; - } - } else { - ep_no = 0; - pf = NULL; - } - - /* align data */ - parm->size[0] += ((-parm->size[0]) & (USB_HOST_ALIGN - 1)); - - for (n = 0; n != ntd; n++) { - - struct at91dci_td *td; - - if (parm->buf) { - - td = USB_ADD_BYTES(parm->buf, parm->size[0]); - - /* init TD */ - td->max_packet_size = xfer->max_packet_size; - td->status_reg = AT91_UDP_CSR(ep_no); - td->fifo_reg = AT91_UDP_FDR(ep_no); - if (pf->support_multi_buffer) { - td->support_multi_buffer = 1; - } - td->obj_next = last_obj; - - last_obj = td; - } - parm->size[0] += sizeof(*td); - } - - xfer->td_start[0] = last_obj; -} - -static void -at91dci_xfer_unsetup(struct usb_xfer *xfer) -{ - return; -} - -static void -at91dci_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc, - struct usb_endpoint *ep) -{ - struct at91dci_softc *sc = AT9100_DCI_BUS2SC(udev->bus); - - DPRINTFN(2, "endpoint=%p, addr=%d, endpt=%d, mode=%d (%d)\n", - ep, udev->address, - edesc->bEndpointAddress, udev->flags.usb_mode, - sc->sc_rt_addr); - - if (udev->device_index != sc->sc_rt_addr) { - - if (udev->speed != USB_SPEED_FULL) { - /* not supported */ - return; - } - switch (edesc->bmAttributes & UE_XFERTYPE) { - case UE_CONTROL: - ep->methods = &at91dci_device_ctrl_methods; - break; - case UE_INTERRUPT: - ep->methods = &at91dci_device_intr_methods; - break; - case UE_ISOCHRONOUS: - ep->methods = &at91dci_device_isoc_fs_methods; - break; - case UE_BULK: - ep->methods = &at91dci_device_bulk_methods; - break; - default: - /* do nothing */ - break; - } - } -} - -static void -at91dci_set_hw_power_sleep(struct usb_bus *bus, uint32_t state) -{ - struct at91dci_softc *sc = AT9100_DCI_BUS2SC(bus); - - switch (state) { - case USB_HW_POWER_SUSPEND: - at91dci_suspend(sc); - break; - case USB_HW_POWER_SHUTDOWN: - at91dci_uninit(sc); - break; - case USB_HW_POWER_RESUME: - at91dci_resume(sc); - break; - default: - break; - } -} - -static const struct usb_bus_methods at91dci_bus_methods = -{ - .endpoint_init = &at91dci_ep_init, - .xfer_setup = &at91dci_xfer_setup, - .xfer_unsetup = &at91dci_xfer_unsetup, - .get_hw_ep_profile = &at91dci_get_hw_ep_profile, - .set_stall = &at91dci_set_stall, - .xfer_stall = &at91dci_xfer_stall, - .clear_stall = &at91dci_clear_stall, - .roothub_exec = &at91dci_roothub_exec, - .xfer_poll = &at91dci_do_poll, - .set_hw_power_sleep = &at91dci_set_hw_power_sleep, -}; Index: head/sys/dev/usb/controller/at91dci_atmelarm.c =================================================================== --- head/sys/dev/usb/controller/at91dci_atmelarm.c +++ head/sys/dev/usb/controller/at91dci_atmelarm.c @@ -1,319 +0,0 @@ -#include -__FBSDID("$FreeBSD$"); - -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2007-2008 Hans Petter Selasky. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include -#include -#include - -#define MEM_RID 0 - -/* Pin Definitions - do they belong here or somewhere else ? -- YES! */ - -#define VBUS_MASK AT91C_PIO_PB24 -#define VBUS_BASE AT91RM92_PIOB_BASE - -#define PULLUP_MASK AT91C_PIO_PB22 -#define PULLUP_BASE AT91RM92_PIOB_BASE - -static device_probe_t at91_udp_probe; -static device_attach_t at91_udp_attach; -static device_detach_t at91_udp_detach; - -struct at91_udp_softc { - struct at91dci_softc sc_dci; /* must be first */ - struct at91_pmc_clock *sc_mclk; - struct at91_pmc_clock *sc_iclk; - struct at91_pmc_clock *sc_fclk; - struct callout sc_vbus; -}; - -static void -at91_vbus_poll(struct at91_udp_softc *sc) -{ - uint8_t vbus_val; - - vbus_val = at91_pio_gpio_get(VBUS_BASE, VBUS_MASK) != 0; - at91dci_vbus_interrupt(&sc->sc_dci, vbus_val); - - callout_reset(&sc->sc_vbus, hz, (void *)&at91_vbus_poll, sc); -} - -static void -at91_udp_clocks_on(void *arg) -{ - struct at91_udp_softc *sc = arg; - - at91_pmc_clock_enable(sc->sc_mclk); - at91_pmc_clock_enable(sc->sc_iclk); - at91_pmc_clock_enable(sc->sc_fclk); -} - -static void -at91_udp_clocks_off(void *arg) -{ - struct at91_udp_softc *sc = arg; - - at91_pmc_clock_disable(sc->sc_fclk); - at91_pmc_clock_disable(sc->sc_iclk); - at91_pmc_clock_disable(sc->sc_mclk); -} - -static void -at91_udp_pull_up(void *arg) -{ - at91_pio_gpio_set(PULLUP_BASE, PULLUP_MASK); -} - -static void -at91_udp_pull_down(void *arg) -{ - at91_pio_gpio_clear(PULLUP_BASE, PULLUP_MASK); -} - -static int -at91_udp_probe(device_t dev) -{ - device_set_desc(dev, "AT91 integrated AT91_UDP controller"); - return (0); -} - -static int -at91_udp_attach(device_t dev) -{ - struct at91_udp_softc *sc = device_get_softc(dev); - int err; - int rid; - - /* setup AT9100 USB device controller interface softc */ - - sc->sc_dci.sc_clocks_on = &at91_udp_clocks_on; - sc->sc_dci.sc_clocks_off = &at91_udp_clocks_off; - sc->sc_dci.sc_clocks_arg = sc; - sc->sc_dci.sc_pull_up = &at91_udp_pull_up; - sc->sc_dci.sc_pull_down = &at91_udp_pull_down; - sc->sc_dci.sc_pull_arg = sc; - - /* initialise some bus fields */ - sc->sc_dci.sc_bus.parent = dev; - sc->sc_dci.sc_bus.devices = sc->sc_dci.sc_devices; - sc->sc_dci.sc_bus.devices_max = AT91_MAX_DEVICES; - sc->sc_dci.sc_bus.dma_bits = 32; - - /* get all DMA memory */ - if (usb_bus_mem_alloc_all(&sc->sc_dci.sc_bus, - USB_GET_DMA_TAG(dev), NULL)) { - return (ENOMEM); - } - callout_init_mtx(&sc->sc_vbus, &sc->sc_dci.sc_bus.bus_mtx, 0); - - /* - * configure VBUS input pin, enable deglitch and enable - * interrupt : - */ - at91_pio_use_gpio(VBUS_BASE, VBUS_MASK); - at91_pio_gpio_input(VBUS_BASE, VBUS_MASK); - at91_pio_gpio_set_deglitch(VBUS_BASE, VBUS_MASK, 1); - at91_pio_gpio_set_interrupt(VBUS_BASE, VBUS_MASK, 0); - - /* - * configure PULLUP output pin : - */ - at91_pio_use_gpio(PULLUP_BASE, PULLUP_MASK); - at91_pio_gpio_output(PULLUP_BASE, PULLUP_MASK, 0); - - at91_udp_pull_down(sc); - - /* wait 10ms for pulldown to stabilise */ - usb_pause_mtx(NULL, hz / 100); - - sc->sc_mclk = at91_pmc_clock_ref("mck"); - sc->sc_iclk = at91_pmc_clock_ref("udc_clk"); - sc->sc_fclk = at91_pmc_clock_ref("udpck"); - - rid = MEM_RID; - sc->sc_dci.sc_io_res = - bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); - - if (!(sc->sc_dci.sc_io_res)) { - err = ENOMEM; - goto error; - } - sc->sc_dci.sc_io_tag = rman_get_bustag(sc->sc_dci.sc_io_res); - sc->sc_dci.sc_io_hdl = rman_get_bushandle(sc->sc_dci.sc_io_res); - sc->sc_dci.sc_io_size = rman_get_size(sc->sc_dci.sc_io_res); - - rid = 0; - sc->sc_dci.sc_irq_res = - bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); - if (!(sc->sc_dci.sc_irq_res)) { - goto error; - } - sc->sc_dci.sc_bus.bdev = device_add_child(dev, "usbus", -1); - if (!(sc->sc_dci.sc_bus.bdev)) { - goto error; - } - device_set_ivars(sc->sc_dci.sc_bus.bdev, &sc->sc_dci.sc_bus); - - err = bus_setup_intr(dev, sc->sc_dci.sc_irq_res, INTR_TYPE_TTY | INTR_MPSAFE, - at91dci_filter_interrupt, at91dci_interrupt, sc, &sc->sc_dci.sc_intr_hdl); - if (err) { - sc->sc_dci.sc_intr_hdl = NULL; - goto error; - } - - err = at91dci_init(&sc->sc_dci); - if (!err) { - err = device_probe_and_attach(sc->sc_dci.sc_bus.bdev); - } - if (err) { - goto error; - } else { - /* poll VBUS one time */ - USB_BUS_LOCK(&sc->sc_dci.sc_bus); - at91_vbus_poll(sc); - USB_BUS_UNLOCK(&sc->sc_dci.sc_bus); - } - return (0); - -error: - at91_udp_detach(dev); - return (ENXIO); -} - -static int -at91_udp_detach(device_t dev) -{ - struct at91_udp_softc *sc = device_get_softc(dev); - int err; - - /* during module unload there are lots of children leftover */ - device_delete_children(dev); - - USB_BUS_LOCK(&sc->sc_dci.sc_bus); - callout_stop(&sc->sc_vbus); - USB_BUS_UNLOCK(&sc->sc_dci.sc_bus); - - callout_drain(&sc->sc_vbus); - - /* disable Transceiver */ - AT91_UDP_WRITE_4(&sc->sc_dci, AT91_UDP_TXVC, AT91_UDP_TXVC_DIS); - - /* disable and clear all interrupts */ - AT91_UDP_WRITE_4(&sc->sc_dci, AT91_UDP_IDR, 0xFFFFFFFF); - AT91_UDP_WRITE_4(&sc->sc_dci, AT91_UDP_ICR, 0xFFFFFFFF); - - if (sc->sc_dci.sc_irq_res && sc->sc_dci.sc_intr_hdl) { - /* - * only call at91_udp_uninit() after at91_udp_init() - */ - at91dci_uninit(&sc->sc_dci); - - err = bus_teardown_intr(dev, sc->sc_dci.sc_irq_res, - sc->sc_dci.sc_intr_hdl); - sc->sc_dci.sc_intr_hdl = NULL; - } - if (sc->sc_dci.sc_irq_res) { - bus_release_resource(dev, SYS_RES_IRQ, 0, - sc->sc_dci.sc_irq_res); - sc->sc_dci.sc_irq_res = NULL; - } - if (sc->sc_dci.sc_io_res) { - bus_release_resource(dev, SYS_RES_MEMORY, MEM_RID, - sc->sc_dci.sc_io_res); - sc->sc_dci.sc_io_res = NULL; - } - usb_bus_mem_free_all(&sc->sc_dci.sc_bus, NULL); - - /* disable clocks */ - at91_pmc_clock_disable(sc->sc_iclk); - at91_pmc_clock_disable(sc->sc_fclk); - at91_pmc_clock_disable(sc->sc_mclk); - at91_pmc_clock_deref(sc->sc_fclk); - at91_pmc_clock_deref(sc->sc_iclk); - at91_pmc_clock_deref(sc->sc_mclk); - - return (0); -} - -static device_method_t at91_udp_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, at91_udp_probe), - DEVMETHOD(device_attach, at91_udp_attach), - DEVMETHOD(device_detach, at91_udp_detach), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - - DEVMETHOD_END -}; - -static driver_t at91_udp_driver = { - .name = "at91_udp", - .methods = at91_udp_methods, - .size = sizeof(struct at91_udp_softc), -}; - -static devclass_t at91_udp_devclass; - -DRIVER_MODULE(at91_udp, atmelarm, at91_udp_driver, at91_udp_devclass, 0, 0); Index: head/sys/dev/usb/controller/at91dci_fdt.c =================================================================== --- head/sys/dev/usb/controller/at91dci_fdt.c +++ head/sys/dev/usb/controller/at91dci_fdt.c @@ -1,325 +0,0 @@ -#include -__FBSDID("$FreeBSD$"); - -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2007-2008 Hans Petter Selasky. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include -#include -#include - -#define MEM_RID 0 - -/* Pin Definitions - do they belong here or somewhere else ? -- YES! */ - -#define VBUS_MASK AT91C_PIO_PB24 -#define VBUS_BASE AT91RM92_PIOB_BASE - -#define PULLUP_MASK AT91C_PIO_PB22 -#define PULLUP_BASE AT91RM92_PIOB_BASE - -static device_probe_t at91_udp_probe; -static device_attach_t at91_udp_attach; -static device_detach_t at91_udp_detach; - -struct at91_udp_softc { - struct at91dci_softc sc_dci; /* must be first */ - struct at91_pmc_clock *sc_mclk; - struct at91_pmc_clock *sc_iclk; - struct at91_pmc_clock *sc_fclk; - struct callout sc_vbus; -}; - -static void -at91_vbus_poll(struct at91_udp_softc *sc) -{ - uint8_t vbus_val; - - vbus_val = at91_pio_gpio_get(VBUS_BASE, VBUS_MASK) != 0; - at91dci_vbus_interrupt(&sc->sc_dci, vbus_val); - - callout_reset(&sc->sc_vbus, hz, (void *)&at91_vbus_poll, sc); -} - -static void -at91_udp_clocks_on(void *arg) -{ - struct at91_udp_softc *sc = arg; - - at91_pmc_clock_enable(sc->sc_mclk); - at91_pmc_clock_enable(sc->sc_iclk); - at91_pmc_clock_enable(sc->sc_fclk); -} - -static void -at91_udp_clocks_off(void *arg) -{ - struct at91_udp_softc *sc = arg; - - at91_pmc_clock_disable(sc->sc_fclk); - at91_pmc_clock_disable(sc->sc_iclk); - at91_pmc_clock_disable(sc->sc_mclk); -} - -static void -at91_udp_pull_up(void *arg) -{ - at91_pio_gpio_set(PULLUP_BASE, PULLUP_MASK); -} - -static void -at91_udp_pull_down(void *arg) -{ - at91_pio_gpio_clear(PULLUP_BASE, PULLUP_MASK); -} - -static int -at91_udp_probe(device_t dev) -{ - if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-udc")) - return (ENXIO); - device_set_desc(dev, "AT91 integrated AT91_UDP controller"); - return (0); -} - -static int -at91_udp_attach(device_t dev) -{ - struct at91_udp_softc *sc = device_get_softc(dev); - int err; - int rid; - - /* setup AT9100 USB device controller interface softc */ - - sc->sc_dci.sc_clocks_on = &at91_udp_clocks_on; - sc->sc_dci.sc_clocks_off = &at91_udp_clocks_off; - sc->sc_dci.sc_clocks_arg = sc; - sc->sc_dci.sc_pull_up = &at91_udp_pull_up; - sc->sc_dci.sc_pull_down = &at91_udp_pull_down; - sc->sc_dci.sc_pull_arg = sc; - - /* initialise some bus fields */ - sc->sc_dci.sc_bus.parent = dev; - sc->sc_dci.sc_bus.devices = sc->sc_dci.sc_devices; - sc->sc_dci.sc_bus.devices_max = AT91_MAX_DEVICES; - sc->sc_dci.sc_bus.dma_bits = 32; - - /* get all DMA memory */ - if (usb_bus_mem_alloc_all(&sc->sc_dci.sc_bus, - USB_GET_DMA_TAG(dev), NULL)) { - return (ENOMEM); - } - callout_init_mtx(&sc->sc_vbus, &sc->sc_dci.sc_bus.bus_mtx, 0); - - /* - * configure VBUS input pin, enable deglitch and enable - * interrupt : - */ - at91_pio_use_gpio(VBUS_BASE, VBUS_MASK); - at91_pio_gpio_input(VBUS_BASE, VBUS_MASK); - at91_pio_gpio_set_deglitch(VBUS_BASE, VBUS_MASK, 1); - at91_pio_gpio_set_interrupt(VBUS_BASE, VBUS_MASK, 0); - - /* - * configure PULLUP output pin : - */ - at91_pio_use_gpio(PULLUP_BASE, PULLUP_MASK); - at91_pio_gpio_output(PULLUP_BASE, PULLUP_MASK, 0); - - at91_udp_pull_down(sc); - - /* wait 10ms for pulldown to stabilise */ - usb_pause_mtx(NULL, hz / 100); - - sc->sc_mclk = at91_pmc_clock_ref("mck"); - sc->sc_iclk = at91_pmc_clock_ref("udc_clk"); - sc->sc_fclk = at91_pmc_clock_ref("udpck"); - - rid = MEM_RID; - sc->sc_dci.sc_io_res = - bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); - - if (!(sc->sc_dci.sc_io_res)) { - err = ENOMEM; - goto error; - } - sc->sc_dci.sc_io_tag = rman_get_bustag(sc->sc_dci.sc_io_res); - sc->sc_dci.sc_io_hdl = rman_get_bushandle(sc->sc_dci.sc_io_res); - sc->sc_dci.sc_io_size = rman_get_size(sc->sc_dci.sc_io_res); - - rid = 0; - sc->sc_dci.sc_irq_res = - bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); - if (!(sc->sc_dci.sc_irq_res)) { - goto error; - } - sc->sc_dci.sc_bus.bdev = device_add_child(dev, "usbus", -1); - if (!(sc->sc_dci.sc_bus.bdev)) { - goto error; - } - device_set_ivars(sc->sc_dci.sc_bus.bdev, &sc->sc_dci.sc_bus); - - err = bus_setup_intr(dev, sc->sc_dci.sc_irq_res, INTR_TYPE_TTY | INTR_MPSAFE, - at91dci_filter_interrupt, at91dci_interrupt, sc, &sc->sc_dci.sc_intr_hdl); - if (err) { - sc->sc_dci.sc_intr_hdl = NULL; - goto error; - } - - err = at91dci_init(&sc->sc_dci); - if (!err) { - err = device_probe_and_attach(sc->sc_dci.sc_bus.bdev); - } - if (err) { - goto error; - } else { - /* poll VBUS one time */ - USB_BUS_LOCK(&sc->sc_dci.sc_bus); - at91_vbus_poll(sc); - USB_BUS_UNLOCK(&sc->sc_dci.sc_bus); - } - return (0); - -error: - at91_udp_detach(dev); - return (ENXIO); -} - -static int -at91_udp_detach(device_t dev) -{ - struct at91_udp_softc *sc = device_get_softc(dev); - int err; - - /* during module unload there are lots of children leftover */ - device_delete_children(dev); - - USB_BUS_LOCK(&sc->sc_dci.sc_bus); - callout_stop(&sc->sc_vbus); - USB_BUS_UNLOCK(&sc->sc_dci.sc_bus); - - callout_drain(&sc->sc_vbus); - - /* disable Transceiver */ - AT91_UDP_WRITE_4(&sc->sc_dci, AT91_UDP_TXVC, AT91_UDP_TXVC_DIS); - - /* disable and clear all interrupts */ - AT91_UDP_WRITE_4(&sc->sc_dci, AT91_UDP_IDR, 0xFFFFFFFF); - AT91_UDP_WRITE_4(&sc->sc_dci, AT91_UDP_ICR, 0xFFFFFFFF); - - if (sc->sc_dci.sc_irq_res && sc->sc_dci.sc_intr_hdl) { - /* - * only call at91_udp_uninit() after at91_udp_init() - */ - at91dci_uninit(&sc->sc_dci); - - err = bus_teardown_intr(dev, sc->sc_dci.sc_irq_res, - sc->sc_dci.sc_intr_hdl); - sc->sc_dci.sc_intr_hdl = NULL; - } - if (sc->sc_dci.sc_irq_res) { - bus_release_resource(dev, SYS_RES_IRQ, 0, - sc->sc_dci.sc_irq_res); - sc->sc_dci.sc_irq_res = NULL; - } - if (sc->sc_dci.sc_io_res) { - bus_release_resource(dev, SYS_RES_MEMORY, MEM_RID, - sc->sc_dci.sc_io_res); - sc->sc_dci.sc_io_res = NULL; - } - usb_bus_mem_free_all(&sc->sc_dci.sc_bus, NULL); - - /* disable clocks */ - at91_pmc_clock_disable(sc->sc_iclk); - at91_pmc_clock_disable(sc->sc_fclk); - at91_pmc_clock_disable(sc->sc_mclk); - at91_pmc_clock_deref(sc->sc_fclk); - at91_pmc_clock_deref(sc->sc_iclk); - at91_pmc_clock_deref(sc->sc_mclk); - - return (0); -} - -static device_method_t at91_udp_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, at91_udp_probe), - DEVMETHOD(device_attach, at91_udp_attach), - DEVMETHOD(device_detach, at91_udp_detach), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - - DEVMETHOD_END -}; - -static driver_t at91_udp_driver = { - .name = "at91_udp", - .methods = at91_udp_methods, - .size = sizeof(struct at91_udp_softc), -}; - -static devclass_t at91_udp_devclass; - -DRIVER_MODULE(at91_udp, simplebus, at91_udp_driver, at91_udp_devclass, 0, 0); Index: head/sys/dev/usb/controller/atmegadci_atmelarm.c =================================================================== --- head/sys/dev/usb/controller/atmegadci_atmelarm.c +++ head/sys/dev/usb/controller/atmegadci_atmelarm.c @@ -1,213 +0,0 @@ -#include -__FBSDID("$FreeBSD$"); - -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2009 Hans Petter Selasky. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include - -static device_probe_t atmegadci_probe; -static device_attach_t atmegadci_attach; -static device_detach_t atmegadci_detach; - -struct atmegadci_super_softc { - struct atmegadci_softc sc_otg; /* must be first */ -}; - -static void -atmegadci_clocks_on(struct usb_bus *bus) -{ - /* TODO */ -} - -static void -atmegadci_clocks_off(struct usb_bus *bus) -{ - /* TODO */ -} - -static int -atmegadci_probe(device_t dev) -{ - device_set_desc(dev, "ATMEL OTG integrated USB controller"); - return (0); -} - -static int -atmegadci_attach(device_t dev) -{ - struct atmegadci_super_softc *sc = device_get_softc(dev); - int err; - int rid; - - /* setup MUSB OTG USB controller interface softc */ - sc->sc_otg.sc_clocks_on = &atmegadci_clocks_on; - sc->sc_otg.sc_clocks_off = &atmegadci_clocks_off; - - /* initialise some bus fields */ - sc->sc_otg.sc_bus.parent = dev; - sc->sc_otg.sc_bus.devices = sc->sc_otg.sc_devices; - sc->sc_otg.sc_bus.devices_max = ATMEGA_MAX_DEVICES; - sc->sc_otg.sc_bus.dma_bits = 32; - - /* get all DMA memory */ - if (usb_bus_mem_alloc_all(&sc->sc_otg.sc_bus, - USB_GET_DMA_TAG(dev), NULL)) { - return (ENOMEM); - } - rid = 0; - sc->sc_otg.sc_io_res = - bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); - - if (!(sc->sc_otg.sc_io_res)) { - err = ENOMEM; - goto error; - } - sc->sc_otg.sc_io_tag = rman_get_bustag(sc->sc_otg.sc_io_res); - sc->sc_otg.sc_io_hdl = rman_get_bushandle(sc->sc_otg.sc_io_res); - - rid = 0; - sc->sc_otg.sc_irq_res = - bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); - if (!(sc->sc_otg.sc_irq_res)) { - goto error; - } - sc->sc_otg.sc_bus.bdev = device_add_child(dev, "usbus", -1); - if (!(sc->sc_otg.sc_bus.bdev)) { - goto error; - } - device_set_ivars(sc->sc_otg.sc_bus.bdev, &sc->sc_otg.sc_bus); - - err = bus_setup_intr(dev, sc->sc_otg.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, - NULL, (driver_intr_t *)atmegadci_interrupt, sc, &sc->sc_otg.sc_intr_hdl); - if (err) { - sc->sc_otg.sc_intr_hdl = NULL; - goto error; - } - err = atmegadci_init(&sc->sc_otg); - if (!err) { - err = device_probe_and_attach(sc->sc_otg.sc_bus.bdev); - } - if (err) { - goto error; - } - return (0); - -error: - atmegadci_detach(dev); - return (ENXIO); -} - -static int -atmegadci_detach(device_t dev) -{ - struct atmegadci_super_softc *sc = device_get_softc(dev); - int err; - - /* during module unload there are lots of children leftover */ - device_delete_children(dev); - - if (sc->sc_otg.sc_irq_res && sc->sc_otg.sc_intr_hdl) { - /* - * only call atmegadci_uninit() after atmegadci_init() - */ - atmegadci_uninit(&sc->sc_otg); - - err = bus_teardown_intr(dev, sc->sc_otg.sc_irq_res, - sc->sc_otg.sc_intr_hdl); - sc->sc_otg.sc_intr_hdl = NULL; - } - /* free IRQ channel, if any */ - if (sc->sc_otg.sc_irq_res) { - bus_release_resource(dev, SYS_RES_IRQ, 0, - sc->sc_otg.sc_irq_res); - sc->sc_otg.sc_irq_res = NULL; - } - /* free memory resource, if any */ - if (sc->sc_otg.sc_io_res) { - bus_release_resource(dev, SYS_RES_MEMORY, 0, - sc->sc_otg.sc_io_res); - sc->sc_otg.sc_io_res = NULL; - } - usb_bus_mem_free_all(&sc->sc_otg.sc_bus, NULL); - - return (0); -} - -static device_method_t atmegadci_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, atmegadci_probe), - DEVMETHOD(device_attach, atmegadci_attach), - DEVMETHOD(device_detach, atmegadci_detach), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - - DEVMETHOD_END -}; - -static driver_t atmegadci_driver = { - .name = "atmegadci", - .methods = atmegadci_methods, - .size = sizeof(struct atmegadci_super_softc), -}; - -static devclass_t atmegadci_devclass; - -DRIVER_MODULE(atmegadci, atmelarm, atmegadci_driver, atmegadci_devclass, 0, 0); -MODULE_DEPEND(atmegadci, usb, 1, 1, 1); Index: head/sys/dev/usb/controller/musb_otg_atmelarm.c =================================================================== --- head/sys/dev/usb/controller/musb_otg_atmelarm.c +++ head/sys/dev/usb/controller/musb_otg_atmelarm.c @@ -1,262 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include - -static device_probe_t musbotg_probe; -static device_attach_t musbotg_attach; -static device_detach_t musbotg_detach; - -struct musbotg_super_softc { - struct musbotg_softc sc_otg; /* must be first */ -}; - -static void -musbotg_vbus_poll(struct musbotg_super_softc *sc) -{ - uint8_t vbus_val = 1; /* fake VBUS on - TODO */ - - /* just forward it */ - musbotg_vbus_interrupt(&sc->sc_otg, vbus_val); -} - -static void -musbotg_clocks_on(void *arg) -{ -#if 0 - struct musbotg_super_softc *sc = arg; - -#endif -} - -static void -musbotg_clocks_off(void *arg) -{ -#if 0 - struct musbotg_super_softc *sc = arg; - -#endif -} - -static void -musbotg_wrapper_interrupt(void *arg) -{ - - /* - * Nothing to do. - * Main driver takes care about everything - */ - musbotg_interrupt(arg, 0, 0, 0); -} - -static void -musbotg_ep_int_set(struct musbotg_softc *sc, int ep, int on) -{ - /* - * Nothing to do. - * Main driver takes care about everything - */ -} - -static int -musbotg_probe(device_t dev) -{ - device_set_desc(dev, "MUSB OTG integrated USB controller"); - return (0); -} - -static int -musbotg_attach(device_t dev) -{ - struct musbotg_super_softc *sc = device_get_softc(dev); - int err; - int rid; - - /* setup MUSB OTG USB controller interface softc */ - sc->sc_otg.sc_clocks_on = &musbotg_clocks_on; - sc->sc_otg.sc_clocks_off = &musbotg_clocks_off; - sc->sc_otg.sc_clocks_arg = sc; - - /* initialise some bus fields */ - sc->sc_otg.sc_bus.parent = dev; - sc->sc_otg.sc_bus.devices = sc->sc_otg.sc_devices; - sc->sc_otg.sc_bus.devices_max = MUSB2_MAX_DEVICES; - sc->sc_otg.sc_bus.dma_bits = 32; - - /* get all DMA memory */ - if (usb_bus_mem_alloc_all(&sc->sc_otg.sc_bus, - USB_GET_DMA_TAG(dev), NULL)) { - return (ENOMEM); - } - rid = 0; - sc->sc_otg.sc_io_res = - bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); - - if (!(sc->sc_otg.sc_io_res)) { - err = ENOMEM; - goto error; - } - sc->sc_otg.sc_io_tag = rman_get_bustag(sc->sc_otg.sc_io_res); - sc->sc_otg.sc_io_hdl = rman_get_bushandle(sc->sc_otg.sc_io_res); - sc->sc_otg.sc_io_size = rman_get_size(sc->sc_otg.sc_io_res); - - rid = 0; - sc->sc_otg.sc_irq_res = - bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); - if (!(sc->sc_otg.sc_irq_res)) { - goto error; - } - sc->sc_otg.sc_bus.bdev = device_add_child(dev, "usbus", -1); - if (!(sc->sc_otg.sc_bus.bdev)) { - goto error; - } - device_set_ivars(sc->sc_otg.sc_bus.bdev, &sc->sc_otg.sc_bus); - - sc->sc_otg.sc_id = 0; - sc->sc_otg.sc_platform_data = sc; - sc->sc_otg.sc_mode = MUSB2_DEVICE_MODE; - -#if (__FreeBSD_version >= 700031) - err = bus_setup_intr(dev, sc->sc_otg.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, - NULL, (driver_intr_t *)musbotg_wrapper_interrupt, sc, &sc->sc_otg.sc_intr_hdl); -#else - err = bus_setup_intr(dev, sc->sc_otg.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, - (driver_intr_t *)musbotg_wrapper_interrupt, sc, &sc->sc_otg.sc_intr_hdl); -#endif - if (err) { - sc->sc_otg.sc_intr_hdl = NULL; - goto error; - } - err = musbotg_init(&sc->sc_otg); - if (!err) { - err = device_probe_and_attach(sc->sc_otg.sc_bus.bdev); - } - if (err) { - goto error; - } else { - /* poll VBUS one time */ - musbotg_vbus_poll(sc); - } - return (0); - -error: - musbotg_detach(dev); - return (ENXIO); -} - -static int -musbotg_detach(device_t dev) -{ - struct musbotg_super_softc *sc = device_get_softc(dev); - int err; - - /* during module unload there are lots of children leftover */ - device_delete_children(dev); - - if (sc->sc_otg.sc_irq_res && sc->sc_otg.sc_intr_hdl) { - /* - * only call musbotg_uninit() after musbotg_init() - */ - musbotg_uninit(&sc->sc_otg); - - err = bus_teardown_intr(dev, sc->sc_otg.sc_irq_res, - sc->sc_otg.sc_intr_hdl); - sc->sc_otg.sc_intr_hdl = NULL; - } - /* free IRQ channel, if any */ - if (sc->sc_otg.sc_irq_res) { - bus_release_resource(dev, SYS_RES_IRQ, 0, - sc->sc_otg.sc_irq_res); - sc->sc_otg.sc_irq_res = NULL; - } - /* free memory resource, if any */ - if (sc->sc_otg.sc_io_res) { - bus_release_resource(dev, SYS_RES_MEMORY, 0, - sc->sc_otg.sc_io_res); - sc->sc_otg.sc_io_res = NULL; - } - usb_bus_mem_free_all(&sc->sc_otg.sc_bus, NULL); - - return (0); -} - -static device_method_t musbotg_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, musbotg_probe), - DEVMETHOD(device_attach, musbotg_attach), - DEVMETHOD(device_detach, musbotg_detach), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - - DEVMETHOD_END -}; - -static driver_t musbotg_driver = { - .name = "musbotg", - .methods = musbotg_methods, - .size = sizeof(struct musbotg_super_softc), -}; - -static devclass_t musbotg_devclass; - -DRIVER_MODULE(musbotg, atmelarm, musbotg_driver, musbotg_devclass, 0, 0); -MODULE_DEPEND(musbotg, usb, 1, 1, 1); Index: head/sys/dev/usb/controller/usb_controller.c =================================================================== --- head/sys/dev/usb/controller/usb_controller.c +++ head/sys/dev/usb/controller/usb_controller.c @@ -131,7 +131,6 @@ DRIVER_MODULE(usbus, xhci, usb_driver, usb_devclass, 0, 0); /* Device Only Drivers */ -DRIVER_MODULE(usbus, at91_udp, usb_driver, usb_devclass, 0, 0); DRIVER_MODULE(usbus, musbotg, usb_driver, usb_devclass, 0, 0); DRIVER_MODULE(usbus, uss820dci, usb_driver, usb_devclass, 0, 0); DRIVER_MODULE(usbus, octusb, usb_driver, usb_devclass, 0, 0); Index: head/sys/dev/usb/controller/uss820dci_atmelarm.c =================================================================== --- head/sys/dev/usb/controller/uss820dci_atmelarm.c +++ head/sys/dev/usb/controller/uss820dci_atmelarm.c @@ -1,197 +0,0 @@ -#include -__FBSDID("$FreeBSD$"); - -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2008 Hans Petter Selasky - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include - -static device_probe_t uss820_atmelarm_probe; -static device_attach_t uss820_atmelarm_attach; -static device_detach_t uss820_atmelarm_detach; - -static device_method_t uss820dci_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, uss820_atmelarm_probe), - DEVMETHOD(device_attach, uss820_atmelarm_attach), - DEVMETHOD(device_detach, uss820_atmelarm_detach), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - - DEVMETHOD_END -}; - -static driver_t uss820dci_driver = { - .name = "uss820dci", - .methods = uss820dci_methods, - .size = sizeof(struct uss820dci_softc), -}; - -static devclass_t uss820dci_devclass; - -DRIVER_MODULE(uss820dci, atmelarm, uss820dci_driver, uss820dci_devclass, 0, 0); -MODULE_DEPEND(uss820dci, usb, 1, 1, 1); - -static const char *const uss820_desc = "USS820 USB Device Controller"; - -static int -uss820_atmelarm_probe(device_t dev) -{ - device_set_desc(dev, uss820_desc); - return (0); /* success */ -} - -static int -uss820_atmelarm_attach(device_t dev) -{ - struct uss820dci_softc *sc = device_get_softc(dev); - int err; - int rid; - - /* initialise some bus fields */ - sc->sc_bus.parent = dev; - sc->sc_bus.devices = sc->sc_devices; - sc->sc_bus.devices_max = USS820_MAX_DEVICES; - sc->sc_bus.dma_bits = 32; - - /* get all DMA memory */ - if (usb_bus_mem_alloc_all(&sc->sc_bus, - USB_GET_DMA_TAG(dev), NULL)) { - return (ENOMEM); - } - rid = 0; - sc->sc_io_res = - bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); - - if (!sc->sc_io_res) { - goto error; - } - sc->sc_io_tag = rman_get_bustag(sc->sc_io_res); - sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res); - sc->sc_io_size = rman_get_size(sc->sc_io_res); - - rid = 0; - sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_SHAREABLE | RF_ACTIVE); - if (sc->sc_irq_res == NULL) { - goto error; - } - sc->sc_bus.bdev = device_add_child(dev, "usbus", -1); - if (!(sc->sc_bus.bdev)) { - goto error; - } - device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus); - - err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_TTY | INTR_MPSAFE, - uss820dci_filter_interrupt, uss820dci_interrupt, sc, &sc->sc_intr_hdl); - if (err) { - sc->sc_intr_hdl = NULL; - goto error; - } - err = uss820dci_init(sc); - if (err) { - device_printf(dev, "Init failed\n"); - goto error; - } - err = device_probe_and_attach(sc->sc_bus.bdev); - if (err) { - device_printf(dev, "USB probe and attach failed\n"); - goto error; - } - return (0); - -error: - uss820_atmelarm_detach(dev); - return (ENXIO); -} - -static int -uss820_atmelarm_detach(device_t dev) -{ - struct uss820dci_softc *sc = device_get_softc(dev); - int err; - - /* during module unload there are lots of children leftover */ - device_delete_children(dev); - - if (sc->sc_irq_res && sc->sc_intr_hdl) { - /* - * only call at91_udp_uninit() after at91_udp_init() - */ - uss820dci_uninit(sc); - - err = bus_teardown_intr(dev, sc->sc_irq_res, - sc->sc_intr_hdl); - sc->sc_intr_hdl = NULL; - } - if (sc->sc_irq_res) { - bus_release_resource(dev, SYS_RES_IRQ, 0, - sc->sc_irq_res); - sc->sc_irq_res = NULL; - } - if (sc->sc_io_res) { - bus_release_resource(dev, SYS_RES_IOPORT, 0, - sc->sc_io_res); - sc->sc_io_res = NULL; - } - usb_bus_mem_free_all(&sc->sc_bus, NULL); - - return (0); -} Index: head/sys/dts/arm/hl201.dts =================================================================== --- head/sys/dts/arm/hl201.dts +++ head/sys/dts/arm/hl201.dts @@ -1,44 +0,0 @@ -/* - * Hot-e HL-201 - Warner Losh public domain - * - * $FreeBSD$ - */ -/dts-v1/; - -/* - * The following is a white lie. The HL-201 is a stripped down version of - * the SAM9G20EK board with a video output chip. - */ -#include "at91sam9g20ek_common.dtsi" - -/ { - model = "Thinlinx HL201"; - compatible = "thinlinx,hl201", "atmel,at91sam9g20ek", "atmel,at91sam9g20", "atmel,at91sam9"; - - leds { - compatible = "gpio-leds"; - - ds1 { - label = "ds1"; - gpios = <&pioA 9 0>; - linux,default-trigger = "heartbeat"; - }; - - ds5 { - label = "ds5"; - gpios = <&pioA 6 1>; - }; - }; - - /* Missing: one wire serial number, video chip */ - - aliases { - dbgu = &dbgu; - }; - - - chosen { - stdin = "dbgu"; - stdout = "dbgu"; - }; -}; Index: head/sys/dts/arm/sam9260ek.dts =================================================================== --- head/sys/dts/arm/sam9260ek.dts +++ head/sys/dts/arm/sam9260ek.dts @@ -1,37 +0,0 @@ -/* - * SAM9260EK eval board - Warner Losh public domain - * - * $FreeBSD$ - */ -/dts-v1/; -#include "sam9260ek_common.dtsi" - -/ { - model = "Atmel at91sam9260ek"; - compatible = "atmel,at91sam9260ek", "atmel,at91sam9260", "atmel,at91sam9"; - - leds { - compatible = "gpio-leds"; - - ds1 { - label = "ds1"; - gpios = <&pioA 9 0>; - linux,default-trigger = "heartbeat"; - }; - - ds5 { - label = "ds5"; - gpios = <&pioA 6 1>; - }; - }; - - aliases { - dbgu = &dbgu; - }; - - - chosen { - stdin = "dbgu"; - stdout = "dbgu"; - }; -}; Index: head/sys/modules/dtb/atmel/Makefile =================================================================== --- head/sys/modules/dtb/atmel/Makefile +++ head/sys/modules/dtb/atmel/Makefile @@ -1,9 +0,0 @@ -# $FreeBSD$ -# All the dts files for the boards we might likely support made by Atmel, -# plus the SAMA5 offerings. -DTS=at91-sama5d3_xplained.dts at91sam9g20ek.dts ethernut5.dts \ - at91-qil_a9260.dts sama5d31ek.dts sama5d33ek.dts sama5d34ek.dts \ - sama5d35ek.dts sama5d36ek.dts tny_a9260.dts tny_a9g20.dts \ - usb_a9260.dts usb_a9g20.dts - -.include Index: head/sys/modules/usb/Makefile =================================================================== --- head/sys/modules/usb/Makefile +++ head/sys/modules/usb/Makefile @@ -44,7 +44,7 @@ # MK_SOURCELESS_UCODE option (see below). SUBDIR = usb -SUBDIR += ${_dwc_otg} ehci ${_musb} ohci uhci xhci ${_uss820dci} ${_at91dci} \ +SUBDIR += ${_dwc_otg} ehci ${_musb} ohci uhci xhci ${_uss820dci} \ ${_atmegadci} ${_avr32dci} ${_rsu} ${_rsufw} ${_saf1761otg} SUBDIR += ${_rum} ${_run} ${_runfw} ${_uath} upgt usie ural ${_zyd} ${_urtw} SUBDIR += atp cfumass uhid uhid_snes ukbd ums udbp ufm uep wmt wsp ugold uled @@ -84,7 +84,6 @@ .endif .if ${MACHINE_CPUARCH} == "arm" -_at91dci= at91dci _atmegadci= atmegadci _dwc_otg= dwc_otg _musb= musb Index: head/sys/modules/usb/at91dci/Makefile =================================================================== --- head/sys/modules/usb/at91dci/Makefile +++ head/sys/modules/usb/at91dci/Makefile @@ -1,42 +0,0 @@ -# -# $FreeBSD$ -# -# Copyright (c) 2008 Hans Petter Selasky. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# - -S= ${SRCTOP}/sys - -.PATH: $S/dev/usb/controller - -KMOD= at91dci -SRCS= bus_if.h device_if.h usb_if.h \ - opt_bus.h opt_usb.h \ - at91dci.c \ - pci_if.h - -.if defined(HAS_ATMELARM) -SRCS+= at91dci_atmelarm.c -.endif - -.include