Index: UPDATING =================================================================== --- UPDATING +++ UPDATING @@ -31,6 +31,19 @@ disable the most expensive debugging functionality run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +20181215: + The XLP config has been removed. We can't support 64-bit atomics in this + kernel because it is running in 32-bit mode. XLP users must transition + to running a 64-bit kernel (XLP64 or XLPN32). + +20181215: + The mips GXEMUL support has been removed from FreeBSD. MALTA* + qemu is + the preferred emulator today and we don't need two different ones. + +20181215: + The old sibyte / swarm / Broadcom BCM1250 support has been + removed from the mips port. + 20181211: Clang, llvm, lld, lldb, compiler-rt and libc++ have been upgraded to 7.0.1. Please see the 20141231 entry below for information about Index: sys/mips/atheros/ar531x/apb.c =================================================================== --- sys/mips/atheros/ar531x/apb.c +++ /dev/null @@ -1,756 +0,0 @@ -/*- - * Copyright (c) 2016, Hiroki Mori - * Copyright (c) 2009, Oleksandr Tymoshenko - * 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 unmodified, 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 "opt_platform.h" -#include "opt_ar531x.h" - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#ifdef INTRNG -#include -#else -#include -#endif - -#ifdef INTRNG -#include "pic_if.h" - -#define PIC_INTR_ISRC(sc, irq) (&(sc)->pic_irqs[(irq)].isrc) -#endif - -#include -#include -#include -#include - -#ifdef AR531X_APB_DEBUG -#define dprintf printf -#else -#define dprintf(x, arg...) -#endif /* AR531X_APB_DEBUG */ - -static int apb_activate_resource(device_t, device_t, int, int, - struct resource *); -static device_t apb_add_child(device_t, u_int, const char *, int); -static struct resource * - apb_alloc_resource(device_t, device_t, int, int *, rman_res_t, - rman_res_t, rman_res_t, u_int); -static int apb_attach(device_t); -static int apb_deactivate_resource(device_t, device_t, int, int, - struct resource *); -static struct resource_list * - apb_get_resource_list(device_t, device_t); -static void apb_hinted_child(device_t, const char *, int); -static int apb_filter(void *); -static int apb_probe(device_t); -static int apb_release_resource(device_t, device_t, int, int, - struct resource *); -#ifndef INTRNG -static int apb_setup_intr(device_t, device_t, struct resource *, int, - driver_filter_t *, driver_intr_t *, void *, void **); -static int apb_teardown_intr(device_t, device_t, struct resource *, - void *); -#endif - -static void -apb_mask_irq(void *source) -{ - unsigned int irq = (unsigned int)source; - uint32_t reg; - - if(ar531x_soc >= AR531X_SOC_AR5315) { - reg = ATH_READ_REG(AR5315_SYSREG_BASE + - AR5315_SYSREG_MISC_INTMASK); - ATH_WRITE_REG(AR5315_SYSREG_BASE - + AR5315_SYSREG_MISC_INTMASK, reg & ~(1 << irq)); - } else { - reg = ATH_READ_REG(AR5312_SYSREG_BASE + - AR5312_SYSREG_MISC_INTMASK); - ATH_WRITE_REG(AR5312_SYSREG_BASE - + AR5312_SYSREG_MISC_INTMASK, reg & ~(1 << irq)); - } -} - -static void -apb_unmask_irq(void *source) -{ - uint32_t reg; - unsigned int irq = (unsigned int)source; - - if(ar531x_soc >= AR531X_SOC_AR5315) { - reg = ATH_READ_REG(AR5315_SYSREG_BASE + - AR5315_SYSREG_MISC_INTMASK); - ATH_WRITE_REG(AR5315_SYSREG_BASE + - AR5315_SYSREG_MISC_INTMASK, reg | (1 << irq)); - } else { - reg = ATH_READ_REG(AR5312_SYSREG_BASE + - AR5312_SYSREG_MISC_INTMASK); - ATH_WRITE_REG(AR5312_SYSREG_BASE + - AR5312_SYSREG_MISC_INTMASK, reg | (1 << irq)); - } -} - -#ifdef INTRNG -static int -apb_pic_register_isrcs(struct apb_softc *sc) -{ - int error; - uint32_t irq; - struct intr_irqsrc *isrc; - const char *name; - - name = device_get_nameunit(sc->apb_dev); - for (irq = 0; irq < APB_NIRQS; irq++) { - sc->pic_irqs[irq].irq = irq; - isrc = PIC_INTR_ISRC(sc, irq); - error = intr_isrc_register(isrc, sc->apb_dev, 0, "%s", name); - if (error != 0) { - /* XXX call intr_isrc_deregister */ - device_printf(sc->apb_dev, "%s failed", __func__); - return (error); - } - } - - return (0); -} - -static inline intptr_t -pic_xref(device_t dev) -{ - return (0); -} -#endif - -static int -apb_probe(device_t dev) -{ -#ifdef INTRNG - device_set_desc(dev, "APB Bus bridge INTRNG"); -#else - device_set_desc(dev, "APB Bus bridge"); -#endif - - return (0); -} - -static int -apb_attach(device_t dev) -{ - struct apb_softc *sc = device_get_softc(dev); -#ifdef INTRNG - intptr_t xref = pic_xref(dev); - int miscirq; -#else - int rid = 0; -#endif - - sc->apb_dev = dev; - - sc->apb_mem_rman.rm_type = RMAN_ARRAY; - sc->apb_mem_rman.rm_descr = "APB memory window"; - - if(ar531x_soc >= AR531X_SOC_AR5315) { - if (rman_init(&sc->apb_mem_rman) != 0 || - rman_manage_region(&sc->apb_mem_rman, - AR5315_APB_BASE, - AR5315_APB_BASE + AR5315_APB_SIZE - 1) != 0) - panic("apb_attach: failed to set up memory rman"); - } else { - if (rman_init(&sc->apb_mem_rman) != 0 || - rman_manage_region(&sc->apb_mem_rman, - AR5312_APB_BASE, - AR5312_APB_BASE + AR5312_APB_SIZE - 1) != 0) - panic("apb_attach: failed to set up memory rman"); - } - - sc->apb_irq_rman.rm_type = RMAN_ARRAY; - sc->apb_irq_rman.rm_descr = "APB IRQ"; - - if (rman_init(&sc->apb_irq_rman) != 0 || - rman_manage_region(&sc->apb_irq_rman, - APB_IRQ_BASE, APB_IRQ_END) != 0) - panic("apb_attach: failed to set up IRQ rman"); - -#ifndef INTRNG - if ((sc->sc_misc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_SHAREABLE | RF_ACTIVE)) == NULL) { - device_printf(dev, "unable to allocate IRQ resource\n"); - return (ENXIO); - } - - if ((bus_setup_intr(dev, sc->sc_misc_irq, INTR_TYPE_MISC, - apb_filter, NULL, sc, &sc->sc_misc_ih))) { - device_printf(dev, - "WARNING: unable to register interrupt handler\n"); - return (ENXIO); - } -#else - /* Register the interrupts */ - if (apb_pic_register_isrcs(sc) != 0) { - device_printf(dev, "could not register PIC ISRCs\n"); - return (ENXIO); - } - - /* - * Now, when everything is initialized, it's right time to - * register interrupt controller to interrupt framefork. - */ - if (intr_pic_register(dev, xref) == NULL) { - device_printf(dev, "could not register PIC\n"); - return (ENXIO); - } - - if(ar531x_soc >= AR531X_SOC_AR5315) { - miscirq = AR5315_CPU_IRQ_MISC; - } else { - miscirq = AR5312_IRQ_MISC; - } - cpu_establish_hardintr("aric", apb_filter, NULL, sc, miscirq, - INTR_TYPE_MISC, NULL); -#endif - - /* mask all misc interrupt */ - if(ar531x_soc >= AR531X_SOC_AR5315) { - ATH_WRITE_REG(AR5315_SYSREG_BASE - + AR5315_SYSREG_MISC_INTMASK, 0); - } else { - ATH_WRITE_REG(AR5312_SYSREG_BASE - + AR5312_SYSREG_MISC_INTMASK, 0); - } - - bus_generic_probe(dev); - bus_enumerate_hinted_children(dev); - bus_generic_attach(dev); - - return (0); -} - -static struct resource * -apb_alloc_resource(device_t bus, device_t child, int type, int *rid, - rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) -{ - struct apb_softc *sc = device_get_softc(bus); - struct apb_ivar *ivar = device_get_ivars(child); - struct resource *rv; - struct resource_list_entry *rle; - struct rman *rm; - int isdefault, needactivate, passthrough; - - isdefault = (RMAN_IS_DEFAULT_RANGE(start, end)); - needactivate = flags & RF_ACTIVE; - /* - * Pass memory requests to nexus device - */ - passthrough = (device_get_parent(child) != bus); - rle = NULL; - - dprintf("%s: entry (%p, %p, %d, %d, %p, %p, %jd, %d)\n", - __func__, bus, child, type, *rid, (void *)(intptr_t)start, - (void *)(intptr_t)end, count, flags); - - if (passthrough) - return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, - rid, start, end, count, flags)); - - /* - * If this is an allocation of the "default" range for a given RID, - * and we know what the resources for this device are (ie. they aren't - * maintained by a child bus), then work out the start/end values. - */ - - if (isdefault) { - rle = resource_list_find(&ivar->resources, type, *rid); - if (rle == NULL) { - return (NULL); - } - - if (rle->res != NULL) { - panic("%s: resource entry is busy", __func__); - } - start = rle->start; - end = rle->end; - count = rle->count; - - dprintf("%s: default resource (%p, %p, %jd)\n", - __func__, (void *)(intptr_t)start, - (void *)(intptr_t)end, count); - } - - switch (type) { - case SYS_RES_IRQ: - rm = &sc->apb_irq_rman; - break; - case SYS_RES_MEMORY: - rm = &sc->apb_mem_rman; - break; - default: - printf("%s: unknown resource type %d\n", __func__, type); - return (0); - } - - rv = rman_reserve_resource(rm, start, end, count, flags, child); - if (rv == NULL) { - printf("%s: could not reserve resource %d\n", __func__, type); - return (0); - } - - rman_set_rid(rv, *rid); - - if (needactivate) { - if (bus_activate_resource(child, type, *rid, rv)) { - printf("%s: could not activate resource\n", __func__); - rman_release_resource(rv); - return (0); - } - } - - return (rv); -} - -static int -apb_activate_resource(device_t bus, device_t child, int type, int rid, - struct resource *r) -{ - - /* XXX: should we mask/unmask IRQ here? */ - return (BUS_ACTIVATE_RESOURCE(device_get_parent(bus), child, - type, rid, r)); -} - -static int -apb_deactivate_resource(device_t bus, device_t child, int type, int rid, - struct resource *r) -{ - - /* XXX: should we mask/unmask IRQ here? */ - return (BUS_DEACTIVATE_RESOURCE(device_get_parent(bus), child, - type, rid, r)); -} - -static int -apb_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 = apb_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 -apb_setup_intr(device_t bus, device_t child, struct resource *ires, - int flags, driver_filter_t *filt, driver_intr_t *handler, - void *arg, void **cookiep) -{ - struct apb_softc *sc = device_get_softc(bus); - int error; - int irq; -#ifndef INTRNG - struct intr_event *event; -#endif - -#ifdef INTRNG - struct intr_irqsrc *isrc; - const char *name; - - if ((rman_get_flags(ires) & RF_SHAREABLE) == 0) - flags |= INTR_EXCL; - - irq = rman_get_start(ires); - isrc = PIC_INTR_ISRC(sc, irq); - if(isrc->isrc_event == 0) { - error = intr_event_create(&isrc->isrc_event, (void *)irq, - 0, irq, apb_mask_irq, apb_unmask_irq, - NULL, NULL, "apb intr%d:", irq); - if(error != 0) - return(error); - } - name = device_get_nameunit(child); - error = intr_event_add_handler(isrc->isrc_event, name, filt, handler, - arg, intr_priority(flags), flags, cookiep); - return(error); -#else - irq = rman_get_start(ires); - - if (irq > APB_IRQ_END) - panic("%s: bad irq %d", __func__, irq); - - event = sc->sc_eventstab[irq]; - if (event == NULL) { - error = intr_event_create(&event, (void *)irq, 0, irq, - apb_mask_irq, apb_unmask_irq, - NULL, NULL, - "apb intr%d:", irq); - - if (error == 0) { - sc->sc_eventstab[irq] = event; - sc->sc_intr_counter[irq] = - mips_intrcnt_create(event->ie_name); - } - else - return (error); - } - - intr_event_add_handler(event, device_get_nameunit(child), filt, - handler, arg, intr_priority(flags), flags, cookiep); - mips_intrcnt_setname(sc->sc_intr_counter[irq], event->ie_fullname); - - apb_unmask_irq((void*)irq); - - return (0); -#endif -} - -#ifndef INTRNG -static int -apb_teardown_intr(device_t dev, device_t child, struct resource *ires, - void *cookie) -{ -#ifdef INTRNG - return (intr_teardown_irq(child, ires, cookie)); -#else - struct apb_softc *sc = device_get_softc(dev); - int irq, result; - - irq = rman_get_start(ires); - if (irq > APB_IRQ_END) - panic("%s: bad irq %d", __func__, irq); - - if (sc->sc_eventstab[irq] == NULL) - panic("Trying to teardown unoccupied IRQ"); - - apb_mask_irq((void*)irq); - - result = intr_event_remove_handler(cookie); - if (!result) - sc->sc_eventstab[irq] = NULL; - - return (result); -#endif -} - - -static int -apb_filter(void *arg) -{ - struct apb_softc *sc = arg; - struct intr_event *event; - uint32_t reg, irq; - - if(ar531x_soc >= AR531X_SOC_AR5315) - reg = ATH_READ_REG(AR5315_SYSREG_BASE + - AR5315_SYSREG_MISC_INTSTAT); - else - reg = ATH_READ_REG(AR5312_SYSREG_BASE + - AR5312_SYSREG_MISC_INTSTAT); - - for (irq = 0; irq < APB_NIRQS; irq++) { - if (reg & (1 << irq)) { - - if(ar531x_soc >= AR531X_SOC_AR5315) { - ATH_WRITE_REG(AR5315_SYSREG_BASE + - AR5315_SYSREG_MISC_INTSTAT, - reg & ~(1 << irq)); - } else { - ATH_WRITE_REG(AR5312_SYSREG_BASE + - AR5312_SYSREG_MISC_INTSTAT, - reg & ~(1 << irq)); - } - - event = sc->sc_eventstab[irq]; - if (!event || CK_SLIST_EMPTY(&event->ie_handlers)) { - if(irq == 1 && ar531x_soc < AR531X_SOC_AR5315) { - ATH_READ_REG(AR5312_SYSREG_BASE + - AR5312_SYSREG_AHBPERR); - ATH_READ_REG(AR5312_SYSREG_BASE + - AR5312_SYSREG_AHBDMAE); - } - /* Ignore non handle interrupts */ - if (irq != 0 && irq != 6) - printf("Stray APB IRQ %d\n", irq); - - continue; - } - - intr_event_handle(event, PCPU_GET(curthread)->td_intr_frame); - mips_intrcnt_inc(sc->sc_intr_counter[irq]); - } - } - - return (FILTER_HANDLED); -} -#else -static int -apb_filter(void *arg) -{ - struct apb_softc *sc = arg; - struct thread *td; - uint32_t i, intr; - - td = curthread; - /* Workaround: do not inflate intr nesting level */ - td->td_intr_nesting_level--; - - if(ar531x_soc >= AR531X_SOC_AR5315) - intr = ATH_READ_REG(AR5315_SYSREG_BASE + - AR5315_SYSREG_MISC_INTSTAT); - else - intr = ATH_READ_REG(AR5312_SYSREG_BASE + - AR5312_SYSREG_MISC_INTSTAT); - - while ((i = fls(intr)) != 0) { - i--; - intr &= ~(1u << i); - - if(i == 1 && ar531x_soc < AR531X_SOC_AR5315) { - ATH_READ_REG(AR5312_SYSREG_BASE + - AR5312_SYSREG_AHBPERR); - ATH_READ_REG(AR5312_SYSREG_BASE + - AR5312_SYSREG_AHBDMAE); - } - - if (intr_isrc_dispatch(PIC_INTR_ISRC(sc, i), - curthread->td_intr_frame) != 0) { - device_printf(sc->apb_dev, - "Stray interrupt %u detected\n", i); - apb_mask_irq((void*)i); - continue; - } - } - - KASSERT(i == 0, ("all interrupts handled")); - - td->td_intr_nesting_level++; - - return (FILTER_HANDLED); - -} - -#endif - -static void -apb_hinted_child(device_t bus, const char *dname, int dunit) -{ - device_t child; - long maddr; - int msize; - int irq; - int result; - int mem_hints_count; - - child = BUS_ADD_CHILD(bus, 0, dname, dunit); - - /* - * Set hard-wired resources for hinted child using - * specific RIDs. - */ - mem_hints_count = 0; - if (resource_long_value(dname, dunit, "maddr", &maddr) == 0) - mem_hints_count++; - if (resource_int_value(dname, dunit, "msize", &msize) == 0) - mem_hints_count++; - - /* check if all info for mem resource has been provided */ - if ((mem_hints_count > 0) && (mem_hints_count < 2)) { - printf("Either maddr or msize hint is missing for %s%d\n", - dname, dunit); - } else if (mem_hints_count) { - result = bus_set_resource(child, SYS_RES_MEMORY, 0, - maddr, msize); - if (result != 0) - device_printf(bus, - "warning: bus_set_resource() failed\n"); - } - - if (resource_int_value(dname, dunit, "irq", &irq) == 0) { - result = bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1); - if (result != 0) - device_printf(bus, - "warning: bus_set_resource() failed\n"); - } -} - -static device_t -apb_add_child(device_t bus, u_int order, const char *name, int unit) -{ - device_t child; - struct apb_ivar *ivar; - - ivar = malloc(sizeof(struct apb_ivar), M_DEVBUF, M_WAITOK | M_ZERO); - if (ivar == NULL) { - printf("Failed to allocate ivar\n"); - return (0); - } - resource_list_init(&ivar->resources); - - child = device_add_child_ordered(bus, order, name, unit); - if (child == NULL) { - printf("Can't add child %s%d ordered\n", name, unit); - return (0); - } - - device_set_ivars(child, ivar); - - return (child); -} - -/* - * Helper routine for bus_generic_rl_get_resource/bus_generic_rl_set_resource - * Provides pointer to resource_list for these routines - */ -static struct resource_list * -apb_get_resource_list(device_t dev, device_t child) -{ - struct apb_ivar *ivar; - - ivar = device_get_ivars(child); - return (&(ivar->resources)); -} - -#ifdef INTRNG -static void -apb_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc) -{ - u_int irq; - - irq = ((struct apb_pic_irqsrc *)isrc)->irq; - apb_unmask_irq((void*)irq); -} - -static void -apb_pic_disable_intr(device_t dev, struct intr_irqsrc *isrc) -{ - u_int irq; - - irq = ((struct apb_pic_irqsrc *)isrc)->irq; - apb_mask_irq((void*)irq); -} - -static void -apb_pic_pre_ithread(device_t dev, struct intr_irqsrc *isrc) -{ - apb_pic_disable_intr(dev, isrc); -} - -static void -apb_pic_post_ithread(device_t dev, struct intr_irqsrc *isrc) -{ - apb_pic_enable_intr(dev, isrc); -} - -static void -apb_pic_post_filter(device_t dev, struct intr_irqsrc *isrc) -{ - uint32_t reg, irq; - - irq = ((struct apb_pic_irqsrc *)isrc)->irq; - if(ar531x_soc >= AR531X_SOC_AR5315) { - reg = ATH_READ_REG(AR5315_SYSREG_BASE + - AR5315_SYSREG_MISC_INTSTAT); - ATH_WRITE_REG(AR5315_SYSREG_BASE + AR5315_SYSREG_MISC_INTSTAT, - reg & ~(1 << irq)); - } else { - reg = ATH_READ_REG(AR5312_SYSREG_BASE + - AR5312_SYSREG_MISC_INTSTAT); - ATH_WRITE_REG(AR5312_SYSREG_BASE + AR5312_SYSREG_MISC_INTSTAT, - reg & ~(1 << irq)); - } -} - -static int -apb_pic_map_intr(device_t dev, struct intr_map_data *data, - struct intr_irqsrc **isrcp) -{ - return (ENOTSUP); -} - -#endif - -static device_method_t apb_methods[] = { - DEVMETHOD(bus_activate_resource, apb_activate_resource), - DEVMETHOD(bus_add_child, apb_add_child), - DEVMETHOD(bus_alloc_resource, apb_alloc_resource), - DEVMETHOD(bus_deactivate_resource, apb_deactivate_resource), - DEVMETHOD(bus_get_resource_list, apb_get_resource_list), - DEVMETHOD(bus_hinted_child, apb_hinted_child), - DEVMETHOD(bus_release_resource, apb_release_resource), - DEVMETHOD(device_attach, apb_attach), - DEVMETHOD(device_probe, apb_probe), - DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), - DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), -#ifdef INTRNG - DEVMETHOD(pic_disable_intr, apb_pic_disable_intr), - DEVMETHOD(pic_enable_intr, apb_pic_enable_intr), - DEVMETHOD(pic_map_intr, apb_pic_map_intr), - DEVMETHOD(pic_post_filter, apb_pic_post_filter), - DEVMETHOD(pic_post_ithread, apb_pic_post_ithread), - DEVMETHOD(pic_pre_ithread, apb_pic_pre_ithread), - -// DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), -#else - DEVMETHOD(bus_teardown_intr, apb_teardown_intr), -#endif - DEVMETHOD(bus_setup_intr, apb_setup_intr), - - DEVMETHOD_END -}; - -static driver_t apb_driver = { - "apb", - apb_methods, - sizeof(struct apb_softc), -}; -static devclass_t apb_devclass; - -EARLY_DRIVER_MODULE(apb, nexus, apb_driver, apb_devclass, 0, 0, - BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE); Index: sys/mips/atheros/ar531x/apbvar.h =================================================================== --- sys/mips/atheros/ar531x/apbvar.h +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * Copyright (c) 2009, Oleksandr Tymoshenko - * 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 unmodified, 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 _APBVAR_H_ -#define _APBVAR_H_ - -#define APB_IRQ_BASE 0 -#define APB_IRQ_END 31 -#define APB_NIRQS 32 - -struct apb_pic_irqsrc { - struct intr_irqsrc isrc; - u_int irq; -}; - -struct apb_softc { - device_t apb_dev; - struct rman apb_irq_rman; - struct rman apb_mem_rman; - /* IRQ events structs for child devices */ - struct intr_event *sc_eventstab[APB_NIRQS]; -#ifndef INTRNG - mips_intrcnt_t sc_intr_counter[APB_NIRQS]; -#endif - /* Resources and cookies for MIPS CPU INTs */ - struct resource *sc_misc_irq; - void *sc_misc_ih; -#ifdef INTRNG - struct apb_pic_irqsrc pic_irqs[APB_NIRQS]; -#endif -}; - -struct apb_ivar { - struct resource_list resources; -}; - -#endif /* _APBVAR_H_ */ Index: sys/mips/atheros/ar531x/ar5312_chip.h =================================================================== --- sys/mips/atheros/ar531x/ar5312_chip.h +++ /dev/null @@ -1,34 +0,0 @@ -/*- - * Copyright (c) 2010 Adrian Chadd - * 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 __AR5312_CHIP_H__ -#define __AR5312_CHIP_H__ - -extern struct ar5315_cpu_def ar5312_chip_def; - -#endif Index: sys/mips/atheros/ar531x/ar5312_chip.c =================================================================== --- sys/mips/atheros/ar531x/ar5312_chip.c +++ /dev/null @@ -1,209 +0,0 @@ -/*- - * Copyright (c) 2016 Hiroki Mori - * Copyright (c) 2010 Adrian Chadd - * 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 "opt_ddb.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -static void -ar5312_chip_detect_mem_size(void) -{ - uint32_t memsize; - uint32_t memcfg, bank0, bank1; - - /* - * Determine the memory size as established by system - * firmware. - * - * NB: we allow compile time override - */ - memcfg = ATH_READ_REG(AR5312_SDRAMCTL_BASE + AR5312_SDRAMCTL_MEM_CFG1); - bank0 = __SHIFTOUT(memcfg, AR5312_MEM_CFG1_BANK0); - bank1 = __SHIFTOUT(memcfg, AR5312_MEM_CFG1_BANK1); - - memsize = (bank0 ? (1 << (bank0 + 1)) : 0) + - (bank1 ? (1 << (bank1 + 1)) : 0); - memsize <<= 20; - - realmem = memsize; -} - -static void -ar5312_chip_detect_sys_frequency(void) -{ - uint32_t predivisor; - uint32_t multiplier; - - - const uint32_t clockctl = ATH_READ_REG(AR5312_SYSREG_BASE + AR5312_SYSREG_CLOCKCTL); - if(ar531x_soc == AR531X_SOC_AR5313) { - predivisor = __SHIFTOUT(clockctl, AR2313_CLOCKCTL_PREDIVIDE); - multiplier = __SHIFTOUT(clockctl, AR2313_CLOCKCTL_MULTIPLIER); - } else { - predivisor = __SHIFTOUT(clockctl, AR5312_CLOCKCTL_PREDIVIDE); - multiplier = __SHIFTOUT(clockctl, AR5312_CLOCKCTL_MULTIPLIER); - } - - const uint32_t divisor = (0x5421 >> (predivisor * 4)) & 15; - - const uint32_t cpufreq = (40000000 / divisor) * multiplier; - - u_ar531x_cpu_freq = cpufreq; - u_ar531x_ahb_freq = cpufreq / 4; - u_ar531x_ddr_freq = 0; -} - -/* - * This does not lock the CPU whilst doing the work! - */ -static void -ar5312_chip_device_reset(void) -{ - ATH_WRITE_REG(AR5312_SYSREG_BASE + AR5312_SYSREG_RESETCTL, - AR5312_RESET_SYSTEM); -} - -static void -ar5312_chip_device_start(void) -{ - uint32_t cfg0, cfg1; - uint32_t bank0, bank1; - uint32_t size0, size1; - - cfg0 = ATH_READ_REG(AR5312_SDRAMCTL_BASE + AR5312_SDRAMCTL_MEM_CFG0); - cfg1 = ATH_READ_REG(AR5312_SDRAMCTL_BASE + AR5312_SDRAMCTL_MEM_CFG1); - - bank0 = __SHIFTOUT(cfg1, AR5312_MEM_CFG1_BANK0); - bank1 = __SHIFTOUT(cfg1, AR5312_MEM_CFG1_BANK1); - - size0 = bank0 ? (1 << (bank0 + 1)) : 0; - size1 = bank1 ? (1 << (bank1 + 1)) : 0; - - size0 <<= 20; - size1 <<= 20; - - printf("SDRMCTL %x %x %x %x\n", cfg0, cfg1, size0, size1); - - ATH_READ_REG(AR5312_SYSREG_BASE + AR5312_SYSREG_AHBPERR); - ATH_READ_REG(AR5312_SYSREG_BASE + AR5312_SYSREG_AHBDMAE); -// ATH_WRITE_REG(AR5312_SYSREG_BASE + AR5312_SYSREG_WDOG_CTL, 0); - ATH_WRITE_REG(AR5312_SYSREG_BASE + AR5312_SYSREG_ENABLE, 0); - - ATH_WRITE_REG(AR5312_SYSREG_BASE+AR5312_SYSREG_ENABLE, - ATH_READ_REG(AR5312_SYSREG_BASE+AR5312_SYSREG_ENABLE) | - AR5312_ENABLE_ENET0 | AR5312_ENABLE_ENET1); - -} - -static int -ar5312_chip_device_stopped(uint32_t mask) -{ - uint32_t reg; - - reg = ATH_READ_REG(AR5312_SYSREG_BASE + AR5312_SYSREG_RESETCTL); - return ((reg & mask) == mask); -} - -static void -ar5312_chip_set_mii_speed(uint32_t unit, uint32_t speed) -{ -} - -/* Speed is either 10, 100 or 1000 */ -static void -ar5312_chip_set_pll_ge(int unit, int speed) -{ -} - -static void -ar5312_chip_ddr_flush_ge(int unit) -{ -} - -static void -ar5312_chip_soc_init(void) -{ - - u_ar531x_uart_addr = MIPS_PHYS_TO_KSEG1(AR5312_UART0_BASE); - - u_ar531x_gpio_di = AR5312_GPIO_DI; - u_ar531x_gpio_do = AR5312_GPIO_DO; - u_ar531x_gpio_cr = AR5312_GPIO_CR; - u_ar531x_gpio_pins = AR5312_GPIO_PINS; - - u_ar531x_wdog_ctl = AR5312_SYSREG_WDOG_CTL; - u_ar531x_wdog_timer = AR5312_SYSREG_WDOG_TIMER; - -} - -static uint32_t -ar5312_chip_get_eth_pll(unsigned int mac, int speed) -{ - return 0; -} - -struct ar5315_cpu_def ar5312_chip_def = { - &ar5312_chip_detect_mem_size, - &ar5312_chip_detect_sys_frequency, - &ar5312_chip_device_reset, - &ar5312_chip_device_start, - &ar5312_chip_device_stopped, - &ar5312_chip_set_pll_ge, - &ar5312_chip_set_mii_speed, - &ar5312_chip_ddr_flush_ge, - &ar5312_chip_get_eth_pll, - &ar5312_chip_soc_init, -}; Index: sys/mips/atheros/ar531x/ar5312reg.h =================================================================== --- sys/mips/atheros/ar531x/ar5312reg.h +++ /dev/null @@ -1,239 +0,0 @@ -/* $Id: ar5312reg.h,v 1.4 2011/07/07 05:06:44 matt Exp $ */ -/* - * Copyright (c) 2006 Urbana-Champaign Independent Media Center. - * Copyright (c) 2006 Garrett D'Amore. - * All rights reserved. - * - * This code was written by Garrett D'Amore for the Champaign-Urbana - * Community Wireless Network Project. - * - * 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 acknowledgements: - * This product includes software developed by the Urbana-Champaign - * Independent Media Center. - * This product includes software developed by Garrett D'Amore. - * 4. Urbana-Champaign Independent Media Center's name and Garrett - * D'Amore's name may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE URBANA-CHAMPAIGN INDEPENDENT - * MEDIA CENTER AND GARRETT D'AMORE ``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 URBANA-CHAMPAIGN INDEPENDENT - * MEDIA CENTER OR GARRETT D'AMORE 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 _MIPS_ATHEROS_AR5312REG_H_ -#define _MIPS_ATHEROS_AR5312REG_H_ - -#define AR5312_MEM0_BASE 0x00000000 /* sdram */ -#define AR5312_MEM1_BASE 0x08000000 /* sdram/flash */ -#define AR5312_MEM3_BASE 0x10000000 /* flash */ -#define AR5312_WLAN0_BASE 0x18000000 -#define AR5312_ENET0_BASE 0x18100000 -#define AR5312_ENET1_BASE 0x18200000 -#define AR5312_SDRAMCTL_BASE 0x18300000 -#define AR5312_FLASHCTL_BASE 0x18400000 -#define AR5312_WLAN1_BASE 0x18500000 -#define AR5312_UART0_BASE 0x1C000000 /* high speed */ -#define AR5312_UART1_BASE 0x1C001000 -#define AR5312_GPIO_BASE 0x1C002000 -#define AR5312_SYSREG_BASE 0x1C003000 -#define AR5312_UARTDMA_BASE 0x1C004000 -#define AR5312_FLASH_BASE 0x1E000000 -#define AR5312_FLASH_END 0x20000000 /* possibly aliased */ - -/* - * FLASHCTL registers -- offset relative to AR531X_FLASHCTL_BASE - */ -#define AR5312_FLASHCTL_0 0x00 -#define AR5312_FLASHCTL_1 0x04 -#define AR5312_FLASHCTL_2 0x08 - -#define AR5312_FLASHCTL_IDCY __BITS(0,3) /* idle cycle turn */ -#define AR5312_FLASHCTL_WST1 __BITS(5,9) /* wait state 1 */ -#define AR5312_FLASHCTL_RBLE __BIT(10) /* rd byte enable */ -#define AR5312_FLASHCTL_WST2 __BITS(11,15) /* wait state 1 */ -#define AR5312_FLASHCTL_AC __BITS(16,18) /* addr chk */ -#define AR5312_FLASHCTL_AC_128K 0 -#define AR5312_FLASHCTL_AC_256K 1 -#define AR5312_FLASHCTL_AC_512K 2 -#define AR5312_FLASHCTL_AC_1M 3 -#define AR5312_FLASHCTL_AC_2M 4 -#define AR5312_FLASHCTL_AC_4M 5 -#define AR5312_FLASHCTL_AC_8M 6 -#define AR5312_FLASHCTL_AC_16M 7 -#define AR5312_FLASHCTL_E __BIT(19) /* enable */ -#define AR5312_FLASHCTL_BUSERR __BIT(24) /* buserr */ -#define AR5312_FLASHCTL_WPERR __BIT(25) /* wperr */ -#define AR5312_FLASHCTL_WP __BIT(26) /* wp */ -#define AR5312_FLASHCTL_BM __BIT(27) /* bm */ -#define AR5312_FLASHCTL_MW __BITS(28,29) /* mem width */ -#define AR5312_FLASHCTL_AT __BITS(31,30) /* access type */ - -/* - * GPIO registers -- offset relative to AR531X_GPIO_BASE - */ -#define AR5312_GPIO_DO 0 -#define AR5312_GPIO_DI 4 -#define AR5312_GPIO_CR 8 - -#define AR5312_GPIO_PINS 8 - -/* - * SYSREG registers -- offset relative to AR531X_SYSREG_BASE - */ -#define AR5312_SYSREG_TIMER 0x0000 -#define AR5312_SYSREG_TIMER_RELOAD 0x0004 -#define AR5312_SYSREG_WDOG_CTL 0x0008 -#define AR5312_SYSREG_WDOG_TIMER 0x000c -#define AR5312_SYSREG_MISC_INTSTAT 0x0010 -#define AR5312_SYSREG_MISC_INTMASK 0x0014 -#define AR5312_SYSREG_INTSTAT 0x0018 -#define AR5312_SYSREG_RESETCTL 0x0020 -#define AR5312_SYSREG_CLOCKCTL 0x0064 -#define AR5312_SYSREG_SCRATCH 0x006c -#define AR5312_SYSREG_AHBPERR 0x0070 -#define AR5312_SYSREG_PROC 0x0074 -#define AR5312_SYSREG_AHBDMAE 0x0078 -#define AR5312_SYSREG_ENABLE 0x0080 -#define AR5312_SYSREG_REVISION 0x0090 - -/* WDOG_CTL watchdog control bits */ -#define AR5312_WDOG_CTL_IGNORE 0x0000 -#define AR5312_WDOG_CTL_NMI 0x0001 -#define AR5312_WDOG_CTL_RESET 0x0002 - -/* Resets */ -#define AR5312_RESET_SYSTEM __BIT(0) -#define AR5312_RESET_CPU __BIT(1) -#define AR5312_RESET_WLAN0 __BIT(2) /* mac & bb */ -#define AR5312_RESET_PHY0 __BIT(3) /* enet phy */ -#define AR5312_RESET_PHY1 __BIT(4) /* enet phy */ -#define AR5312_RESET_ENET0 __BIT(5) /* mac */ -#define AR5312_RESET_ENET1 __BIT(6) /* mac */ -#define AR5312_RESET_UART0 __BIT(8) /* mac */ -#define AR5312_RESET_WLAN1 __BIT(9) /* mac & bb */ -#define AR5312_RESET_APB __BIT(10) /* bridge */ -#define AR5312_RESET_WARM_CPU __BIT(16) -#define AR5312_RESET_WARM_WLAN0_MAC __BIT(17) -#define AR5312_RESET_WARM_WLAN0_BB __BIT(18) -#define AR5312_RESET_NMI __BIT(20) -#define AR5312_RESET_WARM_WLAN1_MAC __BIT(21) -#define AR5312_RESET_WARM_WLAN1_BB __BIT(22) -#define AR5312_RESET_LOCAL_BUS __BIT(23) -#define AR5312_RESET_WDOG __BIT(24) - -/* AR5312/2312 clockctl bits */ -#define AR5312_CLOCKCTL_PREDIVIDE __BITS(4,5) -#define AR5312_CLOCKCTL_MULTIPLIER __BITS(8,12) -#define AR5312_CLOCKCTL_DOUBLER __BIT(16) - -/* AR2313 clockctl */ -#define AR2313_CLOCKCTL_PREDIVIDE __BITS(12,13) -#define AR2313_CLOCKCTL_MULTIPLIER __BITS(16,20) - -/* Enables */ -#define AR5312_ENABLE_WLAN0 __BIT(0) -#define AR5312_ENABLE_ENET0 __BIT(1) -#define AR5312_ENABLE_ENET1 __BIT(2) -#define AR5312_ENABLE_WLAN1 __BITS(7,8) /* both DMA and PIO */ - -/* Revision ids */ -#define AR5312_REVISION_WMAC_MAJOR(x) (((x) >> 12) & 0xf) -#define AR5312_REVISION_WMAC_MINOR(x) (((x) >> 8) & 0xf) -#define AR5312_REVISION_WMAC(x) (((x) >> 8) & 0xff) -#define AR5312_REVISION_MAJOR(x) (((x) >> 4) & 0xf) -#define AR5312_REVISION_MINOR(x) (((x) >> 0) & 0xf) - -#define AR5312_REVISION_MAJ_AR5311 0x1 -#define AR5312_REVISION_MAJ_AR5312 0x4 -#define AR5312_REVISION_MAJ_AR2313 0x5 -#define AR5312_REVISION_MAJ_AR5315 0xB - -/* - * SDRAMCTL registers -- offset relative to SDRAMCTL - */ -#define AR5312_SDRAMCTL_MEM_CFG0 0x0000 -#define AR5312_SDRAMCTL_MEM_CFG1 0x0004 - -/* memory config 1 bits */ -#define AR5312_MEM_CFG1_BANK0 __BITS(8,10) -#define AR5312_MEM_CFG1_BANK1 __BITS(12,15) - -/* helper macro for accessing system registers without bus space */ -#define REGVAL(x) *((volatile uint32_t *)(MIPS_PHYS_TO_KSEG1((x)))) -#define GETSYSREG(x) REGVAL((x) + AR5312_SYSREG_BASE) -#define PUTSYSREG(x,v) (REGVAL((x) + AR5312_SYSREG_BASE)) = (v) -#define GETSDRAMREG(x) REGVAL((x) + AR5312_SDRAMCTL_BASE) -#define PUTSDRAMREG(x,v) (REGVAL((x) + AR5312_SDRAMCTL_BASE)) = (v) - -/* - * Interrupts. - */ -#define AR5312_IRQ_WLAN0 0 -#define AR5312_IRQ_ENET0 1 -#define AR5312_IRQ_ENET1 2 -#define AR5312_IRQ_WLAN1 3 -#define AR5312_IRQ_MISC 4 - -#define AR5312_MISC_IRQ_TIMER 1 -#define AR5312_MISC_IRQ_AHBPERR 2 -#define AR5312_MISC_IRQ_AHBDMAE 3 -#define AR5312_MISC_IRQ_GPIO 4 -#define AR5312_MISC_IRQ_UART0 5 -#define AR5312_MISC_IRQ_UART0_DMA 6 -#define AR5312_MISC_IRQ_WDOG 7 - -/* - * Board data. This is located in flash somewhere, ar531x_board_info - * locates it. - */ -#include /* XXX really doesn't belong in hal */ - -/* XXX write-around for now */ -#define AR5312_BOARD_MAGIC AR531X_BD_MAGIC - -/* config bits */ -#define AR5312_BOARD_CONFIG_ENET0 BD_ENET0 -#define AR5312_BOARD_CONFIG_ENET1 BD_ENET1 -#define AR5312_BOARD_CONFIG_UART1 BD_UART1 -#define AR5312_BOARD_CONFIG_UART0 BD_UART0 -#define AR5312_BOARD_CONFIG_RSTFACTORY BD_RSTFACTORY -#define AR5312_BOARD_CONFIG_SYSLED BD_SYSLED -#define AR5312_BOARD_CONFIG_EXTUARTCLK BD_EXTUARTCLK -#define AR5312_BOARD_CONFIG_CPUFREQ BD_CPUFREQ -#define AR5312_BOARD_CONFIG_SYSFREQ BD_SYSFREQ -#define AR5312_BOARD_CONFIG_WLAN0 BD_WLAN0 -#define AR5312_BOARD_CONFIG_MEMCAP BD_MEMCAP -#define AR5312_BOARD_CONFIG_DISWDOG BD_DISWATCHDOG -#define AR5312_BOARD_CONFIG_WLAN1 BD_WLAN1 -#define AR5312_BOARD_CONFIG_AR2312 BD_ISCASPER -#define AR5312_BOARD_CONFIG_WLAN0_2G BD_WLAN0_2G_EN -#define AR5312_BOARD_CONFIG_WLAN0_5G BD_WLAN0_5G_EN -#define AR5312_BOARD_CONFIG_WLAN1_2G BD_WLAN1_2G_EN -#define AR5312_BOARD_CONFIG_WLAN1_5G BD_WLAN1_5G_EN - -#define AR5312_APB_BASE AR5312_UART0_BASE -#define AR5312_APB_SIZE 0x02000000 - -#endif /* _MIPS_ATHEROS_AR531XREG_H_ */ Index: sys/mips/atheros/ar531x/ar5315_chip.h =================================================================== --- sys/mips/atheros/ar531x/ar5315_chip.h +++ /dev/null @@ -1,34 +0,0 @@ -/*- - * Copyright (c) 2010 Adrian Chadd - * 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 __AR5315_CHIP_H__ -#define __AR5315_CHIP_H__ - -extern struct ar5315_cpu_def ar5315_chip_def; - -#endif Index: sys/mips/atheros/ar531x/ar5315_chip.c =================================================================== --- sys/mips/atheros/ar531x/ar5315_chip.c +++ /dev/null @@ -1,256 +0,0 @@ -/*- - * Copyright (c) 2010 Adrian Chadd - * All rights reserved. - * Copyright (c) 2016, Hiroki Mori - * - * 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 "opt_ddb.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* XXX these shouldn't be in here - this file is a per-chip file */ -/* XXX these should be in the top-level ar5315 type, not ar5315 -chip */ -uint32_t u_ar531x_cpu_freq; -uint32_t u_ar531x_ahb_freq; -uint32_t u_ar531x_ddr_freq; - -uint32_t u_ar531x_uart_addr; - -uint32_t u_ar531x_gpio_di; -uint32_t u_ar531x_gpio_do; -uint32_t u_ar531x_gpio_cr; -uint32_t u_ar531x_gpio_pins; - -uint32_t u_ar531x_wdog_ctl; -uint32_t u_ar531x_wdog_timer; - -static void -ar5315_chip_detect_mem_size(void) -{ - uint32_t memsize = 0; - uint32_t memcfg, cw, rw, dw; - - /* - * Determine the memory size. We query the board info. - */ - memcfg = ATH_READ_REG(AR5315_SDRAMCTL_BASE + AR5315_SDRAMCTL_MEM_CFG); - cw = __SHIFTOUT(memcfg, AR5315_MEM_CFG_COL_WIDTH); - cw += 1; - rw = __SHIFTOUT(memcfg, AR5315_MEM_CFG_ROW_WIDTH); - rw += 1; - - /* XXX: according to redboot, this could be wrong if DDR SDRAM */ - dw = __SHIFTOUT(memcfg, AR5315_MEM_CFG_DATA_WIDTH); - dw += 1; - dw *= 8; /* bits */ - - /* not too sure about this math, but it _seems_ to add up */ - memsize = (1 << cw) * (1 << rw) * dw; -#if 0 - printf("SDRAM_MEM_CFG =%x, cw=%d rw=%d dw=%d xmemsize=%d\n", memcfg, - cw, rw, dw, memsize); -#endif - realmem = memsize; -} - -static void -ar5315_chip_detect_sys_frequency(void) -{ - uint32_t freq_ref, freq_pll; - static const uint8_t pll_divide_table[] = { - 2, 3, 4, 6, 3, - /* - * these entries are bogus, but it avoids a possible - * bad table dereference - */ - 1, 1, 1 - }; - static const uint8_t pre_divide_table[] = { - 1, 2, 4, 5 - }; - - const uint32_t pllc = ATH_READ_REG(AR5315_SYSREG_BASE + - AR5315_SYSREG_PLLC_CTL); - - const uint32_t refdiv = pre_divide_table[AR5315_PLLC_REF_DIV(pllc)]; - const uint32_t fbdiv = AR5315_PLLC_FB_DIV(pllc); - const uint32_t div2 = (AR5315_PLLC_DIV_2(pllc) + 1) * 2; /* results in 2 or 4 */ - - freq_ref = 40000000; - - /* 40MHz reference clk, reference and feedback dividers */ - freq_pll = (freq_ref / refdiv) * div2 * fbdiv; - - const uint32_t pllout[4] = { - /* CLKM select */ - [0] = freq_pll / pll_divide_table[AR5315_PLLC_CLKM(pllc)], - [1] = freq_pll / pll_divide_table[AR5315_PLLC_CLKM(pllc)], - - /* CLKC select */ - [2] = freq_pll / pll_divide_table[AR5315_PLLC_CLKC(pllc)], - - /* ref_clk select */ - [3] = freq_ref, /* use original reference clock */ - }; - - const uint32_t amba_clkctl = ATH_READ_REG(AR5315_SYSREG_BASE + - AR5315_SYSREG_AMBACLK); - uint32_t ambadiv = AR5315_CLOCKCTL_DIV(amba_clkctl); - ambadiv = ambadiv ? (ambadiv * 2) : 1; - u_ar531x_ahb_freq = pllout[AR5315_CLOCKCTL_SELECT(amba_clkctl)] / ambadiv; - - const uint32_t cpu_clkctl = ATH_READ_REG(AR5315_SYSREG_BASE + - AR5315_SYSREG_CPUCLK); - uint32_t cpudiv = AR5315_CLOCKCTL_DIV(cpu_clkctl); - cpudiv = cpudiv ? (cpudiv * 2) : 1; - u_ar531x_cpu_freq = pllout[AR5315_CLOCKCTL_SELECT(cpu_clkctl)] / cpudiv; - - u_ar531x_ddr_freq = 0; -} - -/* - * This does not lock the CPU whilst doing the work! - */ -static void -ar5315_chip_device_reset(void) -{ - ATH_WRITE_REG(AR5315_SYSREG_BASE + AR5315_SYSREG_COLDRESET, - AR5315_COLD_AHB | AR5315_COLD_APB | AR5315_COLD_CPU); -} - -static void -ar5315_chip_device_start(void) -{ - ATH_WRITE_REG(AR5315_SYSREG_BASE+AR5315_SYSREG_AHB_ERR0, - AR5315_AHB_ERROR_DET); - ATH_READ_REG(AR5315_SYSREG_BASE+AR5315_SYSREG_AHB_ERR1); - ATH_WRITE_REG(AR5315_SYSREG_BASE+AR5315_SYSREG_WDOG_CTL, - AR5315_WDOG_CTL_IGNORE); - - // set Ethernet AHB master arbitration control - // Maybe RedBoot was enabled. But to make sure. - ATH_WRITE_REG(AR5315_SYSREG_BASE+AR5315_SYSREG_AHB_ARB_CTL, - ATH_READ_REG(AR5315_SYSREG_BASE+AR5315_SYSREG_AHB_ARB_CTL) | - AR5315_ARB_ENET); - - // set Ethernet controller byteswap control -/* - ATH_WRITE_REG(AR5315_SYSREG_BASE+AR5315_SYSREG_ENDIAN, - ATH_READ_REG(AR5315_SYSREG_BASE+AR5315_SYSREG_ENDIAN) | - AR5315_ENDIAN_ENET); -*/ - /* Disable interrupts for all gpio pins. */ - ATH_WRITE_REG(AR5315_SYSREG_BASE+AR5315_SYSREG_GPIO_INT, 0); - - printf("AHB Master Arbitration Control %08x\n", - ATH_READ_REG(AR5315_SYSREG_BASE+AR5315_SYSREG_AHB_ARB_CTL)); - printf("Byteswap Control %08x\n", - ATH_READ_REG(AR5315_SYSREG_BASE+AR5315_SYSREG_ENDIAN)); -} - -static int -ar5315_chip_device_stopped(uint32_t mask) -{ - uint32_t reg; - - reg = ATH_READ_REG(AR5315_SYSREG_BASE + AR5315_SYSREG_COLDRESET); - return ((reg & mask) == mask); -} - -static void -ar5315_chip_set_mii_speed(uint32_t unit, uint32_t speed) -{ -} - -/* Speed is either 10, 100 or 1000 */ -static void -ar5315_chip_set_pll_ge(int unit, int speed) -{ -} - -static void -ar5315_chip_ddr_flush_ge(int unit) -{ -} - -static void -ar5315_chip_soc_init(void) -{ - u_ar531x_uart_addr = MIPS_PHYS_TO_KSEG1(AR5315_UART_BASE); - - u_ar531x_gpio_di = AR5315_SYSREG_GPIO_DI; - u_ar531x_gpio_do = AR5315_SYSREG_GPIO_DO; - u_ar531x_gpio_cr = AR5315_SYSREG_GPIO_CR; - u_ar531x_gpio_pins = AR5315_GPIO_PINS; - - u_ar531x_wdog_ctl = AR5315_SYSREG_WDOG_CTL; - u_ar531x_wdog_timer = AR5315_SYSREG_WDOG_TIMER; -} - -static uint32_t -ar5315_chip_get_eth_pll(unsigned int mac, int speed) -{ - return 0; -} - -struct ar5315_cpu_def ar5315_chip_def = { - &ar5315_chip_detect_mem_size, - &ar5315_chip_detect_sys_frequency, - &ar5315_chip_device_reset, - &ar5315_chip_device_start, - &ar5315_chip_device_stopped, - &ar5315_chip_set_pll_ge, - &ar5315_chip_set_mii_speed, - &ar5315_chip_ddr_flush_ge, - &ar5315_chip_get_eth_pll, - &ar5315_chip_soc_init, -}; Index: sys/mips/atheros/ar531x/ar5315_cpudef.h =================================================================== --- sys/mips/atheros/ar531x/ar5315_cpudef.h +++ /dev/null @@ -1,139 +0,0 @@ -/*- - * Copyright (c) 2010 Adrian Chadd - * 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 __AR5315_CPUDEF_H__ -#define __AR5315_CPUDEF_H__ - -struct ar5315_cpu_def { - void (* detect_mem_size) (void); - void (* detect_sys_frequency) (void); - void (* ar5315_chip_device_reset) (void); - void (* ar5315_chip_device_start) (void); - int (* ar5315_chip_device_stopped) (uint32_t); - void (* ar5315_chip_set_pll_ge) (int, int); - void (* ar5315_chip_set_mii_speed) (uint32_t, uint32_t); - void (* ar5315_chip_ddr_flush_ge) (int); - uint32_t (* ar5315_chip_get_eth_pll) (unsigned int, int); - void (* ar5315_chip_soc_init) (void); - - /* - * Allow to change MII bus mode: - * AR5315_ARGE_MII_MODE_MII - * AR5315_ARGE_MII_MODE_RMII - * AR5315_ARGE_MII_MODE_GMII - * AR5315_ARGE_MII_MODE_RGMII - * mii_mode(unit, mode); - */ -#define AR5315_ARGE_MII_MODE_MII 0x0100 -#define AR5315_ARGE_MII_MODE_RMII 0x0101 -#define AR5315_ARGE_MII_MODE_GMII 0x1000 -#define AR5315_ARGE_MII_MODE_RGMII 0x1001 - void (* ar5315_chip_set_mii_mode) (int, int, int); -}; - -extern struct ar5315_cpu_def * ar5315_cpu_ops; - -static inline void ar531x_detect_mem_size(void) -{ - ar5315_cpu_ops->detect_mem_size(); -} - -static inline void ar531x_detect_sys_frequency(void) -{ - ar5315_cpu_ops->detect_sys_frequency(); -} - -static inline void ar531x_device_reset(void) -{ - ar5315_cpu_ops->ar5315_chip_device_reset(); -} - -static inline void ar531x_device_start(void) -{ - ar5315_cpu_ops->ar5315_chip_device_start(); -} - -static inline int ar531x_device_stopped(uint32_t mask) -{ - return ar5315_cpu_ops->ar5315_chip_device_stopped(mask); -} - -static inline void ar531x_device_set_pll_ge(int unit, int speed) -{ - ar5315_cpu_ops->ar5315_chip_set_pll_ge(unit, speed); -} - -static inline void ar531x_device_set_mii_speed(int unit, int speed) -{ - ar5315_cpu_ops->ar5315_chip_set_mii_speed(unit, speed); -} - -static inline void ar531x_device_flush_ddr_ge(int unit) -{ - ar5315_cpu_ops->ar5315_chip_ddr_flush_ge(unit); -} - -static inline void ar531x_device_soc_init(void) -{ - ar5315_cpu_ops->ar5315_chip_soc_init(); -} - -static inline void ar531x_device_set_mii_mode(int unit, int mode, int speed) -{ - ar5315_cpu_ops->ar5315_chip_set_mii_mode(unit, mode, speed); -} - -/* XXX shouldn't be here! */ -extern uint32_t u_ar531x_cpu_freq; -extern uint32_t u_ar531x_ahb_freq; -extern uint32_t u_ar531x_ddr_freq; - -extern uint32_t u_ar531x_uart_addr; - -extern uint32_t u_ar531x_gpio_di; -extern uint32_t u_ar531x_gpio_do; -extern uint32_t u_ar531x_gpio_cr; -extern uint32_t u_ar531x_gpio_pins; - -extern uint32_t u_ar531x_wdog_ctl; -extern uint32_t u_ar531x_wdog_timer; - -static inline uint32_t ar531x_cpu_freq(void) { return u_ar531x_cpu_freq; } -static inline uint32_t ar531x_ahb_freq(void) { return u_ar531x_ahb_freq; } -static inline uint32_t ar531x_ddr_freq(void) { return u_ar531x_ddr_freq; } - -static inline uint32_t ar531x_uart_addr(void) { return u_ar531x_uart_addr; } - -static inline uint32_t ar531x_gpio_di(void) { return u_ar531x_gpio_di; } -static inline uint32_t ar531x_gpio_cr(void) { return u_ar531x_gpio_cr; } -static inline uint32_t ar531x_gpio_do(void) { return u_ar531x_gpio_do; } -static inline uint32_t ar531x_gpio_pins(void) { return u_ar531x_gpio_pins; } - -static inline uint32_t ar531x_wdog_ctl(void) { return u_ar531x_wdog_ctl; } -static inline uint32_t ar531x_wdog_timer(void) { return u_ar531x_wdog_timer; } -#endif Index: sys/mips/atheros/ar531x/ar5315_gpio.c =================================================================== --- sys/mips/atheros/ar531x/ar5315_gpio.c +++ /dev/null @@ -1,534 +0,0 @@ -/*- - * Copyright (c) 2016, Hiroki Mori - * Copyright (c) 2009, Oleksandr Tymoshenko - * Copyright (c) 2009, Luiz Otavio O Souza. - * 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 unmodified, 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. - */ - -/* - * GPIO driver for AR5315 - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "gpio_if.h" - -#define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT) - -/* - * Helpers - */ -static void ar5315_gpio_function_enable(struct ar5315_gpio_softc *sc, - uint32_t mask); -static void ar5315_gpio_function_disable(struct ar5315_gpio_softc *sc, - uint32_t mask); -static void ar5315_gpio_pin_configure(struct ar5315_gpio_softc *sc, - struct gpio_pin *pin, uint32_t flags); - -/* - * Driver stuff - */ -static int ar5315_gpio_probe(device_t dev); -static int ar5315_gpio_attach(device_t dev); -static int ar5315_gpio_detach(device_t dev); -static int ar5315_gpio_filter(void *arg); -static void ar5315_gpio_intr(void *arg); - -/* - * GPIO interface - */ -static device_t ar5315_gpio_get_bus(device_t); -static int ar5315_gpio_pin_max(device_t dev, int *maxpin); -static int ar5315_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps); -static int ar5315_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t - *flags); -static int ar5315_gpio_pin_getname(device_t dev, uint32_t pin, char *name); -static int ar5315_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags); -static int ar5315_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value); -static int ar5315_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val); -static int ar5315_gpio_pin_toggle(device_t dev, uint32_t pin); - -/* - * Enable/disable the GPIO function control space. - * - * This is primarily for the AR5315, which has SPI CS1/CS2, UART, SLIC, I2S - * as GPIO pin options. - */ -static void -ar5315_gpio_function_enable(struct ar5315_gpio_softc *sc, uint32_t mask) -{ -// GPIO_SET_BITS(sc, AR5315_GPIO_FUNCTION, mask); -} - -static void -ar5315_gpio_function_disable(struct ar5315_gpio_softc *sc, uint32_t mask) -{ -// GPIO_CLEAR_BITS(sc, AR5315_GPIO_FUNCTION, mask); -} - -static void -ar5315_gpio_pin_configure(struct ar5315_gpio_softc *sc, struct gpio_pin *pin, - unsigned int flags) -{ - uint32_t mask; - - mask = 1 << pin->gp_pin; - - /* - * Manage input/output - */ - if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) { - pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT); - if (flags & GPIO_PIN_OUTPUT) { - pin->gp_flags |= GPIO_PIN_OUTPUT; - GPIO_SET_BITS(sc, ar531x_gpio_cr(), mask); - } - else { - pin->gp_flags |= GPIO_PIN_INPUT; - GPIO_CLEAR_BITS(sc, ar531x_gpio_cr(), mask); - } - } -} - -static device_t -ar5315_gpio_get_bus(device_t dev) -{ - struct ar5315_gpio_softc *sc; - - sc = device_get_softc(dev); - - return (sc->busdev); -} - -static int -ar5315_gpio_pin_max(device_t dev, int *maxpin) -{ - - *maxpin = ar531x_gpio_pins() - 1; - return (0); -} - -static int -ar5315_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) -{ - struct ar5315_gpio_softc *sc = device_get_softc(dev); - int i; - - for (i = 0; i < sc->gpio_npins; i++) { - if (sc->gpio_pins[i].gp_pin == pin) - break; - } - - if (i >= sc->gpio_npins) - return (EINVAL); - - GPIO_LOCK(sc); - *caps = sc->gpio_pins[i].gp_caps; - GPIO_UNLOCK(sc); - - return (0); -} - -static int -ar5315_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) -{ - struct ar5315_gpio_softc *sc = device_get_softc(dev); - int i; - int dir; - - for (i = 0; i < sc->gpio_npins; i++) { - if (sc->gpio_pins[i].gp_pin == pin) - break; - } - - if (i >= sc->gpio_npins) - return (EINVAL); - - dir = GPIO_READ(sc, ar531x_gpio_cr()) & (1 << pin); - - *flags = dir ? GPIO_PIN_OUTPUT : GPIO_PIN_INPUT; - -/* - GPIO_LOCK(sc); - *flags = sc->gpio_pins[i].gp_flags; - GPIO_UNLOCK(sc); -*/ - - return (0); -} - -static int -ar5315_gpio_pin_getname(device_t dev, uint32_t pin, char *name) -{ - struct ar5315_gpio_softc *sc = device_get_softc(dev); - int i; - - for (i = 0; i < sc->gpio_npins; i++) { - if (sc->gpio_pins[i].gp_pin == pin) - break; - } - - if (i >= sc->gpio_npins) - return (EINVAL); - - GPIO_LOCK(sc); - memcpy(name, sc->gpio_pins[i].gp_name, GPIOMAXNAME); - GPIO_UNLOCK(sc); - - return (0); -} - -static int -ar5315_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) -{ - int i; - struct ar5315_gpio_softc *sc = device_get_softc(dev); - - for (i = 0; i < sc->gpio_npins; i++) { - if (sc->gpio_pins[i].gp_pin == pin) - break; - } - - if (i >= sc->gpio_npins) - return (EINVAL); - - ar5315_gpio_pin_configure(sc, &sc->gpio_pins[i], flags); - - return (0); -} - -static int -ar5315_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) -{ - struct ar5315_gpio_softc *sc = device_get_softc(dev); - uint32_t state; - - state = GPIO_READ(sc, ar531x_gpio_do()); - - if(value == 1) { - state |= (1 << pin); - } else { - state &= ~(1 << pin); - } - - GPIO_WRITE(sc, ar531x_gpio_do(), state); - - return (0); -} - -static int -ar5315_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) -{ - struct ar5315_gpio_softc *sc = device_get_softc(dev); - int i; - - for (i = 0; i < sc->gpio_npins; i++) { - if (sc->gpio_pins[i].gp_pin == pin) - break; - } - - if (i >= sc->gpio_npins) - return (EINVAL); - - *val = (GPIO_READ(sc, ar531x_gpio_di()) & (1 << pin)) ? 1 : 0; - - return (0); -} - -static int -ar5315_gpio_pin_toggle(device_t dev, uint32_t pin) -{ - int res, i; - struct ar5315_gpio_softc *sc = device_get_softc(dev); - - for (i = 0; i < sc->gpio_npins; i++) { - if (sc->gpio_pins[i].gp_pin == pin) - break; - } - - if (i >= sc->gpio_npins) - return (EINVAL); - - res = (GPIO_READ(sc, ar531x_gpio_do()) & (1 << pin)) ? 1 : 0; - if (res) - GPIO_CLEAR_BITS(sc, ar531x_gpio_do(), pin); - else - GPIO_SET_BITS(sc, ar531x_gpio_do(), pin); - - return (0); -} - -static int -ar5315_gpio_filter(void *arg) -{ - - /* TODO: something useful */ - return (FILTER_STRAY); -} - - - -static void -ar5315_gpio_intr(void *arg) -{ - struct ar5315_gpio_softc *sc = arg; - GPIO_LOCK(sc); - /* TODO: something useful */ - GPIO_UNLOCK(sc); -} - -static int -ar5315_gpio_probe(device_t dev) -{ - - device_set_desc(dev, "Atheros AR531x GPIO driver"); - return (0); -} - -static int -ar5315_gpio_attach(device_t dev) -{ - struct ar5315_gpio_softc *sc = device_get_softc(dev); - int i, j, maxpin; - int mask, pinon; - uint32_t oe; - - KASSERT((device_get_unit(dev) == 0), - ("ar5315_gpio: Only one gpio module supported")); - - mtx_init(&sc->gpio_mtx, device_get_nameunit(dev), NULL, MTX_DEF); - - /* Map control/status registers. */ - sc->gpio_mem_rid = 0; - sc->gpio_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, - &sc->gpio_mem_rid, RF_ACTIVE); - - if (sc->gpio_mem_res == NULL) { - device_printf(dev, "couldn't map memory\n"); - ar5315_gpio_detach(dev); - return (ENXIO); - } - - if ((sc->gpio_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, - &sc->gpio_irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) { - device_printf(dev, "unable to allocate IRQ resource\n"); - ar5315_gpio_detach(dev); - return (ENXIO); - } - - if ((bus_setup_intr(dev, sc->gpio_irq_res, INTR_TYPE_MISC, - ar5315_gpio_filter, ar5315_gpio_intr, sc, &sc->gpio_ih))) { - device_printf(dev, - "WARNING: unable to register interrupt handler\n"); - ar5315_gpio_detach(dev); - return (ENXIO); - } - - sc->dev = dev; - - /* Enable function bits that are required */ - if (resource_int_value(device_get_name(dev), device_get_unit(dev), - "function_set", &mask) == 0) { - device_printf(dev, "function_set: 0x%x\n", mask); - ar5315_gpio_function_enable(sc, mask); - } - /* Disable function bits that are required */ - if (resource_int_value(device_get_name(dev), device_get_unit(dev), - "function_clear", &mask) == 0) { - device_printf(dev, "function_clear: 0x%x\n", mask); - ar5315_gpio_function_disable(sc, mask); - } - - /* Initialise all pins specified in the mask, up to the pin count */ - (void) ar5315_gpio_pin_max(dev, &maxpin); - if (resource_int_value(device_get_name(dev), device_get_unit(dev), - "pinmask", &mask) != 0) - mask = 0; - if (resource_int_value(device_get_name(dev), device_get_unit(dev), - "pinon", &pinon) != 0) - pinon = 0; - device_printf(dev, "gpio pinmask=0x%x\n", mask); - for (j = 0; j <= maxpin; j++) { - if ((mask & (1 << j)) == 0) - continue; - sc->gpio_npins++; - } - - /* Iniatilize the GPIO pins, keep the loader settings. */ - oe = GPIO_READ(sc, ar531x_gpio_cr()); - sc->gpio_pins = malloc(sizeof(struct gpio_pin) * sc->gpio_npins, - M_DEVBUF, M_WAITOK | M_ZERO); - for (i = 0, j = 0; j <= maxpin; j++) { - if ((mask & (1 << j)) == 0) - continue; - snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME, - "pin %d", j); - sc->gpio_pins[i].gp_pin = j; - sc->gpio_pins[i].gp_caps = DEFAULT_CAPS; - if (oe & (1 << j)) - sc->gpio_pins[i].gp_flags = GPIO_PIN_OUTPUT; - else - sc->gpio_pins[i].gp_flags = GPIO_PIN_INPUT; - i++; - } - -#if 0 - /* Turn on the hinted pins. */ - for (i = 0; i < sc->gpio_npins; i++) { - j = sc->gpio_pins[i].gp_pin; - if ((pinon & (1 << j)) != 0) { - ar5315_gpio_pin_setflags(dev, j, GPIO_PIN_OUTPUT); - ar5315_gpio_pin_set(dev, j, 1); - } - } - - /* - * Search through the function hints, in case there's some - * overrides such as LNA control. - * - * hint.gpio.X.func..gpiofunc= - * hint.gpio.X.func..gpiomode=1 (for output, default low) - */ - for (i = 0; i <= maxpin; i++) { - char buf[32]; - int gpiofunc, gpiomode; - - snprintf(buf, 32, "func.%d.gpiofunc", i); - if (resource_int_value(device_get_name(dev), - device_get_unit(dev), - buf, - &gpiofunc) != 0) - continue; - /* Get the mode too */ - snprintf(buf, 32, "func.%d.gpiomode", i); - if (resource_int_value(device_get_name(dev), - device_get_unit(dev), - buf, - &gpiomode) != 0) - continue; - - /* We only handle mode=1 for now */ - if (gpiomode != 1) - continue; - - device_printf(dev, "%s: GPIO %d: func=%d, mode=%d\n", - __func__, - i, - gpiofunc, - gpiomode); - - /* Set output (bit == 0) */ - oe = GPIO_READ(sc, ar531x_gpio_cr()); - oe &= ~ (1 << i); - GPIO_WRITE(sc, ar531x_gpio_cr(), oe); - - /* Set pin value = 0, so it stays low by default */ - oe = GPIO_READ(sc, ar531x_gpio_do()); - oe &= ~ (1 << i); - GPIO_WRITE(sc, ar531x_gpio_do(), oe); - - /* Finally: Set the output config */ -// ar5315_gpio_ouput_configure(i, gpiofunc); - } -#endif - - sc->busdev = gpiobus_attach_bus(dev); - if (sc->busdev == NULL) { - ar5315_gpio_detach(dev); - return (ENXIO); - } - - return (0); -} - -static int -ar5315_gpio_detach(device_t dev) -{ - struct ar5315_gpio_softc *sc = device_get_softc(dev); - - KASSERT(mtx_initialized(&sc->gpio_mtx), ("gpio mutex not initialized")); - - gpiobus_detach_bus(dev); - if (sc->gpio_ih) - bus_teardown_intr(dev, sc->gpio_irq_res, sc->gpio_ih); - if (sc->gpio_irq_res) - bus_release_resource(dev, SYS_RES_IRQ, sc->gpio_irq_rid, - sc->gpio_irq_res); - if (sc->gpio_mem_res) - bus_release_resource(dev, SYS_RES_MEMORY, sc->gpio_mem_rid, - sc->gpio_mem_res); - if (sc->gpio_pins) - free(sc->gpio_pins, M_DEVBUF); - mtx_destroy(&sc->gpio_mtx); - - return(0); -} - -static device_method_t ar5315_gpio_methods[] = { - DEVMETHOD(device_probe, ar5315_gpio_probe), - DEVMETHOD(device_attach, ar5315_gpio_attach), - DEVMETHOD(device_detach, ar5315_gpio_detach), - - /* GPIO protocol */ - DEVMETHOD(gpio_get_bus, ar5315_gpio_get_bus), - DEVMETHOD(gpio_pin_max, ar5315_gpio_pin_max), - DEVMETHOD(gpio_pin_getname, ar5315_gpio_pin_getname), - DEVMETHOD(gpio_pin_getflags, ar5315_gpio_pin_getflags), - DEVMETHOD(gpio_pin_getcaps, ar5315_gpio_pin_getcaps), - DEVMETHOD(gpio_pin_setflags, ar5315_gpio_pin_setflags), - DEVMETHOD(gpio_pin_get, ar5315_gpio_pin_get), - DEVMETHOD(gpio_pin_set, ar5315_gpio_pin_set), - DEVMETHOD(gpio_pin_toggle, ar5315_gpio_pin_toggle), - {0, 0}, -}; - -static driver_t ar5315_gpio_driver = { - "gpio", - ar5315_gpio_methods, - sizeof(struct ar5315_gpio_softc), -}; -static devclass_t ar5315_gpio_devclass; - -DRIVER_MODULE(ar5315_gpio, apb, ar5315_gpio_driver, ar5315_gpio_devclass, 0, 0); Index: sys/mips/atheros/ar531x/ar5315_gpiovar.h =================================================================== --- sys/mips/atheros/ar531x/ar5315_gpiovar.h +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * Copyright (c) 2009, Oleksandr Tymoshenko - * Copyright (c) 2009, Luiz Otavio O Souza. - * 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 unmodified, 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 __AR5315_GPIOVAR_H__ -#define __AR5315_GPIOVAR_H__ - -#include - -#define GPIO_LOCK(_sc) mtx_lock(&(_sc)->gpio_mtx) -#define GPIO_UNLOCK(_sc) mtx_unlock(&(_sc)->gpio_mtx) -#define GPIO_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->gpio_mtx, MA_OWNED) - -/* - * register space access macros - */ -#define GPIO_WRITE(sc, reg, val) do { \ - bus_write_4(sc->gpio_mem_res, (reg), (val)); \ - } while (0) - -#define GPIO_READ(sc, reg) bus_read_4(sc->gpio_mem_res, (reg)) - -#define GPIO_SET_BITS(sc, reg, bits) \ - GPIO_WRITE(sc, reg, GPIO_READ(sc, (reg)) | (bits)) - -#define GPIO_CLEAR_BITS(sc, reg, bits) \ - GPIO_WRITE(sc, reg, GPIO_READ(sc, (reg)) & ~(bits)) - -#define AR5315_GPIO_PINS 23 -#define AR5312_GPIO_PINS 8 - -struct ar5315_gpio_softc { - device_t dev; - device_t busdev; - struct mtx gpio_mtx; - struct resource *gpio_mem_res; - int gpio_mem_rid; - struct resource *gpio_irq_res; - int gpio_irq_rid; - void *gpio_ih; - int gpio_npins; - struct gpio_pin *gpio_pins; - int gpio_ppspin; - struct pps_state gpio_pps; - uint32_t gpio_ppsenable; -}; - -#endif /* __AR5315_GPIOVAR_H__ */ Index: sys/mips/atheros/ar531x/ar5315_machdep.c =================================================================== --- sys/mips/atheros/ar531x/ar5315_machdep.c +++ /dev/null @@ -1,319 +0,0 @@ -/*- - * Copyright (c) 2016, Hiroki Mori - * Copyright (c) 2009 Oleksandr Tymoshenko - * 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 "opt_ddb.h" -#include "opt_ar531x.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -extern char edata[], end[]; - -uint32_t ar711_base_mac[ETHER_ADDR_LEN]; -/* 4KB static data aread to keep a copy of the bootload env until - the dynamic kenv is setup */ -char boot1_env[4096]; - -void -platform_cpu_init() -{ - /* Nothing special */ -} - -void -platform_reset(void) -{ - ar531x_device_reset(); - /* Wait for reset */ - while(1) - ; -} - -/* - * Obtain the MAC address via the Redboot environment. - */ -static void -ar5315_redboot_get_macaddr(void) -{ - char *var; - int count = 0; - - /* - * "ethaddr" is passed via envp on RedBoot platforms - * "kmac" is passed via argv on RouterBOOT platforms - */ - if ((var = kern_getenv("ethaddr")) != NULL || - (var = kern_getenv("kmac")) != NULL) { - count = sscanf(var, "%x%*c%x%*c%x%*c%x%*c%x%*c%x", - &ar711_base_mac[0], &ar711_base_mac[1], - &ar711_base_mac[2], &ar711_base_mac[3], - &ar711_base_mac[4], &ar711_base_mac[5]); - if (count < 6) - memset(ar711_base_mac, 0, - sizeof(ar711_base_mac)); - freeenv(var); - } -} - -#if defined(SOC_VENDOR) || defined(SOC_MODEL) || defined(SOC_REV) -static SYSCTL_NODE(_hw, OID_AUTO, soc, CTLFLAG_RD, 0, - "System on Chip information"); -#endif -#if defined(SOC_VENDOR) -static char hw_soc_vendor[] = SOC_VENDOR; -SYSCTL_STRING(_hw_soc, OID_AUTO, vendor, CTLFLAG_RD, hw_soc_vendor, 0, - "SoC vendor"); -#endif -#if defined(SOC_MODEL) -static char hw_soc_model[] = SOC_MODEL; -SYSCTL_STRING(_hw_soc, OID_AUTO, model, CTLFLAG_RD, hw_soc_model, 0, - "SoC model"); -#endif -#if defined(SOC_REV) -static char hw_soc_revision[] = SOC_REV; -SYSCTL_STRING(_hw_soc, OID_AUTO, revision, CTLFLAG_RD, hw_soc_revision, 0, - "SoC revision"); -#endif - -#if defined(DEVICE_VENDOR) || defined(DEVICE_MODEL) || defined(DEVICE_REV) -static SYSCTL_NODE(_hw, OID_AUTO, device, CTLFLAG_RD, 0, "Board information"); -#endif -#if defined(DEVICE_VENDOR) -static char hw_device_vendor[] = DEVICE_VENDOR; -SYSCTL_STRING(_hw_device, OID_AUTO, vendor, CTLFLAG_RD, hw_device_vendor, 0, - "Board vendor"); -#endif -#if defined(DEVICE_MODEL) -static char hw_device_model[] = DEVICE_MODEL; -SYSCTL_STRING(_hw_device, OID_AUTO, model, CTLFLAG_RD, hw_device_model, 0, - "Board model"); -#endif -#if defined(DEVICE_REV) -static char hw_device_revision[] = DEVICE_REV; -SYSCTL_STRING(_hw_device, OID_AUTO, revision, CTLFLAG_RD, hw_device_revision, 0, - "Board revision"); -#endif - -void -platform_start(__register_t a0 __unused, __register_t a1 __unused, - __register_t a2 __unused, __register_t a3 __unused) -{ - uint64_t platform_counter_freq; - int argc = 0, i; - char **argv = NULL; -#ifndef AR531X_ENV_UBOOT - char **envp = NULL; -#endif - vm_offset_t kernend; - - /* - * clear the BSS and SBSS segments, this should be first call in - * the function - */ - kernend = (vm_offset_t)&end; - memset(&edata, 0, kernend - (vm_offset_t)(&edata)); - - mips_postboot_fixup(); - - /* Initialize pcpu stuff */ - mips_pcpu0_init(); - - /* - * Until some more sensible abstractions for uboot/redboot - * environment handling, we have to make this a compile-time - * hack. The existing code handles the uboot environment - * very incorrectly so we should just ignore initialising - * the relevant pointers. - */ -#ifndef AR531X_ENV_UBOOT - argc = a0; - argv = (char**)a1; - envp = (char**)a2; -#endif - /* - * Protect ourselves from garbage in registers - */ - if (MIPS_IS_VALID_PTR(envp)) { - for (i = 0; envp[i]; i += 2) { - if (strcmp(envp[i], "memsize") == 0) - realmem = btoc(strtoul(envp[i+1], NULL, 16)); - } - } - - ar5315_detect_sys_type(); - -// RedBoot SDRAM Detect is missing -// ar531x_detect_mem_size(); - - /* - * Just wild guess. RedBoot let us down and didn't reported - * memory size - */ - if (realmem == 0) - realmem = btoc(16*1024*1024); - - /* - * Allow build-time override in case Redboot lies - * or in other situations (eg where there's u-boot) - * where there isn't (yet) a convienent method of - * being told how much RAM is available. - * - * This happens on at least the Ubiquiti LS-SR71A - * board, where redboot says there's 16mb of RAM - * but in fact there's 32mb. - */ -#if defined(AR531X_REALMEM) - realmem = btoc(AR531X_REALMEM); -#endif - - /* phys_avail regions are in bytes */ - phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end); - phys_avail[1] = ctob(realmem); - - dump_avail[0] = phys_avail[0]; - dump_avail[1] = phys_avail[1] - phys_avail[0]; - - physmem = realmem; - - /* - * ns8250 uart code uses DELAY so ticker should be inititalized - * before cninit. And tick_init_params refers to hz, so * init_param1 - * should be called first. - */ - init_param1(); - boothowto |= (RB_SERIAL | RB_MULTIPLE); /* Use multiple consoles */ -// boothowto |= RB_VERBOSE; -// boothowto |= (RB_SINGLE); - - /* Detect the system type - this is needed for subsequent chipset-specific calls */ - - - ar531x_device_soc_init(); - ar531x_detect_sys_frequency(); - - platform_counter_freq = ar531x_cpu_freq(); - mips_timer_init_params(platform_counter_freq, 1); - cninit(); - init_static_kenv(boot1_env, sizeof(boot1_env)); - - printf("CPU platform: %s\n", ar5315_get_system_type()); - printf("CPU Frequency=%d MHz\n", ar531x_cpu_freq() / 1000000); - printf("CPU DDR Frequency=%d MHz\n", ar531x_ddr_freq() / 1000000); - printf("CPU AHB Frequency=%d MHz\n", ar531x_ahb_freq() / 1000000); - - printf("platform frequency: %lld\n", platform_counter_freq); - printf("arguments: \n"); - printf(" a0 = %08x\n", a0); - printf(" a1 = %08x\n", a1); - printf(" a2 = %08x\n", a2); - printf(" a3 = %08x\n", a3); - - /* - * XXX this code is very redboot specific. - */ - printf("Cmd line:"); - if (MIPS_IS_VALID_PTR(argv)) { - for (i = 0; i < argc; i++) { - printf(" %s", argv[i]); - boothowto |= boot_parse_arg(argv[i]); - } - } - else - printf ("argv is invalid"); - printf("\n"); - - printf("Environment:\n"); -#if 0 - if (MIPS_IS_VALID_PTR(envp)) { - if (envp[0] && strchr(envp[0], '=') ) { - char *env_val; // - for (i = 0; envp[i]; i++) { - env_val = strchr(envp[i], '='); - /* Not sure if we correct to change data, but env in RAM */ - *(env_val++) = '\0'; - printf("= %s = %s\n", envp[i], env_val); - kern_setenv(envp[i], env_val); - } - } else { - for (i = 0; envp[i]; i+=2) { - printf(" %s = %s\n", envp[i], envp[i+1]); - kern_setenv(envp[i], envp[i+1]); - } - } - } - else - printf ("envp is invalid\n"); -#else - printf ("envp skiped\n"); -#endif - - /* Redboot if_are MAC address is in the environment */ - ar5315_redboot_get_macaddr(); - - init_param2(physmem); - mips_cpu_init(); - pmap_bootstrap(); - mips_proc0_init(); - mutex_init(); - - ar531x_device_start(); - - kdb_init(); -#ifdef KDB - if (boothowto & RB_KDB) - kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); -#endif - -} Index: sys/mips/atheros/ar531x/ar5315_setup.h =================================================================== --- sys/mips/atheros/ar531x/ar5315_setup.h +++ /dev/null @@ -1,51 +0,0 @@ -/*- - * Copyright (c) 2010 Adrian Chadd - * 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 __AR5315_SETUP_H__ -#define __AR5315_SETUP_H__ - -enum ar531x_soc_type { - AR531X_SOC_UNKNOWN, - AR531X_SOC_AR5311, - AR531X_SOC_AR5312, - AR531X_SOC_AR5313, - AR531X_SOC_AR5314, - AR531X_SOC_AR5315, - AR531X_SOC_AR5316, - AR531X_SOC_AR5317, - AR531X_SOC_AR5318, -}; -extern enum ar531x_soc_type ar531x_soc; - -extern void ar5315_detect_sys_type(void); -extern const char *ar5315_get_system_type(void); - -#define AR_FIRST_GEN 1 -#define AR_SECOND_GEN 2 - -#endif Index: sys/mips/atheros/ar531x/ar5315_setup.c =================================================================== --- sys/mips/atheros/ar531x/ar5315_setup.c +++ /dev/null @@ -1,161 +0,0 @@ -/*- - * Copyright (c) 2016, Hiroki Mori - * Copyright (c) 2010 Adrian Chadd - * 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 "opt_ddb.h" -#include "opt_ar531x.h" - -#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 AR5315_SYS_TYPE_LEN 128 - -static char ar5315_sys_type[AR5315_SYS_TYPE_LEN]; -enum ar531x_soc_type ar531x_soc; -struct ar5315_cpu_def * ar5315_cpu_ops = NULL; - -void -ar5315_detect_sys_type(void) -{ - char *chip = "????"; - uint32_t ver = 0; - uint32_t rev = 0; -#if 0 - const uint8_t *ptr, *end; - static const struct ar531x_boarddata *board = NULL; - - ptr = (const uint8_t *) MIPS_PHYS_TO_KSEG1(AR5315_CONFIG_END - - 0x1000); - - end = (const uint8_t *)AR5315_CONFIG_BASE; - - for (; ptr > end; ptr -= 0x1000) { - if (*(const uint32_t *)ptr == AR531X_BD_MAGIC) { - board = (const struct ar531x_boarddata *) ptr; - rev = board->major; - break; - } - } -#endif - int soctype; - -#ifdef AR531X_1ST_GENERATION - soctype = AR_FIRST_GEN; -#else - soctype = AR_SECOND_GEN; -#endif - - if(soctype == AR_SECOND_GEN) { - ar5315_cpu_ops = &ar5315_chip_def; - - ver = ATH_READ_REG(AR5315_SYSREG_BASE + - AR5315_SYSREG_SREV); - - switch (ver) { - case 0x86: - ar531x_soc = AR531X_SOC_AR5315; - chip = "2315"; - break; - case 0x87: - ar531x_soc = AR531X_SOC_AR5316; - chip = "2316"; - break; - case 0x90: - ar531x_soc = AR531X_SOC_AR5317; - chip = "2317"; - break; - case 0x91: - ar531x_soc = AR531X_SOC_AR5318; - chip = "2318"; - break; - } - } else { - ar5315_cpu_ops = &ar5312_chip_def; - - ver = ATH_READ_REG(AR5312_SYSREG_BASE + - AR5312_SYSREG_REVISION); - rev = AR5312_REVISION_MINOR(ver); - - switch (AR5312_REVISION_MAJOR(ver)) { - case AR5312_REVISION_MAJ_AR5311: - ar531x_soc = AR531X_SOC_AR5311; - chip = "5311"; - break; - case AR5312_REVISION_MAJ_AR5312: - ar531x_soc = AR531X_SOC_AR5312; - chip = "5312"; - break; - case AR5312_REVISION_MAJ_AR2313: - ar531x_soc = AR531X_SOC_AR5313; - chip = "2313"; - break; - } - } - - sprintf(ar5315_sys_type, "Atheros AR%s rev %u", chip, rev); -} - -const char * -ar5315_get_system_type(void) -{ - return ar5315_sys_type; -} - Index: sys/mips/atheros/ar531x/ar5315_spi.c =================================================================== --- sys/mips/atheros/ar531x/ar5315_spi.c +++ /dev/null @@ -1,290 +0,0 @@ -/*- - * Copyright (c) 2016, Hiroki Mori - * Copyright (c) 2009, Oleksandr Tymoshenko - * 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 unmodified, 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 "spibus_if.h" - -#include -#include - -#undef AR531X_SPI_DEBUG -#ifdef AR531X_SPI_DEBUG -#define dprintf printf -#else -#define dprintf(x, arg...) -#endif - -/* - * register space access macros - */ -#define SPI_WRITE(sc, reg, val) do { \ - bus_write_4(sc->sc_mem_res, (reg), (val)); \ - } while (0) - -#define SPI_READ(sc, reg) bus_read_4(sc->sc_mem_res, (reg)) - -#define SPI_SET_BITS(sc, reg, bits) \ - SPI_WRITE(sc, reg, SPI_READ(sc, (reg)) | (bits)) - -#define SPI_CLEAR_BITS(sc, reg, bits) \ - SPI_WRITE(sc, reg, SPI_READ(sc, (reg)) & ~(bits)) - -struct ar5315_spi_softc { - device_t sc_dev; - struct resource *sc_mem_res; - uint32_t sc_reg_ctrl; - uint32_t sc_debug; -}; - -static void -ar5315_spi_attach_sysctl(device_t dev) -{ - struct ar5315_spi_softc *sc; - struct sysctl_ctx_list *ctx; - struct sysctl_oid *tree; - - sc = device_get_softc(dev); - ctx = device_get_sysctl_ctx(dev); - tree = device_get_sysctl_tree(dev); - - SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, - "debug", CTLFLAG_RW, &sc->sc_debug, 0, - "ar5315_spi debugging flags"); -} - -static int -ar5315_spi_probe(device_t dev) -{ - device_set_desc(dev, "AR5315 SPI"); - return (0); -} - -static int -ar5315_spi_attach(device_t dev) -{ - struct ar5315_spi_softc *sc = device_get_softc(dev); - int rid; - - sc->sc_dev = dev; - rid = 0; - sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - if (!sc->sc_mem_res) { - device_printf(dev, "Could not map memory\n"); - return (ENXIO); - } - - device_add_child(dev, "spibus", -1); - ar5315_spi_attach_sysctl(dev); - - return (bus_generic_attach(dev)); -} - -static void -ar5315_spi_chip_activate(struct ar5315_spi_softc *sc, int cs) -{ -} - -static void -ar5315_spi_chip_deactivate(struct ar5315_spi_softc *sc, int cs) -{ -} - -static int -ar5315_spi_get_block(off_t offset, caddr_t data, off_t count) -{ - int i; - for(i = 0; i < count / 4; ++i) { - *((uint32_t *)data + i) = ATH_READ_REG(AR5315_MEM1_BASE + offset + i * 4); - } -// printf("ar5315_spi_get_blockr: %x %x %x\n", -// (int)offset, (int)count, *(uint32_t *)data); - return (0); -} - -static int -ar5315_spi_transfer(device_t dev, device_t child, struct spi_command *cmd) -{ - struct ar5315_spi_softc *sc; - uint8_t *buf_in, *buf_out; - int lin, lout; - uint32_t ctl, cnt, op, rdat, cs; - int i, j; - - sc = device_get_softc(dev); - - if (sc->sc_debug & 0x8000) - printf("ar5315_spi_transfer: CMD "); - - spibus_get_cs(child, &cs); - - cs &= ~SPIBUS_CS_HIGH; - - /* Open SPI controller interface */ - ar5315_spi_chip_activate(sc, cs); - - do { - ctl = SPI_READ(sc, ARSPI_REG_CTL); - } while (ctl & ARSPI_CTL_BUSY); - - /* - * Transfer command - */ - buf_out = (uint8_t *)cmd->tx_cmd; - op = buf_out[0]; - if(op == 0x0b) { - int offset = buf_out[1] << 16 | buf_out[2] << 8 | buf_out[3]; - ar5315_spi_get_block(offset, cmd->rx_data, cmd->rx_data_sz); - return (0); - } - do { - ctl = SPI_READ(sc, ARSPI_REG_CTL); - } while (ctl & ARSPI_CTL_BUSY); - if (sc->sc_debug & 0x8000) { - printf("%08x ", op); - printf("tx_cmd_sz=%d rx_cmd_sz=%d ", cmd->tx_cmd_sz, - cmd->rx_cmd_sz); - if(cmd->tx_cmd_sz != 1) { - printf("%08x ", *((uint32_t *)cmd->tx_cmd)); - printf("%08x ", *((uint32_t *)cmd->tx_cmd + 1)); - } - } - SPI_WRITE(sc, ARSPI_REG_OPCODE, op); - - /* clear all of the tx and rx bits */ - ctl &= ~(ARSPI_CTL_TXCNT_MASK | ARSPI_CTL_RXCNT_MASK); - - /* now set txcnt */ - cnt = 1; - - ctl |= (cnt << ARSPI_CTL_TXCNT_SHIFT); - - cnt = 24; - /* now set txcnt */ - if(cmd->rx_cmd_sz < 24) - cnt = cmd->rx_cmd_sz; - ctl |= (cnt << ARSPI_CTL_RXCNT_SHIFT); - - ctl |= ARSPI_CTL_START; - - SPI_WRITE(sc, ARSPI_REG_CTL, ctl); - - if(op == 0x0b) - SPI_WRITE(sc, ARSPI_REG_DATA, 0); - if (sc->sc_debug & 0x8000) - printf("\nDATA "); - /* - * Receive/transmit data (depends on command) - */ -// buf_out = (uint8_t *)cmd->tx_data; - buf_in = (uint8_t *)cmd->rx_cmd; -// lout = cmd->tx_data_sz; - lin = cmd->rx_cmd_sz; - if (sc->sc_debug & 0x8000) - printf("t%d r%d ", lout, lin); - for(i = 0; i <= (cnt - 1) / 4; ++i) { - do { - ctl = SPI_READ(sc, ARSPI_REG_CTL); - } while (ctl & ARSPI_CTL_BUSY); - - rdat = SPI_READ(sc, ARSPI_REG_DATA); - if (sc->sc_debug & 0x8000) - printf("I%08x ", rdat); - - for(j = 0; j < 4; ++j) { - buf_in[i * 4 + j + 1] = 0xff & (rdat >> (8 * j)); - if(i * 4 + j + 2 == cnt) - break; - } - } - - ar5315_spi_chip_deactivate(sc, cs); - /* - * Close SPI controller interface, restore flash memory mapped access. - */ - if (sc->sc_debug & 0x8000) - printf("\n"); - - return (0); -} - -static int -ar5315_spi_detach(device_t dev) -{ - struct ar5315_spi_softc *sc = device_get_softc(dev); - - if (sc->sc_mem_res) - bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); - - return (0); -} - -static device_method_t ar5315_spi_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, ar5315_spi_probe), - DEVMETHOD(device_attach, ar5315_spi_attach), - DEVMETHOD(device_detach, ar5315_spi_detach), - - DEVMETHOD(spibus_transfer, ar5315_spi_transfer), -// DEVMETHOD(spibus_get_block, ar5315_spi_get_block), - - DEVMETHOD_END -}; - -static driver_t ar5315_spi_driver = { - "spi", - ar5315_spi_methods, - sizeof(struct ar5315_spi_softc), -}; - -static devclass_t ar5315_spi_devclass; - -DRIVER_MODULE(ar5315_spi, nexus, ar5315_spi_driver, ar5315_spi_devclass, 0, 0); Index: sys/mips/atheros/ar531x/ar5315_wdog.c =================================================================== --- sys/mips/atheros/ar531x/ar5315_wdog.c +++ /dev/null @@ -1,150 +0,0 @@ -/*- - * Copyright (c) 2016, Hiroki Mori - * Copyright (c) 2009, Oleksandr Tymoshenko - * 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 unmodified, 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. - */ - -/* - * Watchdog driver for AR5315 - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -struct ar5315_wdog_softc { - device_t dev; - int armed; - int reboot_from_watchdog; - int debug; -}; - -static void -ar5315_wdog_watchdog_fn(void *private, u_int cmd, int *error) -{ - struct ar5315_wdog_softc *sc = private; - uint64_t timer_val; - - cmd &= WD_INTERVAL; - if (sc->debug) - device_printf(sc->dev, "ar5315_wdog_watchdog_fn: cmd: %x\n", cmd); - if (cmd > 0) { - timer_val = (uint64_t)(1ULL << cmd) * ar531x_ahb_freq() / - 1000000000; - if (sc->debug) - device_printf(sc->dev, "ar5315_wdog_watchdog_fn: programming timer: %jx\n", (uintmax_t) timer_val); - /* - * Load timer with large enough value to prevent spurious - * reset - */ - ATH_WRITE_REG(ar531x_wdog_timer(), - ar531x_ahb_freq() * 10); - ATH_WRITE_REG(ar531x_wdog_ctl(), - AR5315_WDOG_CTL_RESET); - ATH_WRITE_REG(ar531x_wdog_timer(), - (timer_val & 0xffffffff)); - sc->armed = 1; - *error = 0; - } else { - if (sc->debug) - device_printf(sc->dev, "ar5315_wdog_watchdog_fn: disarming\n"); - if (sc->armed) { - ATH_WRITE_REG(ar531x_wdog_ctl(), - AR5315_WDOG_CTL_IGNORE); - sc->armed = 0; - } - } -} - -static int -ar5315_wdog_probe(device_t dev) -{ - - device_set_desc(dev, "Atheros AR531x watchdog timer"); - return (0); -} - -static void -ar5315_wdog_sysctl(device_t dev) -{ - struct ar5315_wdog_softc *sc = device_get_softc(dev); - - struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev); - struct sysctl_oid *tree = device_get_sysctl_tree(sc->dev); - - SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, - "debug", CTLFLAG_RW, &sc->debug, 0, - "enable watchdog debugging"); - SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, - "armed", CTLFLAG_RD, &sc->armed, 0, - "whether the watchdog is armed"); - SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, - "reboot_from_watchdog", CTLFLAG_RD, &sc->reboot_from_watchdog, 0, - "whether the system rebooted from the watchdog"); -} - - -static int -ar5315_wdog_attach(device_t dev) -{ - struct ar5315_wdog_softc *sc = device_get_softc(dev); - - /* Initialise */ - sc->reboot_from_watchdog = 0; - sc->armed = 0; - sc->debug = 0; - ATH_WRITE_REG(ar531x_wdog_ctl(), AR5315_WDOG_CTL_IGNORE); - - sc->dev = dev; - EVENTHANDLER_REGISTER(watchdog_list, ar5315_wdog_watchdog_fn, sc, 0); - ar5315_wdog_sysctl(dev); - - return (0); -} - -static device_method_t ar5315_wdog_methods[] = { - DEVMETHOD(device_probe, ar5315_wdog_probe), - DEVMETHOD(device_attach, ar5315_wdog_attach), - DEVMETHOD_END -}; - -static driver_t ar5315_wdog_driver = { - "ar5315_wdog", - ar5315_wdog_methods, - sizeof(struct ar5315_wdog_softc), -}; -static devclass_t ar5315_wdog_devclass; - -DRIVER_MODULE(ar5315_wdog, apb, ar5315_wdog_driver, ar5315_wdog_devclass, 0, 0); Index: sys/mips/atheros/ar531x/ar5315reg.h =================================================================== --- sys/mips/atheros/ar531x/ar5315reg.h +++ /dev/null @@ -1,244 +0,0 @@ -/* $Id: ar5315reg.h,v 1.3 2011/07/07 05:06:44 matt Exp $ */ -/* - * Copyright (c) 2006 Urbana-Champaign Independent Media Center. - * Copyright (c) 2006 Garrett D'Amore. - * All rights reserved. - * - * This code was written by Garrett D'Amore for the Champaign-Urbana - * Community Wireless Network Project. - * - * 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 acknowledgements: - * This product includes software developed by the Urbana-Champaign - * Independent Media Center. - * This product includes software developed by Garrett D'Amore. - * 4. Urbana-Champaign Independent Media Center's name and Garrett - * D'Amore's name may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE URBANA-CHAMPAIGN INDEPENDENT - * MEDIA CENTER AND GARRETT D'AMORE ``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 URBANA-CHAMPAIGN INDEPENDENT - * MEDIA CENTER OR GARRETT D'AMORE 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 _MIPS_ATHEROS_AR5315REG_H_ -#define _MIPS_ATHEROS_AR5315REG_H_ - -#define AR5315_MEM0_BASE 0x00000000 /* sdram */ -#define AR5315_MEM1_BASE 0x08000000 /* spi flash */ -#define AR5315_WLAN_BASE 0x10000000 -#define AR5315_PCI_BASE 0x10100000 -#define AR5315_SDRAMCTL_BASE 0x10300000 -#define AR5315_LOCAL_BASE 0x10400000 /* local bus */ -#define AR5315_ENET_BASE 0x10500000 -#define AR5315_SYSREG_BASE 0x11000000 -#define AR5315_UART_BASE 0x11100000 -#define AR5315_SPI_BASE 0x11300000 /* spi flash */ -#define AR5315_BOOTROM_BASE 0x1FC00000 /* boot rom */ -#define AR5315_CONFIG_BASE 0x087D0000 /* flash start */ -#define AR5315_CONFIG_END 0x087FF000 /* flash end */ -#define AR5315_RADIO_END 0x1FFFF000 /* radio end */ - -#if 0 -#define AR5315_PCIEXT_BASE 0x80000000 /* pci external */ -#define AR5315_RAM2_BASE 0xc0000000 -#define AR5315_RAM3_BASE 0xe0000000 -#endif - -/* - * SYSREG registers -- offset relative to AR531X_SYSREG_BASE - */ -#define AR5315_SYSREG_COLDRESET 0x0000 -#define AR5315_SYSREG_RESETCTL 0x0004 -#define AR5315_SYSREG_AHB_ARB_CTL 0x0008 -#define AR5315_SYSREG_ENDIAN 0x000c -#define AR5315_SYSREG_NMI_CTL 0x0010 -#define AR5315_SYSREG_SREV 0x0014 -#define AR5315_SYSREG_IF_CTL 0x0018 -#define AR5315_SYSREG_MISC_INTSTAT 0x0020 -#define AR5315_SYSREG_MISC_INTMASK 0x0024 -#define AR5315_SYSREG_GISR 0x0028 -#define AR5315_SYSREG_TIMER 0x0030 -#define AR5315_SYSREG_RELOAD 0x0034 -#define AR5315_SYSREG_WDOG_TIMER 0x0038 -#define AR5315_SYSREG_WDOG_CTL 0x003c -#define AR5315_SYSREG_PERFCNT0 0x0048 -#define AR5315_SYSREG_PERFCNT1 0x004c -#define AR5315_SYSREG_AHB_ERR0 0x0050 -#define AR5315_SYSREG_AHB_ERR1 0x0054 -#define AR5315_SYSREG_AHB_ERR2 0x0058 -#define AR5315_SYSREG_AHB_ERR3 0x005c -#define AR5315_SYSREG_AHB_ERR4 0x0060 -#define AR5315_SYSREG_PLLC_CTL 0x0064 -#define AR5315_SYSREG_PLLV_CTL 0x0068 -#define AR5315_SYSREG_CPUCLK 0x006c -#define AR5315_SYSREG_AMBACLK 0x0070 -#define AR5315_SYSREG_SYNCCLK 0x0074 -#define AR5315_SYSREG_DSL_SLEEP_CTL 0x0080 -#define AR5315_SYSREG_DSL_SLEEP_DUR 0x0084 -#define AR5315_SYSREG_GPIO_DI 0x0088 -#define AR5315_SYSREG_GPIO_DO 0x0090 -#define AR5315_SYSREG_GPIO_CR 0x0098 -#define AR5315_SYSREG_GPIO_INT 0x00a0 - -#define AR5315_GPIO_PINS 23 - -/* Cold resets (AR5315_SYSREG_COLDRESET) */ -#define AR5315_COLD_AHB 0x00000001 -#define AR5315_COLD_APB 0x00000002 -#define AR5315_COLD_CPU 0x00000004 -#define AR5315_COLD_CPU_WARM 0x00000008 - -/* Resets (AR5315_SYSREG_RESETCTL) */ -#define AR5315_RESET_WARM_WLAN0_MAC 0x00000001 -#define AR5315_RESET_WARM_WLAN0_BB 0x00000002 -#define AR5315_RESET_MPEGTS 0x00000004 /* MPEG-TS */ -#define AR5315_RESET_PCIDMA 0x00000008 /* PCI dma */ -#define AR5315_RESET_MEMCTL 0x00000010 -#define AR5315_RESET_LOCAL 0x00000020 /* local bus */ -#define AR5315_RESET_I2C 0x00000040 /* i2c */ -#define AR5315_RESET_SPI 0x00000080 /* SPI */ -#define AR5315_RESET_UART 0x00000100 -#define AR5315_RESET_IR 0x00000200 /* infrared */ -#define AR5315_RESET_PHY0 0x00000400 /* enet phy */ -#define AR5315_RESET_ENET0 0x00000800 - -/* Watchdog control (AR5315_SYSREG_WDOG_CTL) */ -#define AR5315_WDOG_CTL_IGNORE 0x0000 -#define AR5315_WDOG_CTL_NMI 0x0001 -#define AR5315_WDOG_CTL_RESET 0x0002 - -/* AR5315 AHB arbitration control (AR5315_SYSREG_AHB_ARB_CTL) */ -#define AR5315_ARB_CPU 0x00001 -#define AR5315_ARB_WLAN 0x00002 -#define AR5315_ARB_MPEGTS 0x00004 -#define AR5315_ARB_LOCAL 0x00008 -#define AR5315_ARB_PCI 0x00010 -#define AR5315_ARB_ENET 0x00020 -#define AR5315_ARB_RETRY 0x00100 - -/* AR5315 endianness control (AR5315_SYSREG_ENDIAN) */ -#define AR5315_ENDIAN_AHB 0x00001 -#define AR5315_ENDIAN_WLAN 0x00002 -#define AR5315_ENDIAN_MPEGTS 0x00004 -#define AR5315_ENDIAN_PCI 0x00008 -#define AR5315_ENDIAN_MEMCTL 0x00010 -#define AR5315_ENDIAN_LOCAL 0x00020 -#define AR5315_ENDIAN_ENET 0x00040 -#define AR5315_ENDIAN_MERGE 0x00200 -#define AR5315_ENDIAN_CPU 0x00400 -#define AR5315_ENDIAN_PCIAHB 0x00800 -#define AR5315_ENDIAN_PCIAHB_BRIDGE 0x01000 -#define AR5315_ENDIAN_SPI 0x08000 -#define AR5315_ENDIAN_CPU_DRAM 0x10000 -#define AR5315_ENDIAN_CPU_PCI 0x20000 -#define AR5315_ENDIAN_CPU_MMR 0x40000 - -/* AR5315 AHB error bits */ -#define AR5315_AHB_ERROR_DET 1 /* error detected */ -#define AR5315_AHB_ERROR_OVR 2 /* AHB overflow */ -#define AR5315_AHB_ERROR_WDT 4 /* wdt (not hresp) */ - -/* AR5315 clocks */ -#define AR5315_PLLC_REF_DIV(reg) ((reg) & 0x3) -#define AR5315_PLLC_FB_DIV(reg) (((reg) & 0x7c) >> 2) -#define AR5315_PLLC_DIV_2(reg) (((reg) & 0x80) >> 7) -#define AR5315_PLLC_CLKC(reg) (((reg) & 0x1c000) >> 14) -#define AR5315_PLLC_CLKM(reg) (((reg) & 0x700000) >> 20) - -#define AR5315_CLOCKCTL_SELECT(reg) ((reg) & 0x3) -#define AR5315_CLOCKCTL_DIV(reg) (((reg) & 0xc) >> 2) - -/* - * SDRAMCTL registers -- offset relative to SDRAMCTL - */ -#define AR5315_SDRAMCTL_MEM_CFG 0x0000 -#define AR5315_MEM_CFG_DATA_WIDTH __BITS(13,14) -#define AR5315_MEM_CFG_COL_WIDTH __BITS(9,12) -#define AR5315_MEM_CFG_ROW_WIDTH __BITS(5,8) - -/* memory config 1 bits */ -#define AR531X_MEM_CFG1_BANK0 __BITS(8,10) -#define AR531X_MEM_CFG1_BANK1 __BITS(12,14) - -/* - * PCI configuration stuff. I don't pretend to fully understand these - * registers, they seem to be magic numbers in the Linux code. - */ -#define AR5315_PCI_MAC_RC 0x4000 -#define AR5315_PCI_MAC_SCR 0x4004 -#define AR5315_PCI_MAC_INTPEND 0x4008 -#define AR5315_PCI_MAC_SFR 0x400c -#define AR5315_PCI_MAC_PCICFG 0x4010 -#define AR5315_PCI_MAC_SREV 0x4020 - -#define PCI_MAC_RC_MAC 0x1 -#define PCI_MAC_RC_BB 0x2 - -#define PCI_MAC_SCR_SLM_MASK 0x00030000 -#define PCI_MAC_SCR_SLM_FWAKE 0x00000000 -#define PCI_MAC_SCR_SLM_FSLEEP 0x00010000 -#define PCI_MAC_SCR_SLM_NORMAL 0x00020000 - -#define PCI_MAC_PCICFG_SPWR_DN 0x00010000 - -/* IRQS */ -#define AR5315_CPU_IRQ_MISC 0 -#define AR5315_CPU_IRQ_WLAN 1 -#define AR5315_CPU_IRQ_ENET 2 - -#define AR5315_MISC_IRQ_UART 0 -#define AR5315_MISC_IRQ_I2C 1 -#define AR5315_MISC_IRQ_SPI 2 -#define AR5315_MISC_IRQ_AHBE 3 -#define AR5315_MISC_IRQ_AHPE 4 -#define AR5315_MISC_IRQ_TIMER 5 -#define AR5315_MISC_IRQ_GPIO 6 -#define AR5315_MISC_IRQ_WDOG 7 -#define AR5315_MISC_IRQ_IR 8 - -#define AR5315_APB_BASE AR5315_SYSREG_BASE -#define AR5315_APB_SIZE 0x06000000 - -#define ATH_READ_REG(reg) \ - *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((reg))) - -#define ATH_WRITE_REG(reg, val) \ - *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((reg))) = (val) - -/* Helpers from NetBSD cdefs.h */ -/* __BIT(n): nth bit, where __BIT(0) == 0x1. */ -#define __BIT(__n) \ - (((__n) >= NBBY * sizeof(uintmax_t)) ? 0 : ((uintmax_t)1 << (__n))) - -/* __BITS(m, n): bits m through n, m < n. */ -#define __BITS(__m, __n) \ - ((__BIT(MAX((__m), (__n)) + 1) - 1) ^ (__BIT(MIN((__m), (__n))) - 1)) - -/* find least significant bit that is set */ -#define __LOWEST_SET_BIT(__mask) ((((__mask) - 1) & (__mask)) ^ (__mask)) - -#define __SHIFTOUT(__x, __mask) (((__x) & (__mask)) / __LOWEST_SET_BIT(__mask)) -#define __SHIFTOUT_MASK(__mask) __SHIFTOUT((__mask), (__mask)) -#endif /* _MIPS_ATHEROS_AR531XREG_H_ */ Index: sys/mips/atheros/ar531x/arspireg.h =================================================================== --- sys/mips/atheros/ar531x/arspireg.h +++ /dev/null @@ -1,62 +0,0 @@ -/* $NetBSD: arspireg.h,v 1.1 2006/10/14 15:33:23 gdamore Exp $ */ - -/*- - * Copyright (c) 2006 Urbana-Champaign Independent Media Center. - * Copyright (c) 2006 Garrett D'Amore. - * All rights reserved. - * - * Portions of this code were written by Garrett D'Amore for the - * Champaign-Urbana Community Wireless Network Project. - * - * 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 acknowledgements: - * This product includes software developed by the Urbana-Champaign - * Independent Media Center. - * This product includes software developed by Garrett D'Amore. - * 4. Urbana-Champaign Independent Media Center's name and Garrett - * D'Amore's name may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE URBANA-CHAMPAIGN INDEPENDENT - * MEDIA CENTER AND GARRETT D'AMORE ``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 URBANA-CHAMPAIGN INDEPENDENT - * MEDIA CENTER OR GARRETT D'AMORE 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 _MIPS_ATHEROS_DEV_ARSPIREG_H -#define _MIPS_ATHEROS_DEV_ARSPIREG_H - -#define ARSPI_REG_CTL 0x00 -#define ARSPI_REG_OPCODE 0x04 -#define ARSPI_REG_DATA 0x08 - -#define ARSPI_CTL_START 0x00000100 -#define ARSPI_CTL_BUSY 0x00010000 -#define ARSPI_CTL_TXCNT_MASK 0x0000000f -#define ARSPI_CTL_TXCNT_SHIFT 0 -#define ARSPI_CTL_RXCNT_MASK 0x000000f0 -#define ARSPI_CTL_RXCNT_SHIFT 4 -#define ARSPI_CTL_SIZE_MASK 0x00060000 -#define ARSPI_CTL_CLKSEL_MASK 0x03000000 - -#endif /* _MIPS_ATHEROS_DEV_ARSPIREG_H */ Index: sys/mips/atheros/ar531x/files.ar5315 =================================================================== --- sys/mips/atheros/ar531x/files.ar5315 +++ /dev/null @@ -1,20 +0,0 @@ -# $FreeBSD$ - -mips/atheros/ar531x/apb.c standard -mips/atheros/ar531x/if_are.c optional are -mips/atheros/ar531x/ar5315_spi.c optional ar5315_spi -mips/atheros/ar531x/ar5315_wdog.c optional ar5315_wdog -mips/atheros/ar531x/ar5315_gpio.c optional gpio -mips/atheros/ar531x/ar5315_machdep.c standard -mips/atheros/ar531x/ar5315_chip.c standard -mips/atheros/ar531x/ar5315_setup.c standard -mips/atheros/ar531x/uart_bus_ar5315.c optional uart_ar5315 -mips/atheros/ar531x/uart_cpu_ar5315.c optional uart_ar5315 - -mips/atheros/ar531x/ar5312_chip.c standard - -mips/atheros/ar71xx_bus_space_reversed.c standard -mips/mips/tick.c standard - -# Non Intrng -mips/mips/intr_machdep.c optional !intrng Index: sys/mips/atheros/ar531x/if_are.c =================================================================== --- sys/mips/atheros/ar531x/if_are.c +++ /dev/null @@ -1,1762 +0,0 @@ -/*- - * Copyright (c) 2016 Hiroki Mori. All rights reserved. - * Copyright (C) 2007 - * Oleksandr Tymoshenko . 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 OR HIS RELATIVES 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 MIND, 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. - * - * $Id: $ - * - */ - -#include "opt_platform.h" -#include "opt_ar531x.h" - -#include -__FBSDID("$FreeBSD$"); - -/* - * AR531x Ethernet interface driver - * copy from mips/idt/if_kr.c and netbsd code - */ -#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 - -#ifdef INTRNG -#include -#endif - -#include -#include - -#ifdef ARE_MDIO -#include -#include -#include "mdio_if.h" -#endif - -MODULE_DEPEND(are, ether, 1, 1, 1); -MODULE_DEPEND(are, miibus, 1, 1, 1); - -#include "miibus_if.h" - -#include -#include -#include -#include - -#ifdef ARE_DEBUG -void dump_txdesc(struct are_softc *, int); -void dump_status_reg(struct are_softc *); -#endif - -static int are_attach(device_t); -static int are_detach(device_t); -static int are_ifmedia_upd(struct ifnet *); -static void are_ifmedia_sts(struct ifnet *, struct ifmediareq *); -static int are_ioctl(struct ifnet *, u_long, caddr_t); -static void are_init(void *); -static void are_init_locked(struct are_softc *); -static void are_link_task(void *, int); -static int are_miibus_readreg(device_t, int, int); -static void are_miibus_statchg(device_t); -static int are_miibus_writereg(device_t, int, int, int); -static int are_probe(device_t); -static void are_reset(struct are_softc *); -static int are_resume(device_t); -static int are_rx_ring_init(struct are_softc *); -static int are_tx_ring_init(struct are_softc *); -static int are_shutdown(device_t); -static void are_start(struct ifnet *); -static void are_start_locked(struct ifnet *); -static void are_stop(struct are_softc *); -static int are_suspend(device_t); - -static void are_rx(struct are_softc *); -static void are_tx(struct are_softc *); -static void are_intr(void *); -static void are_tick(void *); - -static void are_dmamap_cb(void *, bus_dma_segment_t *, int, int); -static int are_dma_alloc(struct are_softc *); -static void are_dma_free(struct are_softc *); -static int are_newbuf(struct are_softc *, int); -static __inline void are_fixup_rx(struct mbuf *); - -static void are_hinted_child(device_t bus, const char *dname, int dunit); - -static device_method_t are_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, are_probe), - DEVMETHOD(device_attach, are_attach), - DEVMETHOD(device_detach, are_detach), - DEVMETHOD(device_suspend, are_suspend), - DEVMETHOD(device_resume, are_resume), - DEVMETHOD(device_shutdown, are_shutdown), - - /* MII interface */ - DEVMETHOD(miibus_readreg, are_miibus_readreg), - DEVMETHOD(miibus_writereg, are_miibus_writereg), - DEVMETHOD(miibus_statchg, are_miibus_statchg), - - /* bus interface */ - DEVMETHOD(bus_add_child, device_add_child_ordered), - DEVMETHOD(bus_hinted_child, are_hinted_child), - - DEVMETHOD_END -}; - -static driver_t are_driver = { - "are", - are_methods, - sizeof(struct are_softc) -}; - -static devclass_t are_devclass; - -DRIVER_MODULE(are, nexus, are_driver, are_devclass, 0, 0); -#ifdef ARE_MII -DRIVER_MODULE(miibus, are, miibus_driver, miibus_devclass, 0, 0); -#endif - -#ifdef ARE_MDIO -static int aremdio_probe(device_t); -static int aremdio_attach(device_t); -static int aremdio_detach(device_t); - -/* - * Declare an additional, separate driver for accessing the MDIO bus. - */ -static device_method_t aremdio_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, aremdio_probe), - DEVMETHOD(device_attach, aremdio_attach), - DEVMETHOD(device_detach, aremdio_detach), - - /* bus interface */ - DEVMETHOD(bus_add_child, device_add_child_ordered), - - /* MDIO access */ - DEVMETHOD(mdio_readreg, are_miibus_readreg), - DEVMETHOD(mdio_writereg, are_miibus_writereg), -}; - -DEFINE_CLASS_0(aremdio, aremdio_driver, aremdio_methods, - sizeof(struct are_softc)); -static devclass_t aremdio_devclass; - -DRIVER_MODULE(miiproxy, are, miiproxy_driver, miiproxy_devclass, 0, 0); -DRIVER_MODULE(aremdio, nexus, aremdio_driver, aremdio_devclass, 0, 0); -DRIVER_MODULE(mdio, aremdio, mdio_driver, mdio_devclass, 0, 0); -#endif - - -static int -are_probe(device_t dev) -{ - - device_set_desc(dev, "AR531x Ethernet interface"); - return (0); -} - -static int -are_attach(device_t dev) -{ - struct ifnet *ifp; - struct are_softc *sc; - int error = 0; -#ifdef INTRNG - int enetirq; -#else - int rid; -#endif - int unit; - char * local_macstr; - int count; - int i; - - sc = device_get_softc(dev); - unit = device_get_unit(dev); - sc->are_dev = dev; - - /* hardcode macaddress */ - sc->are_eaddr[0] = 0x00; - sc->are_eaddr[1] = 0x0C; - sc->are_eaddr[2] = 0x42; - sc->are_eaddr[3] = 0x09; - sc->are_eaddr[4] = 0x5E; - sc->are_eaddr[5] = 0x6B; - - /* try to get from hints */ - if (!resource_string_value(device_get_name(dev), - device_get_unit(dev), "macaddr", (const char **)&local_macstr)) { - uint32_t tmpmac[ETHER_ADDR_LEN]; - - /* Have a MAC address; should use it */ - device_printf(dev, "Overriding MAC address from environment: '%s'\n", - local_macstr); - - /* Extract out the MAC address */ - /* XXX this should all be a generic method */ - count = sscanf(local_macstr, "%x%*c%x%*c%x%*c%x%*c%x%*c%x", - &tmpmac[0], &tmpmac[1], - &tmpmac[2], &tmpmac[3], - &tmpmac[4], &tmpmac[5]); - if (count == 6) { - /* Valid! */ - for (i = 0; i < ETHER_ADDR_LEN; i++) - sc->are_eaddr[i] = tmpmac[i]; - } - } - - mtx_init(&sc->are_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, - MTX_DEF); - callout_init_mtx(&sc->are_stat_callout, &sc->are_mtx, 0); - TASK_INIT(&sc->are_link_task, 0, are_link_task, sc); - - /* Map control/status registers. */ - sc->are_rid = 0; - sc->are_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->are_rid, - RF_ACTIVE | RF_SHAREABLE); - - if (sc->are_res == NULL) { - device_printf(dev, "couldn't map memory\n"); - error = ENXIO; - goto fail; - } - - sc->are_btag = rman_get_bustag(sc->are_res); - sc->are_bhandle = rman_get_bushandle(sc->are_res); - -#ifndef INTRNG - /* Allocate interrupts */ - rid = 0; - sc->are_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_SHAREABLE | RF_ACTIVE); - - if (sc->are_irq == NULL) { - device_printf(dev, "couldn't map interrupt\n"); - error = ENXIO; - goto fail; - } -#endif - - /* Allocate ifnet structure. */ - ifp = sc->are_ifp = if_alloc(IFT_ETHER); - - if (ifp == NULL) { - device_printf(dev, "couldn't allocate ifnet structure\n"); - error = ENOSPC; - goto fail; - } - 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_ioctl = are_ioctl; - ifp->if_start = are_start; - ifp->if_init = are_init; - sc->are_if_flags = ifp->if_flags; - - /* ifqmaxlen is sysctl value in net/if.c */ - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - /* Tell the upper layer(s) we support long frames. */ - ifp->if_capabilities |= IFCAP_VLAN_MTU; - - ifp->if_capenable = ifp->if_capabilities; - - if (are_dma_alloc(sc) != 0) { - error = ENXIO; - goto fail; - } - - CSR_WRITE_4(sc, CSR_BUSMODE, BUSMODE_SWR); - DELAY(1000); - -#ifdef ARE_MDIO - sc->are_miiproxy = mii_attach_proxy(sc->are_dev); -#endif - -#ifdef ARE_MII - /* Do MII setup. */ - error = mii_attach(dev, &sc->are_miibus, ifp, are_ifmedia_upd, - are_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0); - if (error != 0) { - device_printf(dev, "attaching PHYs failed\n"); - goto fail; - } -#else - ifmedia_init(&sc->are_ifmedia, 0, are_ifmedia_upd, are_ifmedia_sts); - - ifmedia_add(&sc->are_ifmedia, IFM_ETHER | IFM_AUTO, 0, NULL); - ifmedia_set(&sc->are_ifmedia, IFM_ETHER | IFM_AUTO); -#endif - - /* Call MI attach routine. */ - ether_ifattach(ifp, sc->are_eaddr); - -#ifdef INTRNG - char *name; - if (ar531x_soc >= AR531X_SOC_AR5315) { - enetirq = AR5315_CPU_IRQ_ENET; - name = "enet"; - } else { - if (device_get_unit(dev) == 0) { - enetirq = AR5312_IRQ_ENET0; - name = "enet0"; - } else { - enetirq = AR5312_IRQ_ENET1; - name = "enet1"; - } - } - cpu_establish_hardintr(name, NULL, are_intr, sc, enetirq, - INTR_TYPE_NET, NULL); -#else - /* Hook interrupt last to avoid having to lock softc */ - error = bus_setup_intr(dev, sc->are_irq, INTR_TYPE_NET | INTR_MPSAFE, - NULL, are_intr, sc, &sc->are_intrhand); - - if (error) { - device_printf(dev, "couldn't set up irq\n"); - ether_ifdetach(ifp); - goto fail; - } -#endif - -fail: - if (error) - are_detach(dev); - - return (error); -} - -static int -are_detach(device_t dev) -{ - struct are_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->are_ifp; - - KASSERT(mtx_initialized(&sc->are_mtx), ("vr mutex not initialized")); - - /* These should only be active if attach succeeded */ - if (device_is_attached(dev)) { - ARE_LOCK(sc); - sc->are_detach = 1; - are_stop(sc); - ARE_UNLOCK(sc); - taskqueue_drain(taskqueue_swi, &sc->are_link_task); - ether_ifdetach(ifp); - } -#ifdef ARE_MII - if (sc->are_miibus) - device_delete_child(dev, sc->are_miibus); -#endif - bus_generic_detach(dev); - - if (sc->are_intrhand) - bus_teardown_intr(dev, sc->are_irq, sc->are_intrhand); - if (sc->are_irq) - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->are_irq); - - if (sc->are_res) - bus_release_resource(dev, SYS_RES_MEMORY, sc->are_rid, - sc->are_res); - - if (ifp) - if_free(ifp); - - are_dma_free(sc); - - mtx_destroy(&sc->are_mtx); - - return (0); - -} - -static int -are_suspend(device_t dev) -{ - - panic("%s", __func__); - return 0; -} - -static int -are_resume(device_t dev) -{ - - panic("%s", __func__); - return 0; -} - -static int -are_shutdown(device_t dev) -{ - struct are_softc *sc; - - sc = device_get_softc(dev); - - ARE_LOCK(sc); - are_stop(sc); - ARE_UNLOCK(sc); - - return (0); -} - -static int -are_miibus_readreg(device_t dev, int phy, int reg) -{ - struct are_softc * sc = device_get_softc(dev); - uint32_t addr; - int i; - - addr = (phy << MIIADDR_PHY_SHIFT) | (reg << MIIADDR_REG_SHIFT); - CSR_WRITE_4(sc, CSR_MIIADDR, addr); - for (i = 0; i < 100000000; i++) { - if ((CSR_READ_4(sc, CSR_MIIADDR) & MIIADDR_BUSY) == 0) - break; - } - - return (CSR_READ_4(sc, CSR_MIIDATA) & 0xffff); -} - -static int -are_miibus_writereg(device_t dev, int phy, int reg, int data) -{ - struct are_softc * sc = device_get_softc(dev); - uint32_t addr; - int i; - - /* write the data register */ - CSR_WRITE_4(sc, CSR_MIIDATA, data); - - /* write the address to latch it in */ - addr = (phy << MIIADDR_PHY_SHIFT) | (reg << MIIADDR_REG_SHIFT) | - MIIADDR_WRITE; - CSR_WRITE_4(sc, CSR_MIIADDR, addr); - - for (i = 0; i < 100000000; i++) { - if ((CSR_READ_4(sc, CSR_MIIADDR) & MIIADDR_BUSY) == 0) - break; - } - - return (0); -} - -static void -are_miibus_statchg(device_t dev) -{ - struct are_softc *sc; - - sc = device_get_softc(dev); - taskqueue_enqueue(taskqueue_swi, &sc->are_link_task); -} - -static void -are_link_task(void *arg, int pending) -{ -#ifdef ARE_MII - struct are_softc *sc; - struct mii_data *mii; - struct ifnet *ifp; - /* int lfdx, mfdx; */ - - sc = (struct are_softc *)arg; - - ARE_LOCK(sc); - mii = device_get_softc(sc->are_miibus); - ifp = sc->are_ifp; - if (mii == NULL || ifp == NULL || - (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - ARE_UNLOCK(sc); - return; - } - - if (mii->mii_media_status & IFM_ACTIVE) { - if (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) - sc->are_link_status = 1; - } else - sc->are_link_status = 0; - - ARE_UNLOCK(sc); -#endif -} - -static void -are_reset(struct are_softc *sc) -{ - int i; - - CSR_WRITE_4(sc, CSR_BUSMODE, BUSMODE_SWR); - - /* - * The chip doesn't take itself out of reset automatically. - * We need to do so after 2us. - */ - DELAY(10); - CSR_WRITE_4(sc, CSR_BUSMODE, 0); - - for (i = 0; i < 1000; i++) { - /* - * Wait a bit for the reset to complete before peeking - * at the chip again. - */ - DELAY(10); - if ((CSR_READ_4(sc, CSR_BUSMODE) & BUSMODE_SWR) == 0) - break; - } - - if (CSR_READ_4(sc, CSR_BUSMODE) & BUSMODE_SWR) - device_printf(sc->are_dev, "reset time out\n"); - - DELAY(1000); -} - -static void -are_init(void *xsc) -{ - struct are_softc *sc = xsc; - - ARE_LOCK(sc); - are_init_locked(sc); - ARE_UNLOCK(sc); -} - -static void -are_init_locked(struct are_softc *sc) -{ - struct ifnet *ifp = sc->are_ifp; -#ifdef ARE_MII - struct mii_data *mii; -#endif - - ARE_LOCK_ASSERT(sc); - -#ifdef ARE_MII - mii = device_get_softc(sc->are_miibus); -#endif - - are_stop(sc); - are_reset(sc); - - /* Init circular RX list. */ - if (are_rx_ring_init(sc) != 0) { - device_printf(sc->are_dev, - "initialization failed: no memory for rx buffers\n"); - are_stop(sc); - return; - } - - /* Init tx descriptors. */ - are_tx_ring_init(sc); - - /* - * Initialize the BUSMODE register. - */ - CSR_WRITE_4(sc, CSR_BUSMODE, - /* XXX: not sure if this is a good thing or not... */ - BUSMODE_BAR | BUSMODE_BLE | BUSMODE_PBL_4LW); - - /* - * Initialize the interrupt mask and enable interrupts. - */ - /* normal interrupts */ - sc->sc_inten = STATUS_TI | STATUS_TU | STATUS_RI | STATUS_NIS; - - /* abnormal interrupts */ - sc->sc_inten |= STATUS_TPS | STATUS_TJT | STATUS_UNF | - STATUS_RU | STATUS_RPS | STATUS_SE | STATUS_AIS; - - sc->sc_rxint_mask = STATUS_RI|STATUS_RU; - sc->sc_txint_mask = STATUS_TI|STATUS_UNF|STATUS_TJT; - - sc->sc_rxint_mask &= sc->sc_inten; - sc->sc_txint_mask &= sc->sc_inten; - - CSR_WRITE_4(sc, CSR_INTEN, sc->sc_inten); - CSR_WRITE_4(sc, CSR_STATUS, 0xffffffff); - - /* - * Give the transmit and receive rings to the chip. - */ - CSR_WRITE_4(sc, CSR_TXLIST, ARE_TX_RING_ADDR(sc, 0)); - CSR_WRITE_4(sc, CSR_RXLIST, ARE_RX_RING_ADDR(sc, 0)); - - /* - * Set the station address. - */ - CSR_WRITE_4(sc, CSR_MACHI, sc->are_eaddr[5] << 16 | sc->are_eaddr[4]); - CSR_WRITE_4(sc, CSR_MACLO, sc->are_eaddr[3] << 24 | - sc->are_eaddr[2] << 16 | sc->are_eaddr[1] << 8 | sc->are_eaddr[0]); - - /* - * Start the mac. - */ - CSR_WRITE_4(sc, CSR_FLOWC, FLOWC_FCE); - CSR_WRITE_4(sc, CSR_MACCTL, MACCTL_RE | MACCTL_TE | - MACCTL_PM | MACCTL_FDX | MACCTL_HBD | MACCTL_RA); - - /* - * Write out the opmode. - */ - CSR_WRITE_4(sc, CSR_OPMODE, OPMODE_SR | OPMODE_ST | OPMODE_SF | - OPMODE_TR_64); - - /* - * Start the receive process. - */ - CSR_WRITE_4(sc, CSR_RXPOLL, RXPOLL_RPD); - - sc->are_link_status = 1; -#ifdef ARE_MII - mii_mediachg(mii); -#endif - - ifp->if_drv_flags |= IFF_DRV_RUNNING; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - - callout_reset(&sc->are_stat_callout, hz, are_tick, sc); -} - -static void -are_start(struct ifnet *ifp) -{ - struct are_softc *sc; - - sc = ifp->if_softc; - - ARE_LOCK(sc); - are_start_locked(ifp); - ARE_UNLOCK(sc); -} - -/* - * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data - * pointers to the fragment pointers. - */ -static int -are_encap(struct are_softc *sc, struct mbuf **m_head) -{ - struct are_txdesc *txd; - struct are_desc *desc, *prev_desc; - struct mbuf *m; - bus_dma_segment_t txsegs[ARE_MAXFRAGS]; - uint32_t link_addr; - int error, i, nsegs, prod, si, prev_prod; - int txstat; - int startcount; - int padlen; - - startcount = sc->are_cdata.are_tx_cnt; - - ARE_LOCK_ASSERT(sc); - - /* - * Some VIA Rhine wants packet buffers to be longword - * aligned, but very often our mbufs aren't. Rather than - * waste time trying to decide when to copy and when not - * to copy, just do it all the time. - */ - m = m_defrag(*m_head, M_NOWAIT); - if (m == NULL) { - device_printf(sc->are_dev, "are_encap m_defrag error\n"); - m_freem(*m_head); - *m_head = NULL; - return (ENOBUFS); - } - *m_head = m; - - /* - * The Rhine chip doesn't auto-pad, so we have to make - * sure to pad short frames out to the minimum frame length - * ourselves. - */ - if ((*m_head)->m_pkthdr.len < ARE_MIN_FRAMELEN) { - m = *m_head; - padlen = ARE_MIN_FRAMELEN - m->m_pkthdr.len; - if (M_WRITABLE(m) == 0) { - /* Get a writable copy. */ - m = m_dup(*m_head, M_NOWAIT); - m_freem(*m_head); - if (m == NULL) { - device_printf(sc->are_dev, "are_encap m_dup error\n"); - *m_head = NULL; - return (ENOBUFS); - } - *m_head = m; - } - if (m->m_next != NULL || M_TRAILINGSPACE(m) < padlen) { - m = m_defrag(m, M_NOWAIT); - if (m == NULL) { - device_printf(sc->are_dev, "are_encap m_defrag error\n"); - m_freem(*m_head); - *m_head = NULL; - return (ENOBUFS); - } - } - /* - * Manually pad short frames, and zero the pad space - * to avoid leaking data. - */ - bzero(mtod(m, char *) + m->m_pkthdr.len, padlen); - m->m_pkthdr.len += padlen; - m->m_len = m->m_pkthdr.len; - *m_head = m; - } - - prod = sc->are_cdata.are_tx_prod; - txd = &sc->are_cdata.are_txdesc[prod]; - error = bus_dmamap_load_mbuf_sg(sc->are_cdata.are_tx_tag, - txd->tx_dmamap, *m_head, txsegs, &nsegs, BUS_DMA_NOWAIT); - if (error == EFBIG) { - device_printf(sc->are_dev, "are_encap EFBIG error\n"); - m = m_defrag(*m_head, M_NOWAIT); - if (m == NULL) { - m_freem(*m_head); - *m_head = NULL; - return (ENOBUFS); - } - *m_head = m; - error = bus_dmamap_load_mbuf_sg(sc->are_cdata.are_tx_tag, - txd->tx_dmamap, *m_head, txsegs, &nsegs, BUS_DMA_NOWAIT); - if (error != 0) { - m_freem(*m_head); - *m_head = NULL; - return (error); - } - - } else if (error != 0) - return (error); - if (nsegs == 0) { - m_freem(*m_head); - *m_head = NULL; - return (EIO); - } - - /* Check number of available descriptors. */ - if (sc->are_cdata.are_tx_cnt + nsegs >= (ARE_TX_RING_CNT - 1)) { - bus_dmamap_unload(sc->are_cdata.are_tx_tag, txd->tx_dmamap); - return (ENOBUFS); - } - - txd->tx_m = *m_head; - bus_dmamap_sync(sc->are_cdata.are_tx_tag, txd->tx_dmamap, - BUS_DMASYNC_PREWRITE); - - si = prod; - - /* - * Make a list of descriptors for this packet. DMA controller will - * walk through it while are_link is not zero. The last one should - * have COF flag set, to pickup next chain from NDPTR - */ - prev_prod = prod; - desc = prev_desc = NULL; - for (i = 0; i < nsegs; i++) { - desc = &sc->are_rdata.are_tx_ring[prod]; - desc->are_stat = ADSTAT_OWN; - desc->are_devcs = ARE_DMASIZE(txsegs[i].ds_len); - desc->are_addr = txsegs[i].ds_addr; - /* link with previous descriptor */ - /* end of descriptor */ - if (prod == ARE_TX_RING_CNT - 1) - desc->are_devcs |= ADCTL_ER; - - sc->are_cdata.are_tx_cnt++; - prev_desc = desc; - ARE_INC(prod, ARE_TX_RING_CNT); - } - - /* - * Set mark last fragment with LD flag - */ - if (desc) { - desc->are_devcs |= ADCTL_Tx_IC; - desc->are_devcs |= ADCTL_Tx_LS; - } - - /* Update producer index. */ - sc->are_cdata.are_tx_prod = prod; - - /* Sync descriptors. */ - bus_dmamap_sync(sc->are_cdata.are_tx_ring_tag, - sc->are_cdata.are_tx_ring_map, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - - /* Start transmitting */ - /* Check if new list is queued in NDPTR */ - txstat = (CSR_READ_4(sc, CSR_STATUS) >> 20) & 7; - if (startcount == 0 && (txstat == 0 || txstat == 6)) { - desc = &sc->are_rdata.are_tx_ring[si]; - desc->are_devcs |= ADCTL_Tx_FS; - } - else { - link_addr = ARE_TX_RING_ADDR(sc, si); - /* Get previous descriptor */ - si = (si + ARE_TX_RING_CNT - 1) % ARE_TX_RING_CNT; - desc = &sc->are_rdata.are_tx_ring[si]; - desc->are_devcs &= ~(ADCTL_Tx_IC | ADCTL_Tx_LS); - } - - return (0); -} - -static void -are_start_locked(struct ifnet *ifp) -{ - struct are_softc *sc; - struct mbuf *m_head; - int enq; - int txstat; - - sc = ifp->if_softc; - - ARE_LOCK_ASSERT(sc); - - if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != - IFF_DRV_RUNNING || sc->are_link_status == 0 ) - return; - - for (enq = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) && - sc->are_cdata.are_tx_cnt < ARE_TX_RING_CNT - 2; ) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); - if (m_head == NULL) - break; - /* - * Pack the data into the transmit ring. If we - * don't have room, set the OACTIVE flag and wait - * for the NIC to drain the ring. - */ - if (are_encap(sc, &m_head)) { - if (m_head == NULL) - break; - IFQ_DRV_PREPEND(&ifp->if_snd, m_head); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - - enq++; - /* - * If there's a BPF listener, bounce a copy of this frame - * to him. - */ - ETHER_BPF_MTAP(ifp, m_head); - } - - if (enq > 0) { - txstat = (CSR_READ_4(sc, CSR_STATUS) >> 20) & 7; - if (txstat == 0 || txstat == 6) { - /* Transmit Process Stat is stop or suspended */ - CSR_WRITE_4(sc, CSR_TXPOLL, TXPOLL_TPD); - } - } -} - -static void -are_stop(struct are_softc *sc) -{ - struct ifnet *ifp; - - ARE_LOCK_ASSERT(sc); - - ifp = sc->are_ifp; - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - callout_stop(&sc->are_stat_callout); - - /* Disable interrupts. */ - CSR_WRITE_4(sc, CSR_INTEN, 0); - - /* Stop the transmit and receive processes. */ - CSR_WRITE_4(sc, CSR_OPMODE, 0); - CSR_WRITE_4(sc, CSR_RXLIST, 0); - CSR_WRITE_4(sc, CSR_TXLIST, 0); - CSR_WRITE_4(sc, CSR_MACCTL, - CSR_READ_4(sc, CSR_MACCTL) & ~(MACCTL_TE | MACCTL_RE)); - -} - -static int -are_set_filter(struct are_softc *sc) -{ - struct ifnet *ifp; - int mchash[2]; - int macctl; - - ifp = sc->are_ifp; - - macctl = CSR_READ_4(sc, CSR_MACCTL); - macctl &= ~(MACCTL_PR | MACCTL_PM); - macctl |= MACCTL_HBD; - - if (ifp->if_flags & IFF_PROMISC) - macctl |= MACCTL_PR; - - /* Todo: hash table set. - * But I don't know how to use multicast hash table at this soc. - */ - - /* this is allmulti */ - mchash[0] = mchash[1] = 0xffffffff; - macctl |= MACCTL_PM; - - CSR_WRITE_4(sc, CSR_HTLO, mchash[0]); - CSR_WRITE_4(sc, CSR_HTHI, mchash[1]); - CSR_WRITE_4(sc, CSR_MACCTL, macctl); - - return 0; -} - -static int -are_ioctl(struct ifnet *ifp, u_long command, caddr_t data) -{ - struct are_softc *sc = ifp->if_softc; - struct ifreq *ifr = (struct ifreq *) data; -#ifdef ARE_MII - struct mii_data *mii; -#endif - int error; - - switch (command) { - case SIOCSIFFLAGS: - ARE_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - if ((ifp->if_flags ^ sc->are_if_flags) & - (IFF_PROMISC | IFF_ALLMULTI)) - are_set_filter(sc); - } else { - if (sc->are_detach == 0) - are_init_locked(sc); - } - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - are_stop(sc); - } - sc->are_if_flags = ifp->if_flags; - ARE_UNLOCK(sc); - error = 0; - break; - case SIOCADDMULTI: - case SIOCDELMULTI: - ARE_LOCK(sc); - are_set_filter(sc); - ARE_UNLOCK(sc); - error = 0; - break; - case SIOCGIFMEDIA: - case SIOCSIFMEDIA: -#ifdef ARE_MII - mii = device_get_softc(sc->are_miibus); - error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); -#else - error = ifmedia_ioctl(ifp, ifr, &sc->are_ifmedia, command); -#endif - break; - case SIOCSIFCAP: - error = 0; - break; - default: - error = ether_ioctl(ifp, command, data); - break; - } - - return (error); -} - -/* - * Set media options. - */ -static int -are_ifmedia_upd(struct ifnet *ifp) -{ -#ifdef ARE_MII - struct are_softc *sc; - struct mii_data *mii; - struct mii_softc *miisc; - int error; - - sc = ifp->if_softc; - ARE_LOCK(sc); - mii = device_get_softc(sc->are_miibus); - LIST_FOREACH(miisc, &mii->mii_phys, mii_list) - PHY_RESET(miisc); - error = mii_mediachg(mii); - ARE_UNLOCK(sc); - - return (error); -#else - return (0); -#endif -} - -/* - * Report current media status. - */ -static void -are_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) -{ -#ifdef ARE_MII - struct are_softc *sc = ifp->if_softc; - struct mii_data *mii; - - mii = device_get_softc(sc->are_miibus); - ARE_LOCK(sc); - mii_pollstat(mii); - ifmr->ifm_active = mii->mii_media_active; - ifmr->ifm_status = mii->mii_media_status; - ARE_UNLOCK(sc); -#else - ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE; -#endif -} - -struct are_dmamap_arg { - bus_addr_t are_busaddr; -}; - -static void -are_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) -{ - struct are_dmamap_arg *ctx; - - if (error != 0) - return; - ctx = arg; - ctx->are_busaddr = segs[0].ds_addr; -} - -static int -are_dma_alloc(struct are_softc *sc) -{ - struct are_dmamap_arg ctx; - struct are_txdesc *txd; - struct are_rxdesc *rxd; - int error, i; - - /* Create parent DMA tag. */ - error = bus_dma_tag_create( - bus_get_dma_tag(sc->are_dev), /* parent */ - 1, 0, /* alignment, boundary */ - BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filter, filterarg */ - BUS_SPACE_MAXSIZE_32BIT, /* maxsize */ - 0, /* nsegments */ - BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ - 0, /* flags */ - NULL, NULL, /* lockfunc, lockarg */ - &sc->are_cdata.are_parent_tag); - if (error != 0) { - device_printf(sc->are_dev, "failed to create parent DMA tag\n"); - goto fail; - } - /* Create tag for Tx ring. */ - error = bus_dma_tag_create( - sc->are_cdata.are_parent_tag, /* parent */ - ARE_RING_ALIGN, 0, /* alignment, boundary */ - BUS_SPACE_MAXADDR, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filter, filterarg */ - ARE_TX_RING_SIZE, /* maxsize */ - 1, /* nsegments */ - ARE_TX_RING_SIZE, /* maxsegsize */ - 0, /* flags */ - NULL, NULL, /* lockfunc, lockarg */ - &sc->are_cdata.are_tx_ring_tag); - if (error != 0) { - device_printf(sc->are_dev, "failed to create Tx ring DMA tag\n"); - goto fail; - } - - /* Create tag for Rx ring. */ - error = bus_dma_tag_create( - sc->are_cdata.are_parent_tag, /* parent */ - ARE_RING_ALIGN, 0, /* alignment, boundary */ - BUS_SPACE_MAXADDR, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filter, filterarg */ - ARE_RX_RING_SIZE, /* maxsize */ - 1, /* nsegments */ - ARE_RX_RING_SIZE, /* maxsegsize */ - 0, /* flags */ - NULL, NULL, /* lockfunc, lockarg */ - &sc->are_cdata.are_rx_ring_tag); - if (error != 0) { - device_printf(sc->are_dev, "failed to create Rx ring DMA tag\n"); - goto fail; - } - - /* Create tag for Tx buffers. */ - error = bus_dma_tag_create( - sc->are_cdata.are_parent_tag, /* parent */ - sizeof(uint32_t), 0, /* alignment, boundary */ - BUS_SPACE_MAXADDR, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filter, filterarg */ - MCLBYTES * ARE_MAXFRAGS, /* maxsize */ - ARE_MAXFRAGS, /* nsegments */ - MCLBYTES, /* maxsegsize */ - 0, /* flags */ - NULL, NULL, /* lockfunc, lockarg */ - &sc->are_cdata.are_tx_tag); - if (error != 0) { - device_printf(sc->are_dev, "failed to create Tx DMA tag\n"); - goto fail; - } - - /* Create tag for Rx buffers. */ - error = bus_dma_tag_create( - sc->are_cdata.are_parent_tag, /* parent */ - ARE_RX_ALIGN, 0, /* alignment, boundary */ - BUS_SPACE_MAXADDR, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filter, filterarg */ - MCLBYTES, /* maxsize */ - 1, /* nsegments */ - MCLBYTES, /* maxsegsize */ - 0, /* flags */ - NULL, NULL, /* lockfunc, lockarg */ - &sc->are_cdata.are_rx_tag); - if (error != 0) { - device_printf(sc->are_dev, "failed to create Rx DMA tag\n"); - goto fail; - } - - /* Allocate DMA'able memory and load the DMA map for Tx ring. */ - error = bus_dmamem_alloc(sc->are_cdata.are_tx_ring_tag, - (void **)&sc->are_rdata.are_tx_ring, BUS_DMA_WAITOK | - BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->are_cdata.are_tx_ring_map); - if (error != 0) { - device_printf(sc->are_dev, - "failed to allocate DMA'able memory for Tx ring\n"); - goto fail; - } - - ctx.are_busaddr = 0; - error = bus_dmamap_load(sc->are_cdata.are_tx_ring_tag, - sc->are_cdata.are_tx_ring_map, sc->are_rdata.are_tx_ring, - ARE_TX_RING_SIZE, are_dmamap_cb, &ctx, 0); - if (error != 0 || ctx.are_busaddr == 0) { - device_printf(sc->are_dev, - "failed to load DMA'able memory for Tx ring\n"); - goto fail; - } - sc->are_rdata.are_tx_ring_paddr = ctx.are_busaddr; - - /* Allocate DMA'able memory and load the DMA map for Rx ring. */ - error = bus_dmamem_alloc(sc->are_cdata.are_rx_ring_tag, - (void **)&sc->are_rdata.are_rx_ring, BUS_DMA_WAITOK | - BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->are_cdata.are_rx_ring_map); - if (error != 0) { - device_printf(sc->are_dev, - "failed to allocate DMA'able memory for Rx ring\n"); - goto fail; - } - - ctx.are_busaddr = 0; - error = bus_dmamap_load(sc->are_cdata.are_rx_ring_tag, - sc->are_cdata.are_rx_ring_map, sc->are_rdata.are_rx_ring, - ARE_RX_RING_SIZE, are_dmamap_cb, &ctx, 0); - if (error != 0 || ctx.are_busaddr == 0) { - device_printf(sc->are_dev, - "failed to load DMA'able memory for Rx ring\n"); - goto fail; - } - sc->are_rdata.are_rx_ring_paddr = ctx.are_busaddr; - - /* Create DMA maps for Tx buffers. */ - for (i = 0; i < ARE_TX_RING_CNT; i++) { - txd = &sc->are_cdata.are_txdesc[i]; - txd->tx_m = NULL; - txd->tx_dmamap = NULL; - error = bus_dmamap_create(sc->are_cdata.are_tx_tag, 0, - &txd->tx_dmamap); - if (error != 0) { - device_printf(sc->are_dev, - "failed to create Tx dmamap\n"); - goto fail; - } - } - /* Create DMA maps for Rx buffers. */ - if ((error = bus_dmamap_create(sc->are_cdata.are_rx_tag, 0, - &sc->are_cdata.are_rx_sparemap)) != 0) { - device_printf(sc->are_dev, - "failed to create spare Rx dmamap\n"); - goto fail; - } - for (i = 0; i < ARE_RX_RING_CNT; i++) { - rxd = &sc->are_cdata.are_rxdesc[i]; - rxd->rx_m = NULL; - rxd->rx_dmamap = NULL; - error = bus_dmamap_create(sc->are_cdata.are_rx_tag, 0, - &rxd->rx_dmamap); - if (error != 0) { - device_printf(sc->are_dev, - "failed to create Rx dmamap\n"); - goto fail; - } - } - -fail: - return (error); -} - -static void -are_dma_free(struct are_softc *sc) -{ - struct are_txdesc *txd; - struct are_rxdesc *rxd; - int i; - - /* Tx ring. */ - if (sc->are_cdata.are_tx_ring_tag) { - if (sc->are_rdata.are_tx_ring_paddr) - bus_dmamap_unload(sc->are_cdata.are_tx_ring_tag, - sc->are_cdata.are_tx_ring_map); - if (sc->are_rdata.are_tx_ring) - bus_dmamem_free(sc->are_cdata.are_tx_ring_tag, - sc->are_rdata.are_tx_ring, - sc->are_cdata.are_tx_ring_map); - sc->are_rdata.are_tx_ring = NULL; - sc->are_rdata.are_tx_ring_paddr = 0; - bus_dma_tag_destroy(sc->are_cdata.are_tx_ring_tag); - sc->are_cdata.are_tx_ring_tag = NULL; - } - /* Rx ring. */ - if (sc->are_cdata.are_rx_ring_tag) { - if (sc->are_rdata.are_rx_ring_paddr) - bus_dmamap_unload(sc->are_cdata.are_rx_ring_tag, - sc->are_cdata.are_rx_ring_map); - if (sc->are_rdata.are_rx_ring) - bus_dmamem_free(sc->are_cdata.are_rx_ring_tag, - sc->are_rdata.are_rx_ring, - sc->are_cdata.are_rx_ring_map); - sc->are_rdata.are_rx_ring = NULL; - sc->are_rdata.are_rx_ring_paddr = 0; - bus_dma_tag_destroy(sc->are_cdata.are_rx_ring_tag); - sc->are_cdata.are_rx_ring_tag = NULL; - } - /* Tx buffers. */ - if (sc->are_cdata.are_tx_tag) { - for (i = 0; i < ARE_TX_RING_CNT; i++) { - txd = &sc->are_cdata.are_txdesc[i]; - if (txd->tx_dmamap) { - bus_dmamap_destroy(sc->are_cdata.are_tx_tag, - txd->tx_dmamap); - txd->tx_dmamap = NULL; - } - } - bus_dma_tag_destroy(sc->are_cdata.are_tx_tag); - sc->are_cdata.are_tx_tag = NULL; - } - /* Rx buffers. */ - if (sc->are_cdata.are_rx_tag) { - for (i = 0; i < ARE_RX_RING_CNT; i++) { - rxd = &sc->are_cdata.are_rxdesc[i]; - if (rxd->rx_dmamap) { - bus_dmamap_destroy(sc->are_cdata.are_rx_tag, - rxd->rx_dmamap); - rxd->rx_dmamap = NULL; - } - } - if (sc->are_cdata.are_rx_sparemap) { - bus_dmamap_destroy(sc->are_cdata.are_rx_tag, - sc->are_cdata.are_rx_sparemap); - sc->are_cdata.are_rx_sparemap = 0; - } - bus_dma_tag_destroy(sc->are_cdata.are_rx_tag); - sc->are_cdata.are_rx_tag = NULL; - } - - if (sc->are_cdata.are_parent_tag) { - bus_dma_tag_destroy(sc->are_cdata.are_parent_tag); - sc->are_cdata.are_parent_tag = NULL; - } -} - -/* - * Initialize the transmit descriptors. - */ -static int -are_tx_ring_init(struct are_softc *sc) -{ - struct are_ring_data *rd; - struct are_txdesc *txd; - bus_addr_t addr; - int i; - - sc->are_cdata.are_tx_prod = 0; - sc->are_cdata.are_tx_cons = 0; - sc->are_cdata.are_tx_cnt = 0; - sc->are_cdata.are_tx_pkts = 0; - - rd = &sc->are_rdata; - bzero(rd->are_tx_ring, ARE_TX_RING_SIZE); - for (i = 0; i < ARE_TX_RING_CNT; i++) { - if (i == ARE_TX_RING_CNT - 1) - addr = ARE_TX_RING_ADDR(sc, 0); - else - addr = ARE_TX_RING_ADDR(sc, i + 1); - rd->are_tx_ring[i].are_stat = 0; - rd->are_tx_ring[i].are_devcs = 0; - rd->are_tx_ring[i].are_addr = 0; - rd->are_tx_ring[i].are_link = addr; - txd = &sc->are_cdata.are_txdesc[i]; - txd->tx_m = NULL; - } - - bus_dmamap_sync(sc->are_cdata.are_tx_ring_tag, - sc->are_cdata.are_tx_ring_map, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - - return (0); -} - -/* - * Initialize the RX descriptors and allocate mbufs for them. Note that - * we arrange the descriptors in a closed ring, so that the last descriptor - * points back to the first. - */ -static int -are_rx_ring_init(struct are_softc *sc) -{ - struct are_ring_data *rd; - struct are_rxdesc *rxd; - bus_addr_t addr; - int i; - - sc->are_cdata.are_rx_cons = 0; - - rd = &sc->are_rdata; - bzero(rd->are_rx_ring, ARE_RX_RING_SIZE); - for (i = 0; i < ARE_RX_RING_CNT; i++) { - rxd = &sc->are_cdata.are_rxdesc[i]; - rxd->rx_m = NULL; - rxd->desc = &rd->are_rx_ring[i]; - if (i == ARE_RX_RING_CNT - 1) - addr = ARE_RX_RING_ADDR(sc, 0); - else - addr = ARE_RX_RING_ADDR(sc, i + 1); - rd->are_rx_ring[i].are_stat = ADSTAT_OWN; - rd->are_rx_ring[i].are_devcs = ADCTL_CH; - if (i == ARE_RX_RING_CNT - 1) - rd->are_rx_ring[i].are_devcs |= ADCTL_ER; - rd->are_rx_ring[i].are_addr = 0; - rd->are_rx_ring[i].are_link = addr; - if (are_newbuf(sc, i) != 0) - return (ENOBUFS); - } - - bus_dmamap_sync(sc->are_cdata.are_rx_ring_tag, - sc->are_cdata.are_rx_ring_map, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - - return (0); -} - -/* - * Initialize an RX descriptor and attach an MBUF cluster. - */ -static int -are_newbuf(struct are_softc *sc, int idx) -{ - struct are_desc *desc; - struct are_rxdesc *rxd; - struct mbuf *m; - bus_dma_segment_t segs[1]; - bus_dmamap_t map; - int nsegs; - - m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); - if (m == NULL) - return (ENOBUFS); - m->m_len = m->m_pkthdr.len = MCLBYTES; - - /* tcp header boundary margin */ - m_adj(m, 4); - - if (bus_dmamap_load_mbuf_sg(sc->are_cdata.are_rx_tag, - sc->are_cdata.are_rx_sparemap, m, segs, &nsegs, 0) != 0) { - m_freem(m); - return (ENOBUFS); - } - KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs)); - - rxd = &sc->are_cdata.are_rxdesc[idx]; - if (rxd->rx_m != NULL) { - /* - * THis is if_kr.c original code but make bug. Make scranble on buffer data. - * bus_dmamap_sync(sc->are_cdata.are_rx_tag, rxd->rx_dmamap, - * BUS_DMASYNC_POSTREAD); - */ - bus_dmamap_unload(sc->are_cdata.are_rx_tag, rxd->rx_dmamap); - } - map = rxd->rx_dmamap; - rxd->rx_dmamap = sc->are_cdata.are_rx_sparemap; - sc->are_cdata.are_rx_sparemap = map; - bus_dmamap_sync(sc->are_cdata.are_rx_tag, rxd->rx_dmamap, - BUS_DMASYNC_PREREAD); - rxd->rx_m = m; - desc = rxd->desc; - desc->are_addr = segs[0].ds_addr; - desc->are_devcs |= ARE_DMASIZE(segs[0].ds_len); - rxd->saved_ca = desc->are_addr ; - rxd->saved_ctl = desc->are_stat ; - - return (0); -} - -static __inline void -are_fixup_rx(struct mbuf *m) -{ - int i; - uint16_t *src, *dst; - - src = mtod(m, uint16_t *); - dst = src - 1; - - for (i = 0; i < m->m_len / sizeof(uint16_t); i++) { - *dst++ = *src++; - } - - if (m->m_len % sizeof(uint16_t)) - *(uint8_t *)dst = *(uint8_t *)src; - - m->m_data -= ETHER_ALIGN; -} - - -static void -are_tx(struct are_softc *sc) -{ - struct are_txdesc *txd; - struct are_desc *cur_tx; - struct ifnet *ifp; - uint32_t ctl, devcs; - int cons, prod; - - ARE_LOCK_ASSERT(sc); - - cons = sc->are_cdata.are_tx_cons; - prod = sc->are_cdata.are_tx_prod; - if (cons == prod) - return; - - bus_dmamap_sync(sc->are_cdata.are_tx_ring_tag, - sc->are_cdata.are_tx_ring_map, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - - ifp = sc->are_ifp; - /* - * Go through our tx list and free mbufs for those - * frames that have been transmitted. - */ - for (; cons != prod; ARE_INC(cons, ARE_TX_RING_CNT)) { - cur_tx = &sc->are_rdata.are_tx_ring[cons]; - ctl = cur_tx->are_stat; - devcs = cur_tx->are_devcs; - /* Check if descriptor has "finished" flag */ - if (ARE_DMASIZE(devcs) == 0) - break; - - sc->are_cdata.are_tx_cnt--; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - - txd = &sc->are_cdata.are_txdesc[cons]; - - if ((ctl & ADSTAT_Tx_ES) == 0) - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - else { - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - } - - bus_dmamap_sync(sc->are_cdata.are_tx_tag, txd->tx_dmamap, - BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->are_cdata.are_tx_tag, txd->tx_dmamap); - - /* Free only if it's first descriptor in list */ - if (txd->tx_m) - m_freem(txd->tx_m); - txd->tx_m = NULL; - - /* reset descriptor */ - cur_tx->are_stat = 0; - cur_tx->are_devcs = 0; - cur_tx->are_addr = 0; - } - - sc->are_cdata.are_tx_cons = cons; - - bus_dmamap_sync(sc->are_cdata.are_tx_ring_tag, - sc->are_cdata.are_tx_ring_map, BUS_DMASYNC_PREWRITE); -} - - -static void -are_rx(struct are_softc *sc) -{ - struct are_rxdesc *rxd; - struct ifnet *ifp = sc->are_ifp; - int cons, prog, packet_len, error; - struct are_desc *cur_rx; - struct mbuf *m; - - ARE_LOCK_ASSERT(sc); - - cons = sc->are_cdata.are_rx_cons; - - bus_dmamap_sync(sc->are_cdata.are_rx_ring_tag, - sc->are_cdata.are_rx_ring_map, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - - for (prog = 0; prog < ARE_RX_RING_CNT; ARE_INC(cons, ARE_RX_RING_CNT)) { - cur_rx = &sc->are_rdata.are_rx_ring[cons]; - rxd = &sc->are_cdata.are_rxdesc[cons]; - m = rxd->rx_m; - - if ((cur_rx->are_stat & ADSTAT_OWN) == ADSTAT_OWN) - break; - - prog++; - - packet_len = ADSTAT_Rx_LENGTH(cur_rx->are_stat); - /* Assume it's error */ - error = 1; - - if (packet_len < 64) - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - else if ((cur_rx->are_stat & ADSTAT_Rx_DE) == 0) { - error = 0; - bus_dmamap_sync(sc->are_cdata.are_rx_tag, rxd->rx_dmamap, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - m = rxd->rx_m; - /* Skip 4 bytes of CRC */ - m->m_pkthdr.len = m->m_len = packet_len - ETHER_CRC_LEN; - are_fixup_rx(m); - m->m_pkthdr.rcvif = ifp; - if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); - - ARE_UNLOCK(sc); - (*ifp->if_input)(ifp, m); - ARE_LOCK(sc); - } - - if (error) { - /* Restore CONTROL and CA values, reset DEVCS */ - cur_rx->are_stat = rxd->saved_ctl; - cur_rx->are_addr = rxd->saved_ca; - cur_rx->are_devcs = 0; - } - else { - /* Reinit descriptor */ - cur_rx->are_stat = ADSTAT_OWN; - cur_rx->are_devcs = 0; - if (cons == ARE_RX_RING_CNT - 1) - cur_rx->are_devcs |= ADCTL_ER; - cur_rx->are_addr = 0; - if (are_newbuf(sc, cons) != 0) { - device_printf(sc->are_dev, - "Failed to allocate buffer\n"); - break; - } - } - - bus_dmamap_sync(sc->are_cdata.are_rx_ring_tag, - sc->are_cdata.are_rx_ring_map, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - - } - - if (prog > 0) { - sc->are_cdata.are_rx_cons = cons; - - bus_dmamap_sync(sc->are_cdata.are_rx_ring_tag, - sc->are_cdata.are_rx_ring_map, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - } -} - -static void -are_intr(void *arg) -{ - struct are_softc *sc = arg; - uint32_t status; - struct ifnet *ifp = sc->are_ifp; - - ARE_LOCK(sc); - - /* mask out interrupts */ - - status = CSR_READ_4(sc, CSR_STATUS); - if (status) { - CSR_WRITE_4(sc, CSR_STATUS, status); - } - if (status & sc->sc_rxint_mask) { - are_rx(sc); - } - if (status & sc->sc_txint_mask) { - are_tx(sc); - } - - /* Try to get more packets going. */ - are_start(ifp); - - ARE_UNLOCK(sc); -} - -static void -are_tick(void *xsc) -{ -#ifdef ARE_MII - struct are_softc *sc = xsc; - struct mii_data *mii; - - ARE_LOCK_ASSERT(sc); - - mii = device_get_softc(sc->are_miibus); - mii_tick(mii); - callout_reset(&sc->are_stat_callout, hz, are_tick, sc); -#endif -} - -static void -are_hinted_child(device_t bus, const char *dname, int dunit) -{ - BUS_ADD_CHILD(bus, 0, dname, dunit); - device_printf(bus, "hinted child %s%d\n", dname, dunit); -} - -#ifdef ARE_MDIO -static int -aremdio_probe(device_t dev) -{ - device_set_desc(dev, "Atheros AR531x built-in ethernet interface, MDIO controller"); - return(0); -} - -static int -aremdio_attach(device_t dev) -{ - struct are_softc *sc; - int error = 0; - - sc = device_get_softc(dev); - sc->are_dev = dev; - sc->are_rid = 0; - sc->are_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, - &sc->are_rid, RF_ACTIVE | RF_SHAREABLE); - if (sc->are_res == NULL) { - device_printf(dev, "couldn't map memory\n"); - error = ENXIO; - goto fail; - } - - sc->are_btag = rman_get_bustag(sc->are_res); - sc->are_bhandle = rman_get_bushandle(sc->are_res); - - bus_generic_probe(dev); - bus_enumerate_hinted_children(dev); - error = bus_generic_attach(dev); -fail: - return (error); -} - -static int -aremdio_detach(device_t dev) -{ - return(0); -} -#endif - -#ifdef ARE_DEBUG -void -dump_txdesc(struct are_softc *sc, int pos) -{ - struct are_desc *desc; - - desc = &sc->are_rdata.are_tx_ring[pos]; - device_printf(sc->are_dev, "CSR_TXLIST %08x\n", CSR_READ_4(sc, CSR_TXLIST)); - device_printf(sc->are_dev, "CSR_HTBA %08x\n", CSR_READ_4(sc, CSR_HTBA)); - device_printf(sc->are_dev, "%d TDES0:%08x TDES1:%08x TDES2:%08x TDES3:%08x\n", - pos, desc->are_stat, desc->are_devcs, desc->are_addr, desc->are_link); -} - -void -dump_status_reg(struct are_softc *sc) -{ - uint32_t status; - - /* mask out interrupts */ - - device_printf(sc->are_dev, "CSR_HTBA %08x\n", CSR_READ_4(sc, CSR_HTBA)); - status = CSR_READ_4(sc, CSR_STATUS); - device_printf(sc->are_dev, "CSR5 Status Register EB:%d TS:%d RS:%d NIS:%d AIS:%d ER:%d SE:%d LNF:%d TM:%d RWT:%d RPS:%d RU:%d RI:%d UNF:%d LNP/ANC:%d TJT:%d TU:%d TPS:%d TI:%d\n", - (status >> 23 ) & 7, - (status >> 20 ) & 7, - (status >> 17 ) & 7, - (status >> 16 ) & 1, - (status >> 15 ) & 1, - (status >> 14 ) & 1, - (status >> 13 ) & 1, - (status >> 12 ) & 1, - (status >> 11 ) & 1, - (status >> 9 ) & 1, - (status >> 8 ) & 1, - (status >> 7 ) & 1, - (status >> 6 ) & 1, - (status >> 5 ) & 1, - (status >> 4 ) & 1, - (status >> 3 ) & 1, - (status >> 2 ) & 1, - (status >> 1 ) & 1, - (status >> 0 ) & 1); - -} -#endif Index: sys/mips/atheros/ar531x/if_arereg.h =================================================================== --- sys/mips/atheros/ar531x/if_arereg.h +++ /dev/null @@ -1,404 +0,0 @@ -/*- - * Copyright (C) 2007 - * Oleksandr Tymoshenko . 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 OR HIS RELATIVES 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 MIND, 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 __IF_AREREG_H__ -#define __IF_AREREG_H__ - -struct are_desc { - uint32_t are_stat; - uint32_t are_devcs; - uint32_t are_addr; - uint32_t are_link; -}; - -#define ARE_DMASIZE(len) ((len) & ((1 << 11)-1)) -#define ARE_PKTSIZE(len) ((len & 0xffff0000) >> 16) - -#define ARE_RX_RING_CNT 128 -#define ARE_TX_RING_CNT 128 -#define ARE_TX_RING_SIZE sizeof(struct are_desc) * ARE_TX_RING_CNT -#define ARE_RX_RING_SIZE sizeof(struct are_desc) * ARE_RX_RING_CNT - -#define ARE_MIN_FRAMELEN 60 -#define ARE_RING_ALIGN sizeof(struct are_desc) -#define ARE_RX_ALIGN sizeof(uint32_t) -#define ARE_MAXFRAGS 8 -#define ARE_TX_INTR_THRESH 8 - -#define ARE_TX_RING_ADDR(sc, i) \ - ((sc)->are_rdata.are_tx_ring_paddr + sizeof(struct are_desc) * (i)) -#define ARE_RX_RING_ADDR(sc, i) \ - ((sc)->are_rdata.are_rx_ring_paddr + sizeof(struct are_desc) * (i)) -#define ARE_INC(x,y) (x) = (((x) + 1) % y) - -struct are_txdesc { - struct mbuf *tx_m; - bus_dmamap_t tx_dmamap; -}; - -struct are_rxdesc { - struct mbuf *rx_m; - bus_dmamap_t rx_dmamap; - struct are_desc *desc; - /* Use this values on error instead of allocating new mbuf */ - uint32_t saved_ctl, saved_ca; -}; - -struct are_chain_data { - bus_dma_tag_t are_parent_tag; - bus_dma_tag_t are_tx_tag; - struct are_txdesc are_txdesc[ARE_TX_RING_CNT]; - bus_dma_tag_t are_rx_tag; - struct are_rxdesc are_rxdesc[ARE_RX_RING_CNT]; - bus_dma_tag_t are_tx_ring_tag; - bus_dma_tag_t are_rx_ring_tag; - bus_dmamap_t are_tx_ring_map; - bus_dmamap_t are_rx_ring_map; - bus_dmamap_t are_rx_sparemap; - int are_tx_pkts; - int are_tx_prod; - int are_tx_cons; - int are_tx_cnt; - int are_rx_cons; -}; - -struct are_ring_data { - struct are_desc *are_rx_ring; - struct are_desc *are_tx_ring; - bus_addr_t are_rx_ring_paddr; - bus_addr_t are_tx_ring_paddr; -}; - -struct are_softc { - struct ifnet *are_ifp; /* interface info */ - bus_space_handle_t are_bhandle; /* bus space handle */ - bus_space_tag_t are_btag; /* bus space tag */ - device_t are_dev; - uint8_t are_eaddr[ETHER_ADDR_LEN]; - struct resource *are_res; - int are_rid; - struct resource *are_irq; - void *are_intrhand; - u_int32_t sc_inten; /* copy of CSR_INTEN */ - u_int32_t sc_rxint_mask; /* mask of Rx interrupts we want */ - u_int32_t sc_txint_mask; /* mask of Tx interrupts we want */ -#ifdef ARE_MII - device_t are_miibus; -#else - struct ifmedia are_ifmedia; -#endif -#ifdef ARE_MDIO - device_t are_miiproxy; -#endif - bus_dma_tag_t are_parent_tag; - bus_dma_tag_t are_tag; - struct mtx are_mtx; - struct callout are_stat_callout; - struct task are_link_task; - struct are_chain_data are_cdata; - struct are_ring_data are_rdata; - int are_link_status; - int are_detach; - int are_if_flags; /* last if flags */ -}; - -#define ARE_LOCK(_sc) mtx_lock(&(_sc)->are_mtx) -#define ARE_UNLOCK(_sc) mtx_unlock(&(_sc)->are_mtx) -#define ARE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->are_mtx, MA_OWNED) - -/* - * register space access macros - */ -#define CSR_WRITE_4(sc, reg, val) \ - bus_space_write_4(sc->are_btag, sc->are_bhandle, reg, val) - -#define CSR_READ_4(sc, reg) \ - bus_space_read_4(sc->are_btag, sc->are_bhandle, reg) - - -/* $NetBSD: aereg.h,v 1.2 2008/04/28 20:23:28 martin Exp $ */ - -/*- - * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, - * NASA Ames Research Center. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Descriptor Status bits common to transmit and receive. - */ -#define ADSTAT_OWN 0x80000000 /* Tulip owns descriptor */ -#define ADSTAT_ES 0x00008000 /* Error Summary */ - -/* - * Descriptor Status bits for Receive Descriptor. - */ -#define ADSTAT_Rx_FF 0x40000000 /* Filtering Fail */ -#define ADSTAT_Rx_FL 0x3fff0000 /* Frame Length including CRC */ -#define ADSTAT_Rx_DE 0x00004000 /* Descriptor Error */ -#define ADSTAT_Rx_LE 0x00001000 /* Length Error */ -#define ADSTAT_Rx_RF 0x00000800 /* Runt Frame */ -#define ADSTAT_Rx_MF 0x00000400 /* Multicast Frame */ -#define ADSTAT_Rx_FS 0x00000200 /* First Descriptor */ -#define ADSTAT_Rx_LS 0x00000100 /* Last Descriptor */ -#define ADSTAT_Rx_TL 0x00000080 /* Frame Too Long */ -#define ADSTAT_Rx_CS 0x00000040 /* Collision Seen */ -#define ADSTAT_Rx_RT 0x00000020 /* Frame Type */ -#define ADSTAT_Rx_RW 0x00000010 /* Receive Watchdog */ -#define ADSTAT_Rx_RE 0x00000008 /* Report on MII Error */ -#define ADSTAT_Rx_DB 0x00000004 /* Dribbling Bit */ -#define ADSTAT_Rx_CE 0x00000002 /* CRC Error */ -#define ADSTAT_Rx_ZER 0x00000001 /* Zero (always 0) */ - -#define ADSTAT_Rx_LENGTH(x) (((x) & ADSTAT_Rx_FL) >> 16) - -/* - * Descriptor Status bits for Transmit Descriptor. - */ -#define ADSTAT_Tx_ES 0x00008000 /* Error Summary */ -#define ADSTAT_Tx_TO 0x00004000 /* Transmit Jabber Timeout */ -#define ADSTAT_Tx_LO 0x00000800 /* Loss of Carrier */ -#define ADSTAT_Tx_NC 0x00000400 /* No Carrier */ -#define ADSTAT_Tx_LC 0x00000200 /* Late Collision */ -#define ADSTAT_Tx_EC 0x00000100 /* Excessive Collisions */ -#define ADSTAT_Tx_HF 0x00000080 /* Heartbeat Fail */ -#define ADSTAT_Tx_CC 0x00000078 /* Collision Count */ -#define ADSTAT_Tx_ED 0x00000004 /* Excessive Deferral */ -#define ADSTAT_Tx_UF 0x00000002 /* Underflow Error */ -#define ADSTAT_Tx_DE 0x00000001 /* Deferred */ - -#define ADSTAT_Tx_COLLISIONS(x) (((x) & ADSTAT_Tx_CC) >> 3) - -/* - * Descriptor Control bits common to transmit and receive. - */ -#define ADCTL_SIZE1 0x000007ff /* Size of buffer 1 */ -#define ADCTL_SIZE1_SHIFT 0 - -#define ADCTL_SIZE2 0x003ff800 /* Size of buffer 2 */ -#define ADCTL_SIZE2_SHIFT 11 - -#define ADCTL_ER 0x02000000 /* End of Ring */ -#define ADCTL_CH 0x01000000 /* Second Address Chained */ - -/* - * Descriptor Control bits for Transmit Descriptor. - */ -#define ADCTL_Tx_IC 0x80000000 /* Interrupt on Completion */ -#define ADCTL_Tx_LS 0x40000000 /* Last Segment */ -#define ADCTL_Tx_FS 0x20000000 /* First Segment */ -#define ADCTL_Tx_AC 0x04000000 /* Add CRC Disable */ -#define ADCTL_Tx_DPD 0x00800000 /* Disabled Padding */ - -/* - * Control registers. - */ - -/* tese are registers only found on this part */ -#define CSR_MACCTL 0x0000 /* mac control */ -#define CSR_MACHI 0x0004 -#define CSR_MACLO 0x0008 -#define CSR_HTHI 0x000C /* multicast table high */ -#define CSR_HTLO 0x0010 /* multicast table low */ -#define CSR_MIIADDR 0x0014 /* mii address */ -#define CSR_MIIDATA 0x0018 /* mii data */ -#define CSR_FLOWC 0x001C /* flow control */ -#define CSR_VL1 0x0020 /* vlan 1 tag */ - -/* these are more or less normal Tulip registers */ -#define CSR_BUSMODE 0x1000 /* bus mode */ -#define CSR_TXPOLL 0x1004 /* tx poll demand */ -#define CSR_RXPOLL 0x1008 /* rx poll demand */ -#define CSR_RXLIST 0x100C /* rx base descriptor address */ -#define CSR_TXLIST 0x1010 /* tx base descriptor address */ -#define CSR_STATUS 0x1014 /* (interrupt) status */ -#define CSR_OPMODE 0x1018 /* operation mode */ -#define CSR_INTEN 0x101C /* interrupt enable */ -#define CSR_MISSED 0x1020 /* missed frame counter */ -#define CSR_HTBA 0x1050 /* host tx buffer address (ro) */ -#define CSR_HRBA 0x1054 /* host rx buffer address (ro) */ - -/* CSR_MACCTL - Mac Control */ -#define MACCTL_RE 0x00000004 /* rx enable */ -#define MACCTL_TE 0x00000008 /* tx enable */ -#define MACCTL_DC 0x00000020 /* deferral check */ -#define MACCTL_PSTR 0x00000100 /* automatic pad strip */ -#define MACCTL_DTRY 0x00000400 /* disable retry */ -#define MACCTL_DBF 0x00000800 /* disable broadcast frames */ -#define MACCTL_LCC 0x00001000 /* late collision control */ -#define MACCTL_HASH 0x00002000 /* hash filtering enable */ -#define MACCTL_HO 0x00008000 /* disable perfect filtering */ -#define MACCTL_PB 0x00010000 /* pass bad frames */ -#define MACCTL_IF 0x00020000 /* inverse filtering */ -#define MACCTL_PR 0x00040000 /* promiscuous mode */ -#define MACCTL_PM 0x00080000 /* pass all multicast */ -#define MACCTL_FDX 0x00100000 /* full duplex mode */ -#define MACCTL_LOOP 0x00600000 /* loopback mask */ -#define MACCTL_LOOP_INT 0x00200000 /* internal loopback */ -#define MACCTL_LOOP_EXT 0x00400000 /* external loopback */ -#define MACCTL_LOOP_NONE 0x00000000 -#define MACCTL_DRO 0x00800000 /* disable receive own */ -#define MACCTL_PS 0x08000000 /* port select, 0 = mii */ -#define MACCTL_HBD 0x10000000 /* heartbeat disable */ -#define MACCTL_BLE 0x40000000 /* mac big endian */ -#define MACCTL_RA 0x80000000 /* receive all packets */ - -/* CSR_MIIADDR - MII Addess */ -#define MIIADDR_BUSY 0x00000001 /* mii busy */ -#define MIIADDR_WRITE 0x00000002 /* mii write */ -#define MIIADDR_REG_MASK 0x000007C0 /* mii register */ -#define MIIADDR_REG_SHIFT 6 -#define MIIADDR_PHY_MASK 0x0000F800 /* mii phy */ -#define MIIADDR_PHY_SHIFT 11 - -#define MIIADDR_GETREG(x) (((x) & MIIADDR_REG) >> 6) -#define MIIADDR_PUTREG(x) (((x) << 6) & MIIADR_REG) -#define MIIADDR_GETPHY(x) (((x) & MIIADDR_PHY) >> 11) -#define MIIADDR_PUTPHY(x) (((x) << 6) & MIIADR_PHY) - -/* CSR_FLOWC - Flow Control */ -#define FLOWC_FCB 0x00000001 /* flow control busy */ -#define FLOWC_FCE 0x00000002 /* flow control enable */ -#define FLOWC_PCF 0x00000004 /* pass control frames */ -#define FLOWC_PT 0xffff0000 /* pause time */ - -/* CSR_BUSMODE - Bus Mode */ -#define BUSMODE_SWR 0x00000001 /* software reset */ -#define BUSMODE_BAR 0x00000002 /* bus arbitration */ -#define BUSMODE_DSL 0x0000007c /* descriptor skip length */ -#define BUSMODE_BLE 0x00000080 /* data buf endian */ - /* programmable burst length */ -#define BUSMODE_PBL_DEFAULT 0x00000000 /* default value */ -#define BUSMODE_PBL_1LW 0x00000100 /* 1 longword */ -#define BUSMODE_PBL_2LW 0x00000200 /* 2 longwords */ -#define BUSMODE_PBL_4LW 0x00000400 /* 4 longwords */ -#define BUSMODE_PBL_8LW 0x00000800 /* 8 longwords */ -#define BUSMODE_PBL_16LW 0x00001000 /* 16 longwords */ -#define BUSMODE_PBL_32LW 0x00002000 /* 32 longwords */ -#define BUSMODE_DBO 0x00100000 /* descriptor endian */ -#define BUSMODE_ALIGN_16B 0x01000000 /* force oddhw rx buf align */ - -/* CSR_TXPOLL - Transmit Poll Demand */ -#define TXPOLL_TPD 0x00000001 /* transmit poll demand */ - - -/* CSR_RXPOLL - Receive Poll Demand */ -#define RXPOLL_RPD 0x00000001 /* receive poll demand */ - -/* CSR_STATUS - Status */ -#define STATUS_TI 0x00000001 /* transmit interrupt */ -#define STATUS_TPS 0x00000002 /* transmit process stopped */ -#define STATUS_TU 0x00000004 /* transmit buffer unavail */ -#define STATUS_TJT 0x00000008 /* transmit jabber timeout */ -#define STATUS_UNF 0x00000020 /* transmit underflow */ -#define STATUS_RI 0x00000040 /* receive interrupt */ -#define STATUS_RU 0x00000080 /* receive buffer unavail */ -#define STATUS_RPS 0x00000100 /* receive process stopped */ -#define STATUS_ETI 0x00000400 /* early transmit interrupt */ -#define STATUS_SE 0x00002000 /* system error */ -#define STATUS_ER 0x00004000 /* early receive (21041) */ -#define STATUS_AIS 0x00008000 /* abnormal intr summary */ -#define STATUS_NIS 0x00010000 /* normal interrupt summary */ -#define STATUS_RS 0x000e0000 /* receive process state */ -#define STATUS_RS_STOPPED 0x00000000 /* Stopped */ -#define STATUS_RS_FETCH 0x00020000 /* Running - fetch receive - descriptor */ -#define STATUS_RS_CHECK 0x00040000 /* Running - check for end - of receive */ -#define STATUS_RS_WAIT 0x00060000 /* Running - wait for packet */ -#define STATUS_RS_SUSPENDED 0x00080000 /* Suspended */ -#define STATUS_RS_CLOSE 0x000a0000 /* Running - close receive - descriptor */ -#define STATUS_RS_FLUSH 0x000c0000 /* Running - flush current - frame from FIFO */ -#define STATUS_RS_QUEUE 0x000e0000 /* Running - queue current - frame from FIFO into - buffer */ -#define STATUS_TS 0x00700000 /* transmit process state */ -#define STATUS_TS_STOPPED 0x00000000 /* Stopped */ -#define STATUS_TS_FETCH 0x00100000 /* Running - fetch transmit - descriptor */ -#define STATUS_TS_WAIT 0x00200000 /* Running - wait for end - of transmission */ -#define STATUS_TS_READING 0x00300000 /* Running - read buffer from - memory and queue into - FIFO */ -#define STATUS_TS_SUSPENDED 0x00600000 /* Suspended */ -#define STATUS_TS_CLOSE 0x00700000 /* Running - close transmit - descriptor */ -#define STATUS_TX_ABORT 0x00800000 /* Transmit bus abort */ -#define STATUS_RX_ABORT 0x01000000 /* Transmit bus abort */ - -/* CSR_OPMODE - Operation Mode */ -#define OPMODE_SR 0x00000002 /* start receive */ -#define OPMODE_OSF 0x00000004 /* operate on second frame */ -#define OPMODE_ST 0x00002000 /* start transmitter */ -#define OPMODE_TR 0x0000c000 /* threshold control */ -#define OPMODE_TR_32 0x00000000 /* 32 words */ -#define OPMODE_TR_64 0x00004000 /* 64 words */ -#define OPMODE_TR_128 0x00008000 /* 128 words */ -#define OPMODE_TR_256 0x0000c000 /* 256 words */ -#define OPMODE_SF 0x00200000 /* store and forward mode */ - -/* CSR_INTEN - Interrupt Enable */ - /* See bits for CSR_STATUS -- Status */ - - -/* CSR_MISSED - Missed Frames */ -#define MISSED_MFC 0xffff0000 /* missed packet count */ -#define MISSED_FOC 0x0000ffff /* fifo overflow counter */ - -#define MISSED_GETMFC(x) ((x) & MISSED_MFC) -#define MISSED_GETFOC(x) (((x) & MISSED_FOC) >> 16) - -#endif /* __IF_AREREG_H__ */ Index: sys/mips/atheros/ar531x/uart_bus_ar5315.c =================================================================== --- sys/mips/atheros/ar531x/uart_bus_ar5315.c +++ /dev/null @@ -1,89 +0,0 @@ -/*- - * Copyright (c) 2009, Oleksandr Tymoshenko - * 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 - */ -#include "opt_uart.h" - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include - -#include "uart_if.h" - -static int uart_ar5315_probe(device_t dev); -extern struct uart_class uart_ar5315_uart_class; - -static device_method_t uart_ar5315_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, uart_ar5315_probe), - DEVMETHOD(device_attach, uart_bus_attach), - DEVMETHOD(device_detach, uart_bus_detach), - DEVMETHOD_END -}; - -static driver_t uart_ar5315_driver = { - uart_driver_name, - uart_ar5315_methods, - sizeof(struct uart_softc), -}; - -extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; - -static int -uart_ar5315_probe(device_t dev) -{ - struct uart_softc *sc; - uint64_t freq; - - freq = ar531x_ahb_freq(); - - sc = device_get_softc(dev); - sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs); - sc->sc_class = &uart_ns8250_class; - bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); - sc->sc_sysdev->bas.regshft = 2; - sc->sc_sysdev->bas.bst = mips_bus_space_generic; - sc->sc_sysdev->bas.bsh = ar531x_uart_addr() + 3; - sc->sc_bas.regshft = 2; - sc->sc_bas.bst = mips_bus_space_generic; - sc->sc_bas.bsh = ar531x_uart_addr() + 3; - - return (uart_bus_probe(dev, 2, 0, freq, 0, 0, 0)); -} - -DRIVER_MODULE(uart, apb, uart_ar5315_driver, uart_devclass, 0, 0); Index: sys/mips/atheros/ar531x/uart_cpu_ar5315.c =================================================================== --- sys/mips/atheros/ar531x/uart_cpu_ar5315.c +++ /dev/null @@ -1,76 +0,0 @@ -/*- - * Copyright (c) 2009 Oleksandr Tymoshenko - * 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 "opt_uart.h" - -#include -__FBSDID("$FreeBSD$"); - -#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; - -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) -{ - uint64_t freq; - - freq = ar531x_ahb_freq(); - - di->ops = uart_getops(&uart_ns8250_class); - di->bas.chan = 0; - di->bas.bst = ar71xx_bus_space_reversed; - di->bas.regshft = 2; - di->bas.rclk = freq; - di->baudrate = 9600; // RedBoot default is 9600 - di->databits = 8; - di->stopbits = 1; - - di->parity = UART_PARITY_NONE; - - uart_bus_space_io = NULL; - uart_bus_space_mem = ar71xx_bus_space_reversed; - di->bas.bsh = ar531x_uart_addr(); - return (0); -} Index: sys/mips/conf/AR5312_BASE.hints =================================================================== --- sys/mips/conf/AR5312_BASE.hints +++ /dev/null @@ -1,29 +0,0 @@ -# $FreeBSD$ -hint.apb.0.at="nexus0" -hint.apb.0.irq=4 - -# uart0 -hint.uart.0.at="apb0" -# see atheros/uart_cpu_ar71xx.c why +3 -hint.uart.0.maddr=0x1C000003 -hint.uart.0.msize=0x20 -#hint.uart.0.irq=4 -#hint.uart.0.flags="0x30" - -# Watchdog -hint.ar5315_wdog.0.at="apb0" -hint.ar5315_wdog.0.irq=6 - -# Ethernet -hint.are.0.at="nexus0" -hint.are.0.maddr=0x18100000 -hint.are.0.msize=0x00100000 -hint.are.0.irq=1 - -hint.are.1.at="nexus0" -hint.are.1.maddr=0x18200000 -hint.are.1.msize=0x00100000 -hint.are.1.irq=2 - -# GEOM redboot FIS directory offset -#hint.redboot.0.fisoffset="0x007e0000" Index: sys/mips/conf/AR5315_BASE.hints =================================================================== --- sys/mips/conf/AR5315_BASE.hints +++ /dev/null @@ -1,34 +0,0 @@ -# $FreeBSD$ -hint.apb.0.at="nexus0" -hint.apb.0.irq=0 - -# uart0 -hint.uart.0.at="apb0" -hint.uart.0.maddr=0x11100003 -hint.uart.0.msize=0x20 -#hint.uart.0.irq=0 -#hint.uart.0.flags="0x30" - -# Watchdog -hint.ar5315_wdog.0.at="apb0" -hint.ar5315_wdog.0.irq=7 - -# SPI -hint.spi.0.at="nexus0" -hint.spi.0.maddr=0x11300000 -hint.spi.0.msize=0x0000000c -#hint.spi.0.irq=2 - -# Ethernet -hint.are.0.at="nexus0" -hint.are.0.maddr=0x10500000 -hint.are.0.msize=0x500000 -hint.are.0.irq=2 - -# Flash -hint.mx25l.0.at="spibus0" -hint.mx25l.0.cs=0 - -# GEOM redboot FIS directory offset -#hint.redboot.0.fisoffset="0x007e0000" - Index: sys/mips/conf/CI20 =================================================================== --- sys/mips/conf/CI20 +++ /dev/null @@ -1,34 +0,0 @@ -# CI20 -- Kernel config for Creator CI20 board -# -# $FreeBSD$ - -#NO_UNIVERSE - -include "JZ4780" -ident CI20 - -options FDT_DTB_STATIC -makeoptions FDT_DTS_FILE=ingenic/ci20.dts - -#options KTR -#options KTR_CPUMASK=0x3 -#options KTR_MASK=(KTR_GEN) -#options KTR_COMPILE=(KTR_GEN) -#options KTR_VERBOSE - -# Uncomment for NFS root -#options BOOTP -#options BOOTP_NFSROOT -#options BOOTP_NFSV3 -#options BOOTP_WIRED_TO=dme0 -#options BOOTP_COMPAT - -options ROOTDEVNAME=\"ufs:mmcsd0\" - -device sound -device xdma - -makeoptions TRAMPLOADADDR=0x88000000 - -#options VERBOSE_SYSINIT -options PRINTF_BUFR_SIZE=256 Index: sys/mips/conf/GXEMUL =================================================================== --- sys/mips/conf/GXEMUL +++ /dev/null @@ -1,64 +0,0 @@ -# -# GXEMUL "oldtestmips" sample kernel configuration. -# -# $FreeBSD$ -# - -ident GXEMUL - -machine mips mips64 -cpu CPU_MIPS4KC - -options HZ=100 - -makeoptions ARCH_FLAGS="-march=mips64 -mabi=64" - -makeoptions KERNLOADADDR=0xffffffff80100000 - -include "../gxemul/std.gxemul" - -hints "GXEMUL.hints" #Default places to look for devices. - -makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols - -makeoptions MODULES_OVERRIDE="" - -options DDB -options KDB - -# Make an SMP-capable kernel by default -options SMP # Symmetric MultiProcessor Kernel - -options SCHED_ULE -options VIMAGE # Subsystem virtualization, e.g. VNET -options INET # InterNETworking -options INET6 # IPv6 communications protocols -options TCP_HHOOK # hhook(9) framework for TCP - -options FFS #Berkeley Fast Filesystem - -# Debugging for use in -current -#options DEADLKRES #Enable the deadlock resolver -options INVARIANTS #Enable calls of extra sanity checking -options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS -#options WITNESS #Enable checks to detect deadlocks and cycles -#options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed - -options ROOTDEVNAME=\"ufs:gxemul_disk0\" - -device gxemul_cons -device gxemul_disk -device gxemul_ether - -# Pseudo devices. -device loop # Network loopback -device random # Entropy device -device ether # Ethernet support -device tun # Packet tunnel. -device md # Memory "disks" -device gif # IPv6 and IPv4 tunneling - -# 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 Index: sys/mips/conf/GXEMUL.hints =================================================================== --- sys/mips/conf/GXEMUL.hints +++ /dev/null @@ -1 +0,0 @@ -# $FreeBSD$ Index: sys/mips/conf/GXEMUL32 =================================================================== --- sys/mips/conf/GXEMUL32 +++ /dev/null @@ -1,62 +0,0 @@ -# -# GXEMUL "oldtestmips" sample kernel configuration. -# -# $FreeBSD$ -# - -ident GXEMUL - -machine mips mips -cpu CPU_MIPS4KC - -options HZ=100 - -makeoptions KERNLOADADDR=0x80100000 - -include "../gxemul/std.gxemul" - -hints "GXEMUL.hints" #Default places to look for devices. - -makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols - -makeoptions MODULES_OVERRIDE="" - -options DDB -options KDB - -# Make an SMP-capable kernel by default -options SMP # Symmetric MultiProcessor Kernel - -options SCHED_ULE -options VIMAGE # Subsystem virtualization, e.g. VNET -options INET # InterNETworking -options INET6 # IPv6 communications protocols -options TCP_HHOOK # hhook(9) framework for TCP - -options FFS #Berkeley Fast Filesystem - -# Debugging for use in -current -#options DEADLKRES #Enable the deadlock resolver -options INVARIANTS #Enable calls of extra sanity checking -options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS -#options WITNESS #Enable checks to detect deadlocks and cycles -#options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed - -options ROOTDEVNAME=\"ufs:gxemul_disk0\" - -device gxemul_cons -device gxemul_disk -device gxemul_ether - -# Pseudo devices. -device loop # Network loopback -device random # Entropy device -device ether # Ethernet support -device tun # Packet tunnel. -device md # Memory "disks" -device gif # IPv6 and IPv4 tunneling - -# 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 Index: sys/mips/conf/JZ4780 =================================================================== --- sys/mips/conf/JZ4780 +++ /dev/null @@ -1,111 +0,0 @@ -# JZ4780 -- Kernel config for Ingenic JZ47XX boards -# -# $FreeBSD$ - -#NO_UNIVERSE - -ident JZ4780 -machine mips mipselhf -cpu CPU_XBURST -cpu CPU_MIPS4KC - -makeoptions KERNLOADADDR=0x80020000 -makeoptions ARCH_FLAGS="-EL -march=mips32r2" - -# Don't build any modules yet. -makeoptions MODULES_OVERRIDE="" - -files "../ingenic/files.jz4780" -hints "JZ4780.hints" #Default places to look for devices. - -makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols - -options INTRNG # Borrow interrupt code from ARM -options MIPS_NIRQ=264 # 8 cpuintc + 64 intc + 6 * 23 gpio - -options DDB -options KDB -options BREAK_TO_DEBUGGER - -options COMPAT_FREEBSD10 -options COMPAT_FREEBSD11 - -options SCHED_4BSD #4BSD scheduler -options INET #InterNETworking -options NFSCL #Network Filesystem Client -options NFS_ROOT #NFS usable as /, requires NFSCL -options NFSLOCKD #Network Lock Manager -options PSEUDOFS #Pseudo-filesystem framework -options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions - -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 ROOTDEVNAME=\"ufs:ada0\" - -options GEOM_LABEL # Provides labelization -options GEOM_PART_GPT # GUID Partition Tables. -#options GEOM_RAID # Soft RAID functionality. - -# Debugging for use in -current -#options DEADLKRES #Enable the deadlock resolver -options INVARIANTS #Enable calls of extra sanity checking -options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS -#options WITNESS #Enable checks to detect deadlocks and cycles -#options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed - -# Make an SMP-capable kernel by default -options SMP # Symmetric MultiProcessor Kernel - -device loop -device ether -#device le -device miibus -device bpf -device md -device uart -device random - -device fdt_pinctrl - -device clk -device regulator -options EXT_RESOURCES - -device gpio - -device scbus -device da - -device mmc -device mmcsd - -device dme - -device iic -device iicbus - -# Framebuffer console support -device vt -device kbdmux -device hdmi -device videomode -device pty - -# USB support -options USB_DEBUG # enable debug msgs -options USB_HOST_ALIGN=128 # L2 cache line size -device ohci # OHCI PCI->USB interface -device ehci # EHCI PCI->USB interface (USB 2.0) -device dwcotg # DesignWare HS OTG controller -device usb # USB Bus (required) -#device udbp # USB Double Bulk Pipe devices -device uhid # "Human Interface Devices" -device ukbd # Allow keyboard like HIDs to control console -#device ulpt # Printer -device umass # Disks/Mass storage - Requires scbus and da -device ums # Mouse - -# FDT support -options FDT Index: sys/mips/conf/JZ4780.hints =================================================================== --- sys/mips/conf/JZ4780.hints +++ /dev/null @@ -1,2 +0,0 @@ -# $FreeBSD$ -# device.hints Index: sys/mips/conf/RT2880_FDT =================================================================== --- sys/mips/conf/RT2880_FDT +++ /dev/null @@ -1,77 +0,0 @@ -# -# RT2880_FDT -- Kernel configuration file for FreeBSD/MIPS RT2880 SoC -# -# This includes all the configurable parts of the kernel. -# -# $FreeBSD$ -# - -#NO_UNIVERSE - -# -# FDT_DTS_FILE should be modified to suit the target board type. -# -#makeoptions FDT_DTS_FILE=MZK-W04N-XX.dts - -# Start with a base configuration -include "../mediatek/std.rt2880" - -ident RT2880 -cpu CPU_MIPS4KC - -# Don't build any modules by default -makeoptions MODULES_OVERRIDE="" - -# Default rootfs device configuration, should be changed to suit target board -options ROOTDEVNAME=\""ufs:md0.uzip\" - -# Support geom_uzip(4) compressed disk images -device geom_map -options GEOM_UZIP - -# Support md(4) and md-based rootfs -device md -options MD_ROOT - -# Interrupt controller support -device mtk_intr_v1 - -# UART device support -nodevice uart_ns8250 -device uart_dev_mtk - -# SPI and SPI flash support -device mtk_spi_v1 -device spibus -device mx25l - -# CFI support -device cfi -device cfid - -# GPIO and gpioled support -device mtk_gpio_v1 -device gpio -device gpioled - -# USB (dwcotg) support -device usb -device mtk_usb_phy -device dwcotg - -# USB umass(4) storage and da(4) support -device umass -device da - -# CAM support, required if umass(4) is enabled above -device pass -device scbus - -# Ethernet, BPF and bridge support -device rt -device bpf -device if_bridge - -# Extres -options EXT_RESOURCES -device clk Index: sys/mips/conf/SENTRY5 =================================================================== --- sys/mips/conf/SENTRY5 +++ /dev/null @@ -1,91 +0,0 @@ -# -# $FreeBSD$ -# -# The Broadcom Sentry5 series of processors and boards is very commonly -# used in COTS hardware including the Netgear WGT634U. -# -# Some tweaks are needed for use with this platform: -# -# * CFE firmware's ELF loader expects an ELF kernel which is linked so as -# not to contain offsets in PT_LOAD which point behind the actual offset -# of that PT header. FreeBSD normally links the first PT_LOAD header to -# begin at offset 0. -# -# * Broadcom's support package for the internal bus, the Sonics -# SiliconBackplane, needs to be integrated to detect and probe hardware -# correctly. -# -# * The clock needs to be calibrated correctly, so that DELAY() may work. -# One problem with this is that the low-level printf() routine calls DELAY(), -# which currently causes divide-by-zero trap -# -# * The Broadcom CPUs have no FPU. Attempting to detect one by reading CP1's -# status register causes an unhandled boot-time exception. An FPU emulator -# will be necessary to support multi-user boot. -# - -ident SENTRY5 -cpu CPU_MIPS4KC -makeoptions TRAMPLOADADDR=0x807963c0 - -hints "SENTRY5.hints" -include "../broadcom/std.broadcom" - -# sentry5 normally ships with cfe firmware -options CFE -options ALT_BREAK_TO_DEBUGGER -device cfe - -makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols -makeoptions MODULES_OVERRIDE="" - -options DDB -options KDB - -options SCHED_4BSD #4BSD scheduler -options INET #InterNETworking -options TCP_HHOOK # hhook(9) framework for TCP -options NFSCL #Network Filesystem Client -options NFS_ROOT #NFS usable as /, requires NFSCL -options PSEUDOFS #Pseudo-filesystem framework -options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions - -# Debugging for use in -current -#options DEADLKRES -options INVARIANTS -options INVARIANT_SUPPORT - -#options BUS_DEBUG -#makeoptions BUS_DEBUG -options EARLY_PRINTF - -device bhnd -device siba -device siba_nexus -device bhnd_pcib -device pci # bhnd_pcib - -# device bfe # XXX will build both pci and siba -# device miibus # attachments - -# pci devices -# notyet: -#device ath # in pci slot -#device ath_pci # Atheros pci/cardbus glue -#device ath_hal # pci chip support -#options AH_SUPPORT_AR5416 # enable AR5416 tx/rx descriptors - -options USB_DEBUG # enable debug msgs -device usb # USB Bus (required) -device uhci # UHCI PCI->USB interface -device ehci # EHCI PCI->USB interface (USB 2.0) - -device cfi # parallel flash -device cfid - -device gpio -device uart - -device loop -device ether -device md Index: sys/mips/conf/SENTRY5.hints =================================================================== --- sys/mips/conf/SENTRY5.hints +++ /dev/null @@ -1,7 +0,0 @@ -# $FreeBSD$ -hint.bhnd.0.at="nexus0" -hint.bhnd.0.maddr="0x18000000" -hint.bhnd.0.msize="0x00100000" - -# NVRAM via CFE -hint.bhnd_nvram.0.at="nexus0" Index: sys/mips/conf/SWARM =================================================================== --- sys/mips/conf/SWARM +++ /dev/null @@ -1,12 +0,0 @@ -# -# $FreeBSD$ -# - -include "std.SWARM" - -ident SWARM - -machine mips mips - -makeoptions ARCH_FLAGS="-mabi=32 -march=mips32" -makeoptions LDSCRIPT_NAME= ldscript.mips.cfe Index: sys/mips/conf/SWARM.hints =================================================================== --- sys/mips/conf/SWARM.hints +++ /dev/null @@ -1,17 +0,0 @@ -# $FreeBSD$ -hint.zbbus.0.at="nexus0" -hint.zbpci.0.at="zbbus0" -hint.scd.0.at="zbbus0" - -# -# SWARM IDE interface is on the generic bus at chip select 4. -# The CS4 region is 64KB in size and starts at 0x100B0000. -# The IDE interrupt is wired to GPIO4 (intsrc 36 to the interrupt mapper) -# -hint.ata.0.at="zbbus0" -hint.ata.0.maddr=0x100B0000 -hint.ata.0.msize=0x10000 -hint.ata.0.irq=36 -#hint.ata.0.disabled=0 -#hint.ata.0.regoffset=0x1F0 -#hint.ata.0.regshift=5 Index: sys/mips/conf/SWARM64 =================================================================== --- sys/mips/conf/SWARM64 +++ /dev/null @@ -1,12 +0,0 @@ -# -# $FreeBSD$ -# - -include "std.SWARM" - -ident SWARM64 - -machine mips mips64 -makeoptions ARCH_FLAGS="-mabi=64 -march=mips64" -makeoptions LDSCRIPT_NAME=ldscript.mips.cfe -makeoptions KERNLOADADDR=0xffffffff80001000 Index: sys/mips/conf/SWARM64_SMP =================================================================== --- sys/mips/conf/SWARM64_SMP +++ /dev/null @@ -1,15 +0,0 @@ -# -# $FreeBSD$ -# - -include "std.SWARM" - -ident SWARM64_SMP - -options SMP -options PRINTF_BUFR_SIZE=128 - -machine mips mips64 -makeoptions ARCH_FLAGS="-mabi=64 -march=mips64" -makeoptions LDSCRIPT_NAME=ldscript.mips.cfe -makeoptions KERNLOADADDR=0xffffffff80001000 Index: sys/mips/conf/SWARM_SMP =================================================================== --- sys/mips/conf/SWARM_SMP +++ /dev/null @@ -1,15 +0,0 @@ -# -# $FreeBSD$ -# - -include "std.SWARM" - -ident SWARM_SMP - -options SMP -options PRINTF_BUFR_SIZE=128 - -machine mips mips - -makeoptions ARCH_FLAGS="-mabi=32 -march=mips32" -makeoptions LDSCRIPT_NAME= ldscript.mips.cfe Index: sys/mips/conf/X1000 =================================================================== --- sys/mips/conf/X1000 +++ /dev/null @@ -1,95 +0,0 @@ -# X1000 -- Kernel config for Ingenic X1000 boards -# -# $FreeBSD$ - -#NO_UNIVERSE - -ident X1000 -machine mips mipsel -cpu CPU_XBURST -cpu CPU_MIPS4KC - -makeoptions KERNLOADADDR=0x80020000 -makeoptions ARCH_FLAGS="-EL -march=mips32r2" - -# Don't build any modules yet. -makeoptions MODULES_OVERRIDE="" - -files "../ingenic/files.x1000" -hints "X1000.hints" #Default places to look for devices. - -makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols - -options INTRNG # Borrow interrupt code from ARM -options MIPS_NIRQ=264 # 8 cpuintc + 64 intc + 6 * 23 gpio - -options DDB -options KDB -options BREAK_TO_DEBUGGER - -options COMPAT_FREEBSD10 -options COMPAT_FREEBSD11 - -options SCHED_4BSD #4BSD scheduler -options INET #InterNETworking -options NFSCL #Network Filesystem Client -options NFS_ROOT #NFS usable as /, requires NFSCL -options NFSLOCKD #Network Lock Manager -options PSEUDOFS #Pseudo-filesystem framework -options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions - -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 ROOTDEVNAME=\"ufs:ada0\" - -options GEOM_LABEL # Provides labelization -options GEOM_PART_GPT # GUID Partition Tables. -#options GEOM_RAID # Soft RAID functionality. - -# Debugging for use in -current -#options DEADLKRES #Enable the deadlock resolver -options INVARIANTS #Enable calls of extra sanity checking -options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS -#options WITNESS #Enable checks to detect deadlocks and cycles -#options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed - -device loop -device ether -#device le -device miibus -device bpf -device md -device uart -device random - -device fdt_pinctrl - -device clk -device regulator -options EXT_RESOURCES - -device gpio - -device scbus -device da - -device mmc -device mmcsd - -# USB support -#options USB_DEBUG # enable debug msgs -#options USB_HOST_ALIGN=128 # L2 cache line size -#device ohci # OHCI PCI->USB interface -#device ehci # EHCI PCI->USB interface (USB 2.0) -#device dwcotg # DesignWare HS OTG controller -#device usb # USB Bus (required) -#device udbp # USB Double Bulk Pipe devices -#device uhid # "Human Interface Devices" -#device ulpt # Printer -#device umass # Disks/Mass storage - Requires scbus and da -#device ums # Mouse - -# FDT support -options FDT Index: sys/mips/conf/X1000.hints =================================================================== --- sys/mips/conf/X1000.hints +++ /dev/null @@ -1,2 +0,0 @@ -# $FreeBSD$ -# device.hints Index: sys/mips/conf/XLP =================================================================== --- sys/mips/conf/XLP +++ /dev/null @@ -1,28 +0,0 @@ -# XLP -- Generic kernel configuration file for FreeBSD/mips -# -# 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$ - -machine mips mips -ident XLP - -makeoptions KERNLOADADDR=0x80100000 - -include "std.XLP" - -makeoptions TRAMPLOADADDR=0xffffffff85000000 -makeoptions TRAMP_ARCH_FLAGS="-mabi=64 -march=mips64" Index: sys/mips/conf/std.AR5312 =================================================================== --- sys/mips/conf/std.AR5312 +++ /dev/null @@ -1,81 +0,0 @@ -# -# AR5312 -- Kernel configuration file for FreeBSD/MIPS for Atheros 5312 systems -# -# This includes all the common drivers for the AR5312 boards -# -# $FreeBSD$ -# - -machine mips mips -#ident AR5312_BASE -cpu CPU_MIPS4KC -makeoptions KERNLOADADDR=0x80050000 -options HZ=1000 - -makeoptions MODULES_OVERRIDE="" - -files "../atheros/ar531x/files.ar5315" - -options INTRNG -options AR531X_1ST_GENERATION - -# For now, hints are per-board. - -hints "AR5312_BASE.hints" - -makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols - -# For small memory footprints -options VM_KMEM_SIZE_SCALE=1 - -options DDB -options KDB - -options SCHED_4BSD #4BSD scheduler -options INET #InterNETworking -options INET6 # IPv6 -options TCP_HHOOK # hhook(9) framework for TCP - -# options NFSCL #Network Filesystem Client - -options PSEUDOFS #Pseudo-filesystem framework -options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions - -# options NFS_LEGACYRPC -# Debugging for use in -current -options INVARIANTS -options INVARIANT_SUPPORT -options WITNESS -options WITNESS_SKIPSPIN -options DEBUG_REDZONE -options DEBUG_MEMGUARD - -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 MSDOSFS # Read MSDOS filesystems; useful for USB/CF - -device mii -device are - -device cfi -options CFI_HARDWAREBYTESWAP -device geom_redboot - -device ar5315_wdog - -device uart -device uart_ar5315 - -device loop -device ether -device md -device bpf -device random - -options ARGE_DEBUG # Enable if_arge debugging for now - -# Enable GPIO -device gpio -device gpioled Index: sys/mips/conf/std.AR5315 =================================================================== --- sys/mips/conf/std.AR5315 +++ /dev/null @@ -1,81 +0,0 @@ -# -# AR5315 -- Kernel configuration file for FreeBSD/MIPS for Atheros 5315 systems -# -# This includes all the common drivers for the AR5315 boards -# -# $FreeBSD$ -# - -machine mips mips -#ident AR5315_BASE -cpu CPU_MIPS4KC -makeoptions KERNLOADADDR=0x80050000 -options HZ=1000 - -makeoptions MODULES_OVERRIDE="" - -files "../atheros/ar531x/files.ar5315" - -options INTRNG - -# For now, hints are per-board. - -hints "AR5315_BASE.hints" - -makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols - -# For small memory footprints -options VM_KMEM_SIZE_SCALE=1 - -options DDB -options KDB - -options SCHED_4BSD #4BSD scheduler -options INET #InterNETworking -options INET6 # IPv6 -options TCP_HHOOK # hhook(9) framework for TCP - -# options NFSCL #Network Filesystem Client - -options PSEUDOFS #Pseudo-filesystem framework -options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions - -# options NFS_LEGACYRPC -# Debugging for use in -current -options INVARIANTS -options INVARIANT_SUPPORT -options WITNESS -options WITNESS_SKIPSPIN -options DEBUG_REDZONE -options DEBUG_MEMGUARD - -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 MSDOSFS # Read MSDOS filesystems; useful for USB/CF - -device mii -device are - -device ar5315_spi -device spibus -device mx25l -device geom_redboot - -device ar5315_wdog - -device uart -device uart_ar5315 - -device loop -device ether -device md -device bpf -device random - -options ARGE_DEBUG # Enable if_arge debugging for now - -# Enable GPIO -device gpio -device gpioled Index: sys/mips/conf/std.SWARM =================================================================== --- sys/mips/conf/std.SWARM +++ /dev/null @@ -1,60 +0,0 @@ -# -# $FreeBSD$ -# - -hints "SWARM.hints" -include "../sibyte/std.sibyte" - -options CFE -options CFE_CONSOLE -options CFE_ENV -options ALT_BREAK_TO_DEBUGGER - -cpu CPU_SB1 - -makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols -makeoptions MODULES_OVERRIDE="" - -options DDB -options KDB - -options SCHED_4BSD #4BSD scheduler -options INET #InterNETworking -options TCP_HHOOK # hhook(9) framework for TCP -options NFSCL #Network Filesystem Client -options NFS_ROOT #NFS usable as /, requires NFSCL -options PSEUDOFS #Pseudo-filesystem framework -options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions - -# Debugging for use in -current -#options DEADLKRES -options INVARIANTS -options INVARIANT_SUPPORT -options WITNESS - -options FFS #Fast filesystem - -options KTRACE - -device pci -device miibus -device bge -device loop -device ether -device md -device random - -options USB_DEBUG -device usb -device ohci -device uhci -device ehci - -device umass - -device scbus -device cd -device da -device pass - -device ata Index: sys/mips/gxemul/files.gxemul =================================================================== --- sys/mips/gxemul/files.gxemul +++ /dev/null @@ -1,8 +0,0 @@ -# $FreeBSD$ -dev/gxemul/cons/gxemul_cons.c optional gxemul_cons -mips/gxemul/gxemul_machdep.c standard -mips/mips/intr_machdep.c standard -mips/mips/tick.c standard - -dev/gxemul/disk/gxemul_disk.c optional gxemul_disk -dev/gxemul/ether/if_gx.c optional gxemul_ether Index: sys/mips/gxemul/gxemul_machdep.c =================================================================== --- sys/mips/gxemul/gxemul_machdep.c +++ /dev/null @@ -1,247 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2006 Wojciech A. Koszek - * 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 "opt_ddb.h" - -#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 - -#ifdef SMP -#include -#include -#endif - -#include - -extern int *edata; -extern int *end; - -void -platform_cpu_init() -{ - /* Nothing special */ -} - -static void -mips_init(void) -{ - int i; - - for (i = 0; i < 10; i++) { - phys_avail[i] = 0; - } - - /* phys_avail regions are in bytes */ - phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end); - phys_avail[1] = ctob(realmem); - - dump_avail[0] = phys_avail[0]; - dump_avail[1] = phys_avail[1]; - - physmem = realmem; - - init_param1(); - init_param2(physmem); - mips_cpu_init(); - pmap_bootstrap(); - mips_proc0_init(); - mutex_init(); - kdb_init(); -#ifdef KDB - if (boothowto & RB_KDB) - kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); -#endif -} - -/* - * Perform a board-level soft-reset. - * - * XXXRW: Does gxemul have a moral equivalent to board-level reset? - */ -void -platform_reset(void) -{ - - panic("%s: not yet", __func__); -} - -void -platform_start(__register_t a0, __register_t a1, __register_t a2, - __register_t a3) -{ - vm_offset_t kernend; - uint64_t platform_counter_freq; - int argc = a0; - char **argv = (char **)a1; - char **envp = (char **)a2; - int i; - - /* clear the BSS and SBSS segments */ - kernend = (vm_offset_t)&end; - memset(&edata, 0, kernend - (vm_offset_t)(&edata)); - - mips_postboot_fixup(); - - mips_pcpu0_init(); - - /* - * XXXRW: Support for the gxemul real-time clock required in order to - * usefully determine our emulated timer frequency. Go with something - * classic as the default in the mean time. - */ - platform_counter_freq = MIPS_DEFAULT_HZ; - mips_timer_early_init(platform_counter_freq); - - cninit(); - printf("entry: platform_start()\n"); - - bootverbose = 1; - if (bootverbose) { - printf("cmd line: "); - for (i = 0; i < argc; i++) - printf("%s ", argv[i]); - printf("\n"); - - if (envp != NULL) { - printf("envp:\n"); - for (i = 0; envp[i]; i += 2) - printf("\t%s = %s\n", envp[i], envp[i+1]); - } else { - printf("no envp.\n"); - } - } - - realmem = btoc(GXEMUL_MP_DEV_READ(GXEMUL_MP_DEV_MEMORY)); - mips_init(); - - mips_timer_init_params(platform_counter_freq, 0); -} - -#ifdef SMP -void -platform_ipi_send(int cpuid) -{ - GXEMUL_MP_DEV_WRITE(GXEMUL_MP_DEV_IPI_ONE, (1 << 16) | cpuid); -} - -void -platform_ipi_clear(void) -{ - GXEMUL_MP_DEV_WRITE(GXEMUL_MP_DEV_IPI_READ, 0); -} - -int -platform_ipi_hardintr_num(void) -{ - - return (GXEMUL_MP_DEV_IPI_INTERRUPT - 2); -} - -int -platform_ipi_softintr_num(void) -{ - - return (-1); -} - -struct cpu_group * -platform_smp_topo(void) -{ - return (smp_topo_none()); -} - -void -platform_init_ap(int cpuid) -{ - int ipi_int_mask, clock_int_mask; - - /* - * Unmask the clock and ipi interrupts. - */ - clock_int_mask = hard_int_mask(5); - ipi_int_mask = hard_int_mask(platform_ipi_hardintr_num()); - set_intr_mask(ipi_int_mask | clock_int_mask); -} - -void -platform_cpu_mask(cpuset_t *mask) -{ - unsigned i, n; - - n = GXEMUL_MP_DEV_READ(GXEMUL_MP_DEV_NCPUS); - CPU_ZERO(mask); - for (i = 0; i < n; i++) - CPU_SET(i, mask); -} - -int -platform_processor_id(void) -{ - return (GXEMUL_MP_DEV_READ(GXEMUL_MP_DEV_WHOAMI)); -} - -int -platform_start_ap(int cpuid) -{ - GXEMUL_MP_DEV_WRITE(GXEMUL_MP_DEV_STARTADDR, (intptr_t)mpentry); - GXEMUL_MP_DEV_WRITE(GXEMUL_MP_DEV_START, cpuid); - return (0); -} -#endif /* SMP */ Index: sys/mips/gxemul/mpreg.h =================================================================== --- sys/mips/gxemul/mpreg.h +++ /dev/null @@ -1,64 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2004-2012 Juli Mallett - * 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 _MIPS_GXEMUL_MPREG_H_ -#define _MIPS_GXEMUL_MPREG_H_ - -#define GXEMUL_MP_DEV_BASE 0x11000000 - -#define GXEMUL_MP_DEV_WHOAMI 0x0000 -#define GXEMUL_MP_DEV_NCPUS 0x0010 -#define GXEMUL_MP_DEV_START 0x0020 -#define GXEMUL_MP_DEV_STARTADDR 0x0030 -#define GXEMUL_MP_DEV_STACK 0x0070 -#define GXEMUL_MP_DEV_RANDOM 0x0080 -#define GXEMUL_MP_DEV_MEMORY 0x0090 -#define GXEMUL_MP_DEV_IPI_ONE 0x00a0 -#define GXEMUL_MP_DEV_IPI_MANY 0x00b0 -#define GXEMUL_MP_DEV_IPI_READ 0x00c0 -#define GXEMUL_MP_DEV_CYCLES 0x00d0 - -#ifdef _LP64 -#define GXEMUL_MP_DEV_FUNCTION(f) \ - (volatile uint64_t *)MIPS_PHYS_TO_DIRECT_UNCACHED(GXEMUL_MP_DEV_BASE + (f)) -#define GXEMUL_MP_DEV_READ(f) \ - (volatile uint64_t)*GXEMUL_MP_DEV_FUNCTION(f) -#else -#define GXEMUL_MP_DEV_FUNCTION(f) \ - (volatile uint32_t *)MIPS_PHYS_TO_DIRECT_UNCACHED(GXEMUL_MP_DEV_BASE + (f)) -#define GXEMUL_MP_DEV_READ(f) \ - (volatile uint32_t)*GXEMUL_MP_DEV_FUNCTION(f) -#endif -#define GXEMUL_MP_DEV_WRITE(f, v) \ - *GXEMUL_MP_DEV_FUNCTION(f) = (v) - -#define GXEMUL_MP_DEV_IPI_INTERRUPT (6) - -#endif /* !_MIPS_GXEMUL_MPREG_H */ Index: sys/mips/gxemul/std.gxemul =================================================================== --- sys/mips/gxemul/std.gxemul +++ /dev/null @@ -1,4 +0,0 @@ -# $FreeBSD$ -files "../gxemul/files.gxemul" - -cpu CPU_MIPS4KC Index: sys/mips/ingenic/files.jz4780 =================================================================== --- sys/mips/ingenic/files.jz4780 +++ /dev/null @@ -1,39 +0,0 @@ -# $FreeBSD$ - -mips/ingenic/jz4780_dwc_fdt.c optional dwcotg -mips/ingenic/jz4780_ehci.c optional ehci -mips/ingenic/jz4780_mmc.c optional mmc -mips/ingenic/jz4780_ohci.c optional ohci -mips/ingenic/jz4780_smb.c optional iicbus -mips/ingenic/jz4780_uart.c optional uart -mips/ingenic/jz4780_lcd.c optional vt -dev/hdmi/dwc_hdmi.c optional hdmi iicbus -dev/hdmi/dwc_hdmi_fdt.c optional hdmi iicbus - -mips/ingenic/jz4780_clock.c standard -mips/ingenic/jz4780_clk_gen.c standard -mips/ingenic/jz4780_clk_otg.c standard -mips/ingenic/jz4780_clk_pll.c standard -mips/ingenic/jz4780_efuse.c standard -mips/ingenic/jz4780_intr.c standard -mips/ingenic/jz4780_gpio.c standard -mips/ingenic/jz4780_machdep.c standard -mips/ingenic/jz4780_nemc.c standard -mips/ingenic/jz4780_pdma.c standard -mips/ingenic/jz4780_pinctrl.c standard -mips/ingenic/jz4780_rtc.c standard -mips/ingenic/jz4780_timer.c standard - -# Sound -mips/ingenic/jz4780_aic.c optional sound xdma -mips/ingenic/jz4780_codec.c optional sound - -# SMP -mips/ingenic/jz4780_mp.c optional smp -mips/ingenic/jz4780_mpboot.S optional smp - -# Custom interface between pinctrl and gpio -mips/ingenic/jz4780_gpio_if.m standard - -# HDMI interface -dev/hdmi/hdmi_if.m standard Index: sys/mips/ingenic/files.x1000 =================================================================== --- sys/mips/ingenic/files.x1000 +++ /dev/null @@ -1,22 +0,0 @@ -# $FreeBSD$ - -mips/ingenic/jz4780_mmc.c optional mmc -mips/ingenic/jz4780_uart.c optional uart - -mips/ingenic/jz4780_clock.c standard -mips/ingenic/jz4780_clk_gen.c standard -mips/ingenic/jz4780_clk_otg.c standard -mips/ingenic/jz4780_clk_pll.c standard -mips/ingenic/jz4780_intr.c standard -mips/ingenic/jz4780_gpio.c standard -mips/ingenic/jz4780_machdep.c standard -mips/ingenic/jz4780_pdma.c standard -mips/ingenic/jz4780_pinctrl.c standard -mips/ingenic/jz4780_timer.c standard - -# Sound -mips/ingenic/jz4780_aic.c optional sound xdma -mips/ingenic/jz4780_codec.c optional sound - -# Custom interface between pinctrl and gpio -mips/ingenic/jz4780_gpio_if.m standard Index: sys/mips/ingenic/jz4780_aic.h =================================================================== --- sys/mips/ingenic/jz4780_aic.h +++ /dev/null @@ -1,74 +0,0 @@ -/*- - * Copyright (c) 2016 Ruslan Bukin - * All rights reserved. - * - * This software was developed by SRI International and the University of - * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 - * ("CTSRD"), as part of the DARPA CRASH research programme. - * - * 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$ - */ - -#define AICFR 0x00 /* AIC Configuration Register */ -#define AICFR_TFTH_S 16 /* Transmit FIFO threshold for interrupt or DMA request. */ -#define AICFR_TFTH_M (0x1f << AICFR_TFTH_S) -#define AICFR_TFTH(x) ((x) << AICFR_TFTH_S) -#define AICFR_RFTH_S 24 /* Receive FIFO threshold for interrupt or DMA request. */ -#define AICFR_RFTH_M (0x0f << AICFR_RFTH_S) -#define AICFR_RFTH(x) ((x) << AICFR_RFTH_S) -#define AICFR_ICDC (1 << 5) /* Internal CODEC used. */ -#define AICFR_AUSEL (1 << 4) /* Audio Unit Select */ -#define AICFR_RST (1 << 3) /* Reset AIC. */ -#define AICFR_BCKD (1 << 2) /* BIT_CLK Direction. */ -#define AICFR_SYNCD (1 << 1) /* SYNC is generated internally and driven out to the CODEC. */ -#define AICFR_ENB (1 << 0) /* Enable AIC Controller. */ -#define AICCR 0x04 /* AIC Common Control Register */ -#define AICCR_TFLUSH (1 << 8) /* Transmit FIFO Flush. */ -#define AICCR_RFLUSH (1 << 7) /* Receive FIFO Flush. */ -#define AICCR_CHANNEL_S 24 -#define AICCR_CHANNEL_M (0x7 << AICCR_CHANNEL_S) -#define AICCR_CHANNEL_2 (0x1 << AICCR_CHANNEL_S) /* 2 channels, stereo */ -#define AICCR_ISS_S 16 /* Input Sample Size. */ -#define AICCR_ISS_M (0x7 << AICCR_ISS_S) -#define AICCR_ISS_16 (0x1 << AICCR_ISS_S) -#define AICCR_OSS_S 19 /* Output Sample Size. */ -#define AICCR_OSS_M (0x7 << AICCR_OSS_S) -#define AICCR_OSS_16 (0x1 << AICCR_OSS_S) -#define AICCR_RDMS (1 << 15) /* Receive DMA enable. */ -#define AICCR_TDMS (1 << 14) /* Transmit DMA enable. */ -#define AICCR_ENLBF (1 << 2) /* Enable AIC Loop Back Function. */ -#define AICCR_ERPL (1 << 1) /* Enable Playing Back function. */ -#define I2SCR 0x10 /* AIC I2S/MSB-justified Control */ -#define I2SCR_ESCLK (1 << 4) /* Enable SYSCLK output. */ -#define I2SCR_AMSL (1 << 0) /* Select MSB-Justified Operation Mode. */ -#define AICSR 0x14 /* AIC FIFO Status Register Register */ -#define I2SSR 0x1C /* AIC I2S/MSB-justified Status Register */ -#define I2SDIV 0x30 /* AIC I2S/MSB-justified Clock Divider Register */ -#define AICDR 0x34 /* AIC FIFO Data Port Register */ -#define SPENA 0x80 /* SPDIF Enable Register */ -#define SPCTRL 0x84 /* SPDIF Control Register */ -#define SPSTATE 0x88 /* SPDIF Status Register */ -#define SPCFG1 0x8C /* SPDIF Configure 1 Register */ -#define SPCFG2 0x90 /* SPDIF Configure 2 Register */ -#define SPFIFO 0x94 /* SPDIF FIFO Register */ Index: sys/mips/ingenic/jz4780_aic.c =================================================================== --- sys/mips/ingenic/jz4780_aic.c +++ /dev/null @@ -1,809 +0,0 @@ -/*- - * Copyright (c) 2016-2018 Ruslan Bukin - * All rights reserved. - * - * This software was developed by SRI International and the University of - * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 - * ("CTSRD"), as part of the DARPA CRASH research programme. - * - * 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. - */ - -/* Ingenic JZ4780 Audio Interface Controller (AIC). */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include - -#define AIC_NCHANNELS 1 - -struct aic_softc { - device_t dev; - struct resource *res[1]; - bus_space_tag_t bst; - bus_space_handle_t bsh; - struct mtx *lock; - int pos; - bus_dma_tag_t dma_tag; - bus_dmamap_t dma_map; - bus_addr_t buf_base_phys; - uint32_t *buf_base; - uintptr_t aic_fifo_paddr; - int dma_size; - clk_t clk_aic; - clk_t clk_i2s; - struct aic_rate *sr; - void *ih; - int internal_codec; - - /* xDMA */ - struct xdma_channel *xchan; - xdma_controller_t *xdma_tx; - struct xdma_request req; -}; - -/* Channel registers */ -struct sc_chinfo { - struct snd_dbuf *buffer; - struct pcm_channel *channel; - struct sc_pcminfo *parent; - - /* Channel information */ - uint32_t dir; - uint32_t format; - - /* Flags */ - uint32_t run; -}; - -/* PCM device private data */ -struct sc_pcminfo { - device_t dev; - uint32_t chnum; - struct sc_chinfo chan[AIC_NCHANNELS]; - struct aic_softc *sc; -}; - -static struct resource_spec aic_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE }, - { -1, 0 } -}; - -static int aic_probe(device_t dev); -static int aic_attach(device_t dev); -static int aic_detach(device_t dev); -static int setup_xdma(struct sc_pcminfo *scp); - -struct aic_rate { - uint32_t speed; -}; - -static struct aic_rate rate_map[] = { - { 48000 }, - /* TODO: add more frequences */ - { 0 }, -}; - -/* - * Mixer interface. - */ -static int -aicmixer_init(struct snd_mixer *m) -{ - struct sc_pcminfo *scp; - struct aic_softc *sc; - int mask; - - scp = mix_getdevinfo(m); - sc = scp->sc; - - if (sc == NULL) - return -1; - - mask = SOUND_MASK_PCM; - - snd_mtxlock(sc->lock); - pcm_setflags(scp->dev, pcm_getflags(scp->dev) | SD_F_SOFTPCMVOL); - mix_setdevs(m, mask); - snd_mtxunlock(sc->lock); - - return (0); -} - -static int -aicmixer_set(struct snd_mixer *m, unsigned dev, - unsigned left, unsigned right) -{ - struct sc_pcminfo *scp; - - scp = mix_getdevinfo(m); - - /* Here we can configure hardware volume on our DAC */ - - return (0); -} - -static kobj_method_t aicmixer_methods[] = { - KOBJMETHOD(mixer_init, aicmixer_init), - KOBJMETHOD(mixer_set, aicmixer_set), - KOBJMETHOD_END -}; -MIXER_DECLARE(aicmixer); - -/* - * Channel interface. - */ -static void * -aicchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, - struct pcm_channel *c, int dir) -{ - struct sc_pcminfo *scp; - struct sc_chinfo *ch; - struct aic_softc *sc; - - scp = (struct sc_pcminfo *)devinfo; - sc = scp->sc; - - snd_mtxlock(sc->lock); - ch = &scp->chan[0]; - ch->dir = dir; - ch->run = 0; - ch->buffer = b; - ch->channel = c; - ch->parent = scp; - snd_mtxunlock(sc->lock); - - if (sndbuf_setup(ch->buffer, sc->buf_base, sc->dma_size) != 0) { - device_printf(scp->dev, "Can't setup sndbuf.\n"); - return NULL; - } - - return (ch); -} - -static int -aicchan_free(kobj_t obj, void *data) -{ - struct sc_chinfo *ch = data; - struct sc_pcminfo *scp = ch->parent; - struct aic_softc *sc = scp->sc; - - snd_mtxlock(sc->lock); - /* TODO: free channel buffer */ - snd_mtxunlock(sc->lock); - - return (0); -} - -static int -aicchan_setformat(kobj_t obj, void *data, uint32_t format) -{ - struct sc_pcminfo *scp; - struct sc_chinfo *ch; - - ch = data; - scp = ch->parent; - - ch->format = format; - - return (0); -} - -static uint32_t -aicchan_setspeed(kobj_t obj, void *data, uint32_t speed) -{ - struct sc_pcminfo *scp; - struct sc_chinfo *ch; - struct aic_rate *sr; - struct aic_softc *sc; - int threshold; - int i; - - ch = data; - scp = ch->parent; - sc = scp->sc; - - sr = NULL; - - /* First look for equal frequency. */ - for (i = 0; rate_map[i].speed != 0; i++) { - if (rate_map[i].speed == speed) - sr = &rate_map[i]; - } - - /* If no match, just find nearest. */ - if (sr == NULL) { - for (i = 0; rate_map[i].speed != 0; i++) { - sr = &rate_map[i]; - threshold = sr->speed + ((rate_map[i + 1].speed != 0) ? - ((rate_map[i + 1].speed - sr->speed) >> 1) : 0); - if (speed < threshold) - break; - } - } - - sc->sr = sr; - - /* Clocks can be reconfigured here. */ - - return (sr->speed); -} - -static uint32_t -aicchan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) -{ - struct sc_pcminfo *scp; - struct sc_chinfo *ch; - struct aic_softc *sc; - - ch = data; - scp = ch->parent; - sc = scp->sc; - - sndbuf_resize(ch->buffer, sc->dma_size / blocksize, blocksize); - - return (sndbuf_getblksz(ch->buffer)); -} - -static int -aic_intr(void *arg, xdma_transfer_status_t *status) -{ - struct sc_pcminfo *scp; - struct xdma_request *req; - xdma_channel_t *xchan; - struct sc_chinfo *ch; - struct aic_softc *sc; - int bufsize; - - scp = arg; - sc = scp->sc; - ch = &scp->chan[0]; - req = &sc->req; - - xchan = sc->xchan; - - bufsize = sndbuf_getsize(ch->buffer); - - sc->pos += req->block_len; - if (sc->pos >= bufsize) - sc->pos -= bufsize; - - if (ch->run) - chn_intr(ch->channel); - - return (0); -} - -static int -setup_xdma(struct sc_pcminfo *scp) -{ - struct aic_softc *sc; - struct sc_chinfo *ch; - int fmt; - int err; - - ch = &scp->chan[0]; - sc = scp->sc; - - fmt = sndbuf_getfmt(ch->buffer); - - KASSERT(fmt & AFMT_16BIT, ("16-bit audio supported only.")); - - sc->req.operation = XDMA_CYCLIC; - sc->req.req_type = XR_TYPE_PHYS; - sc->req.direction = XDMA_MEM_TO_DEV; - sc->req.src_addr = sc->buf_base_phys; - sc->req.dst_addr = sc->aic_fifo_paddr; - sc->req.src_width = 2; - sc->req.dst_width = 2; - sc->req.block_len = sndbuf_getblksz(ch->buffer); - sc->req.block_num = sndbuf_getblkcnt(ch->buffer); - - err = xdma_request(sc->xchan, &sc->req); - if (err != 0) { - device_printf(sc->dev, "Can't configure virtual channel\n"); - return (-1); - } - - xdma_control(sc->xchan, XDMA_CMD_BEGIN); - - return (0); -} - -static int -aic_start(struct sc_pcminfo *scp) -{ - struct aic_softc *sc; - int reg; - - sc = scp->sc; - - /* Ensure clock enabled. */ - reg = READ4(sc, I2SCR); - reg |= (I2SCR_ESCLK); - WRITE4(sc, I2SCR, reg); - - setup_xdma(scp); - - reg = (AICCR_OSS_16 | AICCR_ISS_16); - reg |= (AICCR_CHANNEL_2); - reg |= (AICCR_TDMS); - reg |= (AICCR_ERPL); - WRITE4(sc, AICCR, reg); - - return (0); -} - -static int -aic_stop(struct sc_pcminfo *scp) -{ - struct aic_softc *sc; - int reg; - - sc = scp->sc; - - reg = READ4(sc, AICCR); - reg &= ~(AICCR_TDMS | AICCR_ERPL); - WRITE4(sc, AICCR, reg); - - xdma_control(sc->xchan, XDMA_CMD_TERMINATE); - - return (0); -} - -static int -aicchan_trigger(kobj_t obj, void *data, int go) -{ - struct sc_pcminfo *scp; - struct sc_chinfo *ch; - struct aic_softc *sc; - - ch = data; - scp = ch->parent; - sc = scp->sc; - - snd_mtxlock(sc->lock); - - switch (go) { - case PCMTRIG_START: - ch->run = 1; - - sc->pos = 0; - - aic_start(scp); - - break; - - case PCMTRIG_STOP: - case PCMTRIG_ABORT: - ch->run = 0; - - aic_stop(scp); - - sc->pos = 0; - - bzero(sc->buf_base, sc->dma_size); - - break; - } - - snd_mtxunlock(sc->lock); - - return (0); -} - -static uint32_t -aicchan_getptr(kobj_t obj, void *data) -{ - struct sc_pcminfo *scp; - struct sc_chinfo *ch; - struct aic_softc *sc; - - ch = data; - scp = ch->parent; - sc = scp->sc; - - return (sc->pos); -} - -static uint32_t aic_pfmt[] = { - SND_FORMAT(AFMT_S16_LE, 2, 0), - 0 -}; - -static struct pcmchan_caps aic_pcaps = {48000, 48000, aic_pfmt, 0}; - -static struct pcmchan_caps * -aicchan_getcaps(kobj_t obj, void *data) -{ - - return (&aic_pcaps); -} - -static kobj_method_t aicchan_methods[] = { - KOBJMETHOD(channel_init, aicchan_init), - KOBJMETHOD(channel_free, aicchan_free), - KOBJMETHOD(channel_setformat, aicchan_setformat), - KOBJMETHOD(channel_setspeed, aicchan_setspeed), - KOBJMETHOD(channel_setblocksize, aicchan_setblocksize), - KOBJMETHOD(channel_trigger, aicchan_trigger), - KOBJMETHOD(channel_getptr, aicchan_getptr), - KOBJMETHOD(channel_getcaps, aicchan_getcaps), - KOBJMETHOD_END -}; -CHANNEL_DECLARE(aicchan); - -static void -aic_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err) -{ - bus_addr_t *addr; - - if (err) - return; - - addr = (bus_addr_t*)arg; - *addr = segs[0].ds_addr; -} - -static int -aic_dma_setup(struct aic_softc *sc) -{ - device_t dev; - int err; - - dev = sc->dev; - - /* DMA buffer size. */ - sc->dma_size = 131072; - - /* - * Must use dma_size boundary as modulo feature required. - * Modulo feature allows setup circular buffer. - */ - err = bus_dma_tag_create( - bus_get_dma_tag(sc->dev), - 4, sc->dma_size, /* alignment, boundary */ - BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filter, filterarg */ - sc->dma_size, 1, /* maxsize, nsegments */ - sc->dma_size, 0, /* maxsegsize, flags */ - NULL, NULL, /* lockfunc, lockarg */ - &sc->dma_tag); - if (err) { - device_printf(dev, "cannot create bus dma tag\n"); - return (-1); - } - - err = bus_dmamem_alloc(sc->dma_tag, (void **)&sc->buf_base, - BUS_DMA_WAITOK | BUS_DMA_COHERENT, &sc->dma_map); - if (err) { - device_printf(dev, "cannot allocate memory\n"); - return (-1); - } - - err = bus_dmamap_load(sc->dma_tag, sc->dma_map, sc->buf_base, - sc->dma_size, aic_dmamap_cb, &sc->buf_base_phys, BUS_DMA_WAITOK); - if (err) { - device_printf(dev, "cannot load DMA map\n"); - return (-1); - } - - bzero(sc->buf_base, sc->dma_size); - - return (0); -} - -static int -aic_configure_clocks(struct aic_softc *sc) -{ - uint64_t aic_freq; - uint64_t i2s_freq; - device_t dev; - int err; - - dev = sc->dev; - - err = clk_get_by_ofw_name(sc->dev, 0, "aic", &sc->clk_aic); - if (err != 0) { - device_printf(dev, "Can't find aic clock.\n"); - return (-1); - } - - err = clk_enable(sc->clk_aic); - if (err != 0) { - device_printf(dev, "Can't enable aic clock.\n"); - return (-1); - } - - err = clk_get_by_ofw_name(sc->dev, 0, "i2s", &sc->clk_i2s); - if (err != 0) { - device_printf(dev, "Can't find i2s clock.\n"); - return (-1); - } - - err = clk_enable(sc->clk_i2s); - if (err != 0) { - device_printf(dev, "Can't enable i2s clock.\n"); - return (-1); - } - - err = clk_set_freq(sc->clk_i2s, 12000000, 0); - if (err != 0) { - device_printf(dev, "Can't set i2s frequency.\n"); - return (-1); - } - - clk_get_freq(sc->clk_aic, &aic_freq); - clk_get_freq(sc->clk_i2s, &i2s_freq); - - device_printf(dev, "Frequency aic %d i2s %d\n", - (uint32_t)aic_freq, (uint32_t)i2s_freq); - - return (0); -} - -static int -aic_configure(struct aic_softc *sc) -{ - int reg; - - WRITE4(sc, AICFR, AICFR_RST); - - /* Configure AIC */ - reg = 0; - if (sc->internal_codec) { - reg |= (AICFR_ICDC); - } else { - reg |= (AICFR_SYNCD | AICFR_BCKD); - } - reg |= (AICFR_AUSEL); /* I2S/MSB-justified format. */ - reg |= (AICFR_TFTH(8)); /* Transmit FIFO threshold */ - reg |= (AICFR_RFTH(7)); /* Receive FIFO threshold */ - WRITE4(sc, AICFR, reg); - - reg = READ4(sc, AICFR); - reg |= (AICFR_ENB); /* Enable the controller. */ - WRITE4(sc, AICFR, reg); - - return (0); -} - -static int -sysctl_hw_pcm_internal_codec(SYSCTL_HANDLER_ARGS) -{ - struct sc_pcminfo *scp; - struct sc_chinfo *ch; - struct aic_softc *sc; - int error, val; - - if (arg1 == NULL) - return (EINVAL); - - scp = arg1; - sc = scp->sc; - ch = &scp->chan[0]; - - snd_mtxlock(sc->lock); - - val = sc->internal_codec; - error = sysctl_handle_int(oidp, &val, 0, req); - if (error || req->newptr == NULL) { - snd_mtxunlock(sc->lock); - return (error); - } - if (val < 0 || val > 1) { - snd_mtxunlock(sc->lock); - return (EINVAL); - } - - if (sc->internal_codec != val) { - sc->internal_codec = val; - if (ch->run) - aic_stop(scp); - aic_configure(sc); - if (ch->run) - aic_start(scp); - } - - snd_mtxunlock(sc->lock); - - return (0); -} - -static int -aic_probe(device_t dev) -{ - - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (!ofw_bus_is_compatible(dev, "ingenic,jz4780-i2s")) - return (ENXIO); - - device_set_desc(dev, "Audio Interface Controller"); - - return (BUS_PROBE_DEFAULT); -} - -static int -aic_attach(device_t dev) -{ - char status[SND_STATUSLEN]; - struct sc_pcminfo *scp; - struct aic_softc *sc; - int err; - - sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); - sc->dev = dev; - sc->pos = 0; - sc->internal_codec = 1; - - /* Get xDMA controller */ - sc->xdma_tx = xdma_ofw_get(sc->dev, "tx"); - if (sc->xdma_tx == NULL) { - device_printf(dev, "Can't find DMA controller.\n"); - return (ENXIO); - } - - /* Alloc xDMA virtual channel. */ - sc->xchan = xdma_channel_alloc(sc->xdma_tx, 0); - if (sc->xchan == NULL) { - device_printf(dev, "Can't alloc virtual DMA channel.\n"); - return (ENXIO); - } - - /* Setup sound subsystem */ - sc->lock = snd_mtxcreate(device_get_nameunit(dev), "aic softc"); - if (sc->lock == NULL) { - device_printf(dev, "Can't create mtx.\n"); - return (ENXIO); - } - - if (bus_alloc_resources(dev, aic_spec, sc->res)) { - device_printf(dev, - "could not allocate resources for device\n"); - return (ENXIO); - } - - /* Memory interface */ - sc->bst = rman_get_bustag(sc->res[0]); - sc->bsh = rman_get_bushandle(sc->res[0]); - sc->aic_fifo_paddr = rman_get_start(sc->res[0]) + AICDR; - - /* Setup PCM. */ - scp = malloc(sizeof(struct sc_pcminfo), M_DEVBUF, M_WAITOK | M_ZERO); - scp->sc = sc; - scp->dev = dev; - - /* Setup audio buffer. */ - err = aic_dma_setup(sc); - if (err != 0) { - device_printf(dev, "Can't setup sound buffer.\n"); - return (ENXIO); - } - - /* Setup clocks. */ - err = aic_configure_clocks(sc); - if (err != 0) { - device_printf(dev, "Can't configure clocks.\n"); - return (ENXIO); - } - - err = aic_configure(sc); - if (err != 0) { - device_printf(dev, "Can't configure AIC.\n"); - return (ENXIO); - } - - pcm_setflags(dev, pcm_getflags(dev) | SD_F_MPSAFE); - - /* Setup interrupt handler. */ - err = xdma_setup_intr(sc->xchan, aic_intr, scp, &sc->ih); - if (err) { - device_printf(sc->dev, - "Can't setup xDMA interrupt handler.\n"); - return (ENXIO); - } - - err = pcm_register(dev, scp, 1, 0); - if (err) { - device_printf(dev, "Can't register pcm.\n"); - return (ENXIO); - } - - scp->chnum = 0; - pcm_addchan(dev, PCMDIR_PLAY, &aicchan_class, scp); - scp->chnum++; - - snprintf(status, SND_STATUSLEN, "at %s", ofw_bus_get_name(dev)); - pcm_setstatus(dev, status); - - mixer_init(dev, &aicmixer_class, scp); - - /* Create device sysctl node. */ - SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), - OID_AUTO, "internal_codec", CTLTYPE_INT | CTLFLAG_RW, - scp, 0, sysctl_hw_pcm_internal_codec, "I", - "use internal audio codec"); - - return (0); -} - -static int -aic_detach(device_t dev) -{ - struct aic_softc *sc; - - sc = device_get_softc(dev); - - xdma_channel_free(sc->xchan); - - bus_release_resources(dev, aic_spec, sc->res); - - return (0); -} - -static device_method_t aic_pcm_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, aic_probe), - DEVMETHOD(device_attach, aic_attach), - DEVMETHOD(device_detach, aic_detach), - DEVMETHOD_END -}; - -static driver_t aic_pcm_driver = { - "pcm", - aic_pcm_methods, - PCM_SOFTC_SIZE, -}; - -DRIVER_MODULE(aic, simplebus, aic_pcm_driver, pcm_devclass, 0, 0); -MODULE_DEPEND(aic, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); -MODULE_VERSION(aic, 1); Index: sys/mips/ingenic/jz4780_clk.h =================================================================== --- sys/mips/ingenic/jz4780_clk.h +++ /dev/null @@ -1,93 +0,0 @@ -/*- - * Copyright 2015 Alexander Kabaev - * 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 _MIPS_INGENIC_JZ4780_CLK_H -#define _MIPS_INGENIC_JZ4780_CLK_H - -#include -#include - -/* Convenience bitfiled manipulation macros */ -#define REG_MSK(field) (((1u << field ## _WIDTH) - 1) << field ##_SHIFT) -#define REG_VAL(field, val) ((val) << field ##_SHIFT) -#define REG_CLR(reg, field) ((reg) & ~REG_MSK(field)) -#define REG_GET(reg, field) (((reg) & REG_MSK(field)) >> field ##_SHIFT) -#define REG_SET(reg, field, val) (REG_CLR(reg, field) | REG_VAL(field, val)) - -/* Common clock macros */ -#define CLK_LOCK(_sc) mtx_lock((_sc)->clk_mtx) -#define CLK_UNLOCK(_sc) mtx_unlock((_sc)->clk_mtx) - -#define CLK_WR_4(_sc, off, val) bus_write_4((_sc)->clk_res, (off), (val)) -#define CLK_RD_4(_sc, off) bus_read_4((_sc)->clk_res, (off)) - -struct jz4780_clk_mux_descr { - uint16_t mux_reg; - uint16_t mux_shift: 5; - uint16_t mux_bits: 5; - uint16_t mux_map: 4; /* Map into mux space */ -}; - -struct jz4780_clk_div_descr { - uint16_t div_reg; - uint16_t div_shift: 5; - uint16_t div_bits: 5; - uint16_t div_lg: 5; - int div_ce_bit: 6; /* -1, if CE bit is not present */ - int div_st_bit: 6; /* Can be negative */ - int div_busy_bit: 6; /* Can be negative */ -}; - -struct jz4780_clk_descr { - uint16_t clk_id: 6; - uint16_t clk_type: 3; - int clk_gate_bit: 7; /* Can be negative */ - struct jz4780_clk_mux_descr clk_mux; - struct jz4780_clk_div_descr clk_div; - const char *clk_name; - const char *clk_pnames[4]; -}; - -/* clk_type bits */ -#define CLK_MASK_GATE 0x01 -#define CLK_MASK_DIV 0x02 -#define CLK_MASK_MUX 0x04 - -extern int jz4780_clk_gen_register(struct clkdom *clkdom, - const struct jz4780_clk_descr *descr, struct mtx *dev_mtx, - struct resource *mem_res); - -extern int jz4780_clk_pll_register(struct clkdom *clkdom, - struct clknode_init_def *clkdef, struct mtx *dev_mtx, - struct resource *mem_res, uint32_t mem_reg); - -extern int jz4780_clk_otg_register(struct clkdom *clkdom, - struct clknode_init_def *clkdef, struct mtx *dev_mtx, - struct resource *mem_res); - -#endif /* _MIPS_INGENIC_JZ4780_CLK_PLL_H */ Index: sys/mips/ingenic/jz4780_clk_gen.c =================================================================== --- sys/mips/ingenic/jz4780_clk_gen.c +++ /dev/null @@ -1,323 +0,0 @@ -/*- - * Copyright 2015 Alexander Kabaev - * 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. - */ - -/* - * Ingenic JZ4780 generic CGU clock driver. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -/* JZ4780 generic mux and div clocks implementation */ -static int jz4780_clk_gen_init(struct clknode *clk, device_t dev); -static int jz4780_clk_gen_recalc_freq(struct clknode *clk, uint64_t *freq); -static int jz4780_clk_gen_set_freq(struct clknode *clk, uint64_t fin, - uint64_t *fout, int flags, int *stop); -static int jz4780_clk_gen_set_gate(struct clknode *clk, bool enable); -static int jz4780_clk_gen_set_mux(struct clknode *clk, int src); - -struct jz4780_clk_gen_sc { - struct mtx *clk_mtx; - struct resource *clk_res; - int clk_reg; - const struct jz4780_clk_descr *clk_descr; -}; - -/* - * JZ4780 clock PLL clock methods - */ -static clknode_method_t jz4780_clk_gen_methods[] = { - CLKNODEMETHOD(clknode_init, jz4780_clk_gen_init), - CLKNODEMETHOD(clknode_set_gate, jz4780_clk_gen_set_gate), - CLKNODEMETHOD(clknode_recalc_freq, jz4780_clk_gen_recalc_freq), - CLKNODEMETHOD(clknode_set_freq, jz4780_clk_gen_set_freq), - CLKNODEMETHOD(clknode_set_mux, jz4780_clk_gen_set_mux), - - CLKNODEMETHOD_END -}; -DEFINE_CLASS_1(jz4780_clk_pll, jz4780_clk_gen_class, jz4780_clk_gen_methods, - sizeof(struct jz4780_clk_gen_sc), clknode_class); - -static inline unsigned -mux_to_reg(unsigned src, unsigned map) -{ - unsigned ret, bit; - - bit = (1u << 3); - for (ret = 0; bit; ret++, bit >>= 1) { - if (map & bit) { - if (src-- == 0) - return (ret); - } - } - panic("mux_to_reg"); -} - -static inline unsigned -reg_to_mux(unsigned reg, unsigned map) -{ - unsigned ret, bit; - - bit = (1u << 3); - for (ret = 0; reg; reg--, bit >>= 1) - if (map & bit) - ret++; - return (ret); -} - -static int -jz4780_clk_gen_init(struct clknode *clk, device_t dev) -{ - struct jz4780_clk_gen_sc *sc; - uint32_t reg, msk, parent_idx; - - sc = clknode_get_softc(clk); - CLK_LOCK(sc); - /* Figure our parent out */ - if (sc->clk_descr->clk_type & CLK_MASK_MUX) { - msk = (1u << sc->clk_descr->clk_mux.mux_bits) - 1; - reg = CLK_RD_4(sc, sc->clk_descr->clk_mux.mux_reg); - reg = (reg >> sc->clk_descr->clk_mux.mux_shift) & msk; - parent_idx = reg_to_mux(reg, sc->clk_descr->clk_mux.mux_map); - } else - parent_idx = 0; - CLK_UNLOCK(sc); - - clknode_init_parent_idx(clk, parent_idx); - return (0); -} - -static int -jz4780_clk_gen_recalc_freq(struct clknode *clk, uint64_t *freq) -{ - struct jz4780_clk_gen_sc *sc; - uint32_t reg; - - sc = clknode_get_softc(clk); - - /* Calculate divisor frequency */ - if (sc->clk_descr->clk_type & CLK_MASK_DIV) { - uint32_t msk; - - msk = (1u << sc->clk_descr->clk_div.div_bits) - 1; - reg = CLK_RD_4(sc, sc->clk_descr->clk_div.div_reg); - reg = (reg >> sc->clk_descr->clk_div.div_shift) & msk; - reg = (reg + 1) << sc->clk_descr->clk_div.div_lg; - *freq /= reg; - } - return (0); -} - -#define DIV_TIMEOUT 100 - -static int -jz4780_clk_gen_set_freq(struct clknode *clk, uint64_t fin, - uint64_t *fout, int flags, int *stop) -{ - struct jz4780_clk_gen_sc *sc; - uint64_t _fout; - uint32_t divider, div_reg, div_msk, reg, div_l, div_h; - int rv; - - sc = clknode_get_softc(clk); - - /* Find closest divider */ - div_l = howmany(fin, *fout); - div_h = fin / *fout; - divider = abs((int64_t)*fout - (fin / div_l)) < - abs((int64_t)*fout - (fin / div_h)) ? div_l : div_h; - - /* Adjust for divider multiplier */ - div_reg = divider >> sc->clk_descr->clk_div.div_lg; - divider = div_reg << sc->clk_descr->clk_div.div_lg; - if (divider == 0) - divider = 1; - - _fout = fin / divider; - - /* Rounding */ - if ((flags & CLK_SET_ROUND_UP) && (*fout > _fout)) - div_reg--; - else if ((flags & CLK_SET_ROUND_DOWN) && (*fout < _fout)) - div_reg++; - if (div_reg == 0) - div_reg = 1; - - div_msk = (1u << sc->clk_descr->clk_div.div_bits) - 1; - - *stop = 1; - if (div_reg > div_msk + 1) { - *stop = 0; - div_reg = div_msk; - } - - divider = (div_reg << sc->clk_descr->clk_div.div_lg); - div_reg--; - - if ((flags & CLK_SET_DRYRUN) != 0) { - if (*stop != 0 && *fout != fin / divider && - (flags & (CLK_SET_ROUND_UP | CLK_SET_ROUND_DOWN)) == 0) - return (ERANGE); - *fout = fin / divider; - return (0); - } - - CLK_LOCK(sc); - /* Apply the new divider value */ - reg = CLK_RD_4(sc, sc->clk_descr->clk_div.div_reg); - reg &= ~(div_msk << sc->clk_descr->clk_div.div_shift); - reg |= (div_reg << sc->clk_descr->clk_div.div_shift); - /* Set the change enable bit, it present */ - if (sc->clk_descr->clk_div.div_ce_bit >= 0) - reg |= (1u << sc->clk_descr->clk_div.div_ce_bit); - /* Clear stop bit, it present */ - if (sc->clk_descr->clk_div.div_st_bit >= 0) - reg &= ~(1u << sc->clk_descr->clk_div.div_st_bit); - /* Initiate the change */ - CLK_WR_4(sc, sc->clk_descr->clk_div.div_reg, reg); - - /* Wait for busy bit to clear indicating the change is complete */ - rv = 0; - if (sc->clk_descr->clk_div.div_busy_bit >= 0) { - int i; - - for (i = 0; i < DIV_TIMEOUT; i++) { - reg = CLK_RD_4(sc, sc->clk_descr->clk_div.div_reg); - if (!(reg & (1u << sc->clk_descr->clk_div.div_busy_bit))) - break; - DELAY(1000); - } - if (i == DIV_TIMEOUT) - rv = ETIMEDOUT; - } - CLK_UNLOCK(sc); - - *fout = fin / divider; - return (rv); -} - -static int -jz4780_clk_gen_set_mux(struct clknode *clk, int src) -{ - struct jz4780_clk_gen_sc *sc; - uint32_t reg, msk; - - sc = clknode_get_softc(clk); - - /* Only mux nodes are capable of being reparented */ - if (!(sc->clk_descr->clk_type & CLK_MASK_MUX)) - return (src ? EINVAL : 0); - - msk = (1u << sc->clk_descr->clk_mux.mux_bits) - 1; - src = mux_to_reg(src & msk, sc->clk_descr->clk_mux.mux_map); - - CLK_LOCK(sc); - reg = CLK_RD_4(sc, sc->clk_descr->clk_mux.mux_reg); - reg &= ~(msk << sc->clk_descr->clk_mux.mux_shift); - reg |= (src << sc->clk_descr->clk_mux.mux_shift); - CLK_WR_4(sc, sc->clk_descr->clk_mux.mux_reg, reg); - CLK_UNLOCK(sc); - - return (0); -} - -static int -jz4780_clk_gen_set_gate(struct clknode *clk, bool enable) -{ - struct jz4780_clk_gen_sc *sc; - uint32_t off, reg, bit; - - sc = clknode_get_softc(clk); - - /* Check is clock can be gated */ - if (sc->clk_descr->clk_gate_bit < 0) - return 0; - - bit = sc->clk_descr->clk_gate_bit; - if (bit < 32) { - off = JZ_CLKGR0; - } else { - off = JZ_CLKGR1; - bit -= 32; - } - - CLK_LOCK(sc); - reg = CLK_RD_4(sc, off); - if (enable) - reg &= ~(1u << bit); - else - reg |= (1u << bit); - CLK_WR_4(sc, off, reg); - CLK_UNLOCK(sc); - - return (0); -} - - -int jz4780_clk_gen_register(struct clkdom *clkdom, - const struct jz4780_clk_descr *descr, struct mtx *dev_mtx, - struct resource *mem_res) -{ - struct clknode_init_def clkdef; - struct clknode *clk; - struct jz4780_clk_gen_sc *sc; - - clkdef.id = descr->clk_id; - clkdef.name = __DECONST(char *, descr->clk_name); - /* Silly const games to work around API deficiency */ - clkdef.parent_names = (const char **)(uintptr_t)&descr->clk_pnames[0]; - clkdef.flags = CLK_NODE_STATIC_STRINGS; - if (descr->clk_type & CLK_MASK_MUX) - clkdef.parent_cnt = __bitcount16(descr->clk_mux.mux_map); - else - clkdef.parent_cnt = 1; - - clk = clknode_create(clkdom, &jz4780_clk_gen_class, &clkdef); - if (clk == NULL) - return (1); - - sc = clknode_get_softc(clk); - sc->clk_mtx = dev_mtx; - sc->clk_res = mem_res; - sc->clk_descr = descr; - clknode_register(clkdom, clk); - - return (0); -} Index: sys/mips/ingenic/jz4780_clk_otg.c =================================================================== --- sys/mips/ingenic/jz4780_clk_otg.c +++ /dev/null @@ -1,167 +0,0 @@ -/*- - * Copyright 2015 Alexander Kabaev - * 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. - */ - -/* - * Ingenic JZ4780 OTG PHY clock driver. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -/* JZ4780 OTG PHY clock */ -static int jz4780_clk_otg_init(struct clknode *clk, device_t dev); -static int jz4780_clk_otg_recalc_freq(struct clknode *clk, uint64_t *freq); -static int jz4780_clk_otg_set_freq(struct clknode *clk, uint64_t fin, - uint64_t *fout, int flags, int *stop); - -struct jz4780_clk_otg_sc { - struct mtx *clk_mtx; - struct resource *clk_res; -}; - -/* - * JZ4780 OTG PHY clock methods - */ -static clknode_method_t jz4780_clk_otg_methods[] = { - CLKNODEMETHOD(clknode_init, jz4780_clk_otg_init), - CLKNODEMETHOD(clknode_recalc_freq, jz4780_clk_otg_recalc_freq), - CLKNODEMETHOD(clknode_set_freq, jz4780_clk_otg_set_freq), - - CLKNODEMETHOD_END -}; -DEFINE_CLASS_1(jz4780_clk_pll, jz4780_clk_otg_class, jz4780_clk_otg_methods, - sizeof(struct jz4780_clk_otg_sc), clknode_class); - -static int -jz4780_clk_otg_init(struct clknode *clk, device_t dev) -{ - struct jz4780_clk_otg_sc *sc; - uint32_t reg; - - sc = clknode_get_softc(clk); - CLK_LOCK(sc); - /* Force the use fo the core clock */ - reg = CLK_RD_4(sc, JZ_USBPCR1); - reg &= ~PCR_REFCLK_M; - reg |= PCR_REFCLK_CORE; - CLK_WR_4(sc, JZ_USBPCR1, reg); - CLK_UNLOCK(sc); - - clknode_init_parent_idx(clk, 0); - return (0); -} - -static const struct { - uint32_t div_val; - uint32_t freq; -} otg_div_table[] = { - { PCR_CLK_12, 12000000 }, - { PCR_CLK_192, 19200000 }, - { PCR_CLK_24, 24000000 }, - { PCR_CLK_48, 48000000 } -}; - -static int -jz4780_clk_otg_recalc_freq(struct clknode *clk, uint64_t *freq) -{ - struct jz4780_clk_otg_sc *sc; - uint32_t reg; - int i; - - sc = clknode_get_softc(clk); - reg = CLK_RD_4(sc, JZ_USBPCR1); - reg &= PCR_CLK_M; - - for (i = 0; i < nitems(otg_div_table); i++) - if (otg_div_table[i].div_val == reg) - *freq = otg_div_table[i].freq; - return (0); -} - -static int -jz4780_clk_otg_set_freq(struct clknode *clk, uint64_t fin, - uint64_t *fout, int flags, int *stop) -{ - struct jz4780_clk_otg_sc *sc; - uint32_t reg; - int i; - - sc = clknode_get_softc(clk); - - for (i = 0; i < nitems(otg_div_table) - 1; i++) { - if (*fout < (otg_div_table[i].freq + otg_div_table[i + 1].freq) / 2) - break; - } - - *fout = otg_div_table[i].freq; - - *stop = 1; - if (flags & CLK_SET_DRYRUN) - return (0); - - CLK_LOCK(sc); - reg = CLK_RD_4(sc, JZ_USBPCR1); - /* Set the calculated values */ - reg &= ~PCR_CLK_M; - reg |= otg_div_table[i].div_val; - /* Initiate the change */ - CLK_WR_4(sc, JZ_USBPCR1, reg); - CLK_UNLOCK(sc); - - return (0); -} - -int jz4780_clk_otg_register(struct clkdom *clkdom, - struct clknode_init_def *clkdef, struct mtx *dev_mtx, - struct resource *mem_res) -{ - struct clknode *clk; - struct jz4780_clk_otg_sc *sc; - - clk = clknode_create(clkdom, &jz4780_clk_otg_class, clkdef); - if (clk == NULL) - return (1); - - sc = clknode_get_softc(clk); - sc->clk_mtx = dev_mtx; - sc->clk_res = mem_res; - clknode_register(clkdom, clk); - return (0); -} Index: sys/mips/ingenic/jz4780_clk_pll.c =================================================================== --- sys/mips/ingenic/jz4780_clk_pll.c +++ /dev/null @@ -1,234 +0,0 @@ -/*- - * Copyright 2015 Alexander Kabaev - * 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. - */ - -/* - * Ingenic JZ4780 CGU driver. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -/********************************************************************** - * JZ4780 PLL control register bit fields - **********************************************************************/ -#define CGU_PLL_M_SHIFT 19 -#define CGU_PLL_M_WIDTH 13 - -#define CGU_PLL_N_SHIFT 13 -#define CGU_PLL_N_WIDTH 6 - -#define CGU_PLL_OD_SHIFT 9 -#define CGU_PLL_OD_WIDTH 4 - -#define CGU_PLL_LOCK_SHIFT 6 -#define CGU_PLL_LOCK_WIDTH 1 - -#define CGU_PLL_ON_SHIFT 4 -#define CGU_PLL_ON_WIDTH 1 - -#define CGU_PLL_MODE_SHIFT 3 -#define CGU_PLL_MODE_WIDTH 1 - -#define CGU_PLL_BP_SHIFT 1 -#define CGU_PLL_BP_WIDTH 1 - -#define CGU_PLL_EN_SHIFT 0 -#define CGU_PLL_EN_WIDTH 1 - -/* JZ4780 PLL clock */ -static int jz4780_clk_pll_init(struct clknode *clk, device_t dev); -static int jz4780_clk_pll_recalc_freq(struct clknode *clk, uint64_t *freq); -static int jz4780_clk_pll_set_freq(struct clknode *clk, uint64_t fin, - uint64_t *fout, int flags, int *stop); - -struct jz4780_clk_pll_sc { - struct mtx *clk_mtx; - struct resource *clk_res; - uint32_t clk_reg; -}; - -/* - * JZ4780 PLL clock methods - */ -static clknode_method_t jz4780_clk_pll_methods[] = { - CLKNODEMETHOD(clknode_init, jz4780_clk_pll_init), - CLKNODEMETHOD(clknode_recalc_freq, jz4780_clk_pll_recalc_freq), - CLKNODEMETHOD(clknode_set_freq, jz4780_clk_pll_set_freq), - - CLKNODEMETHOD_END -}; -DEFINE_CLASS_1(jz4780_clk_pll, jz4780_clk_pll_class, jz4780_clk_pll_methods, - sizeof(struct jz4780_clk_pll_sc), clknode_class); - -static int -jz4780_clk_pll_init(struct clknode *clk, device_t dev) -{ - struct jz4780_clk_pll_sc *sc; - uint32_t reg; - - sc = clknode_get_softc(clk); - CLK_LOCK(sc); - reg = CLK_RD_4(sc, sc->clk_reg); - CLK_WR_4(sc, sc->clk_reg, reg); - CLK_UNLOCK(sc); - - clknode_init_parent_idx(clk, 0); - return (0); -} - -static int -jz4780_clk_pll_recalc_freq(struct clknode *clk, uint64_t *freq) -{ - struct jz4780_clk_pll_sc *sc; - uint32_t reg, m, n, od; - - sc = clknode_get_softc(clk); - reg = CLK_RD_4(sc, sc->clk_reg); - - /* Check for PLL enabled status */ - if (REG_GET(reg, CGU_PLL_EN) == 0) { - *freq = 0; - return 0; - } - - /* Return parent frequency if PPL is being bypassed */ - if (REG_GET(reg, CGU_PLL_BP) != 0) - return 0; - - m = REG_GET(reg, CGU_PLL_M) + 1; - n = REG_GET(reg, CGU_PLL_N) + 1; - od = REG_GET(reg, CGU_PLL_OD) + 1; - - /* Sanity check values */ - if (m == 0 || n == 0 || od == 0) { - *freq = 0; - return (EINVAL); - } - - *freq = ((*freq / n) * m) / od; - return (0); -} - -#define MHZ (1000 * 1000) -#define PLL_TIMEOUT 100 - -static int -jz4780_clk_pll_wait_lock(struct jz4780_clk_pll_sc *sc) -{ - int i; - - for (i = 0; i < PLL_TIMEOUT; i++) { - if (CLK_RD_4(sc, sc->clk_reg) & REG_VAL(CGU_PLL_LOCK, 1)) - return (0); - DELAY(1000); - } - return (ETIMEDOUT); -} - -static int -jz4780_clk_pll_set_freq(struct clknode *clk, uint64_t fin, - uint64_t *fout, int flags, int *stop) -{ - struct jz4780_clk_pll_sc *sc; - uint32_t reg, m, n, od; - int rv; - - sc = clknode_get_softc(clk); - - /* Should be able to figure all clocks with m & n only */ - od = 1; - - m = MIN((uint32_t)(*fout / MHZ), (1u << CGU_PLL_M_WIDTH)); - m = MIN(m, 1); - - n = MIN((uint32_t)(fin / MHZ), (1u << CGU_PLL_N_WIDTH)); - n = MIN(n, 1); - - if (flags & CLK_SET_DRYRUN) { - if (((flags & (CLK_SET_ROUND_UP | CLK_SET_ROUND_DOWN)) == 0) && - (*fout != (((fin / n) * m) / od))) - return (ERANGE); - - *fout = ((fin / n) * m) / od; - return (0); - } - - CLK_LOCK(sc); - reg = CLK_RD_4(sc, sc->clk_reg); - - /* Set the calculated values */ - reg = REG_SET(reg, CGU_PLL_M, m - 1); - reg = REG_SET(reg, CGU_PLL_N, n - 1); - reg = REG_SET(reg, CGU_PLL_OD, od - 1); - - /* Enable the PLL */ - reg = REG_SET(reg, CGU_PLL_EN, 1); - reg = REG_SET(reg, CGU_PLL_BP, 0); - - /* Initiate the change */ - CLK_WR_4(sc, sc->clk_reg, reg); - - /* Wait for PLL to lock */ - rv = jz4780_clk_pll_wait_lock(sc); - CLK_UNLOCK(sc); - if (rv != 0) - return (rv); - - *fout = ((fin / n) * m) / od; - return (0); -} - -int jz4780_clk_pll_register(struct clkdom *clkdom, - struct clknode_init_def *clkdef, struct mtx *dev_mtx, - struct resource *mem_res, uint32_t mem_reg) -{ - struct clknode *clk; - struct jz4780_clk_pll_sc *sc; - - clk = clknode_create(clkdom, &jz4780_clk_pll_class, clkdef); - if (clk == NULL) - return (1); - - sc = clknode_get_softc(clk); - sc->clk_mtx = dev_mtx; - sc->clk_res = mem_res; - sc->clk_reg = mem_reg; - clknode_register(clkdom, clk); - return (0); -} Index: sys/mips/ingenic/jz4780_clock.h =================================================================== --- sys/mips/ingenic/jz4780_clock.h +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * Copyright 2015 Alexander Kabaev - * 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 JZ4780_CLOCK_H -#define JZ4780_CLOCK_H - -extern int jz4780_ehci_enable(void); -extern int jz4780_ohci_enable(void); -extern int jz4780_otg_enable(void); - -#endif Index: sys/mips/ingenic/jz4780_clock.c =================================================================== --- sys/mips/ingenic/jz4780_clock.c +++ /dev/null @@ -1,831 +0,0 @@ -/*- - * Copyright 2015 Alexander Kabaev - * 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. - */ - -/* - * Ingenic JZ4780 CGU driver. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include - -#include "clkdev_if.h" - -#include - -/********************************************************************** - * JZ4780 CGU clock domain - **********************************************************************/ -struct jz4780_clock_softc { - device_t dev; - struct resource *res[1]; - struct mtx mtx; - struct clkdom *clkdom; -}; - -static struct resource_spec jz4780_clock_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE }, - { -1, 0 } -}; - -struct jz4780_clk_pll_def { - uint16_t clk_id; - uint16_t clk_reg; - const char *clk_name; - const char *clk_pname[1]; -}; - -#define PLL(_id, cname, pname, reg) { \ - .clk_id = _id, \ - .clk_reg = reg, \ - .clk_name = cname, \ - .clk_pname[0] = pname, \ -} - -struct jz4780_clk_gate_def { - uint16_t clk_id; - uint16_t clk_bit; - const char *clk_name; - const char *clk_pname[1]; -}; - -#define GATE(_id, cname, pname, bit) { \ - .clk_id = _id, \ - .clk_bit = bit, \ - .clk_name = cname, \ - .clk_pname[0] = pname, \ -} - -#define MUX(reg, shift, bits, map) \ - .clk_mux.mux_reg = (reg), \ - .clk_mux.mux_shift = (shift), \ - .clk_mux.mux_bits = (bits), \ - .clk_mux.mux_map = (map), -#define NO_MUX - -#define DIV(reg, shift, lg, bits, ce, st, bb) \ - .clk_div.div_reg = (reg), \ - .clk_div.div_shift = (shift), \ - .clk_div.div_bits = (bits), \ - .clk_div.div_lg = (lg), \ - .clk_div.div_ce_bit = (ce), \ - .clk_div.div_st_bit = (st), \ - .clk_div.div_busy_bit = (bb), -#define NO_DIV \ - -#define GATEBIT(bit) \ - .clk_gate_bit = (bit), -#define NO_GATE \ - .clk_gate_bit = (-1), - -#define PLIST(pnames...) \ - .clk_pnames = { pnames }, - -#define GENCLK(id, name, type, parents, mux, div, gt) { \ - .clk_id = id, \ - .clk_type = type, \ - .clk_name = name, \ - parents \ - mux \ - div \ - gt \ -} - -/* PLL definitions */ -static struct jz4780_clk_pll_def pll_clks[] = { - PLL(JZ4780_CLK_APLL, "apll", "ext", JZ_CPAPCR), - PLL(JZ4780_CLK_MPLL, "mpll", "ext", JZ_CPMPCR), - PLL(JZ4780_CLK_EPLL, "epll", "ext", JZ_CPEPCR), - PLL(JZ4780_CLK_VPLL, "vpll", "ext", JZ_CPVPCR), -}; - -/* OTG PHY clock (reuse gate def structure */ -static struct jz4780_clk_gate_def otg_clks[] = { - GATE(JZ4780_CLK_OTGPHY, "otg_phy", "ext", 0), -}; - -static const struct jz4780_clk_descr gen_clks[] = { - GENCLK(JZ4780_CLK_SCLKA, "sclk_a", CLK_MASK_MUX, - PLIST("apll", "ext", "rtc"), - MUX(JZ_CPCCR, 30, 2, 0x7), - NO_DIV, - NO_GATE - ), - - GENCLK(JZ4780_CLK_CPUMUX, "cpumux", CLK_MASK_MUX, - PLIST("sclk_a", "mpll", "epll"), - MUX(JZ_CPCCR, 28, 2, 0x7), - NO_DIV, - NO_GATE - ), - - GENCLK(JZ4780_CLK_CPU, "cpu", CLK_MASK_DIV, - PLIST("cpumux"), - NO_MUX, - DIV(JZ_CPCCR, 0, 0, 4, 22, -1, -1), - NO_GATE - ), - - GENCLK(JZ4780_CLK_L2CACHE, "l2cache", CLK_MASK_DIV, - PLIST("cpumux"), - NO_MUX, - DIV(JZ_CPCCR, 4, 0, 4, -1, -1, -1), - NO_GATE - ), - - GENCLK(JZ4780_CLK_AHB0, "ahb0", CLK_MASK_MUX | CLK_MASK_DIV, - PLIST("sclk_a", "mpll", "epll"), - MUX(JZ_CPCCR, 26, 2, 0x7), - DIV(JZ_CPCCR, 8, 0, 4, 21, -1, -1), - NO_GATE - ), - - GENCLK(JZ4780_CLK_AHB2PMUX, "ahb2_apb_mux", CLK_MASK_MUX, - PLIST("sclk_a", "mpll", "rtc"), - MUX(JZ_CPCCR, 24, 2, 0x7), - NO_DIV, - NO_GATE - ), - - GENCLK(JZ4780_CLK_AHB2, "ahb2", CLK_MASK_DIV, - PLIST("ahb2_apb_mux"), - NO_MUX, - DIV(JZ_CPCCR, 12, 0, 4, 20, -1, -1), - NO_GATE - ), - - GENCLK(JZ4780_CLK_PCLK, "pclk", CLK_MASK_DIV, - PLIST("ahb2_apb_mux"), - NO_MUX, - DIV(JZ_CPCCR, 16, 0, 4, 20, -1, -1), - NO_GATE - ), - - GENCLK(JZ4780_CLK_DDR, "ddr", CLK_MASK_MUX | CLK_MASK_DIV, - PLIST("sclk_a", "mpll"), - MUX(JZ_DDCDR, 30, 2, 0x6), - DIV(JZ_DDCDR, 0, 0, 4, 29, 28, 27), - NO_GATE - ), - - GENCLK(JZ4780_CLK_VPU, "vpu", CLK_MASK_MUX | CLK_MASK_DIV | CLK_MASK_GATE, - PLIST("sclk_a", "mpll", "epll"), - MUX(JZ_VPUCDR, 30, 2, 0xe), - DIV(JZ_VPUCDR, 0, 0, 4, 29, 28, 27), - GATEBIT(32 + 2) - ), - - GENCLK(JZ4780_CLK_I2SPLL, "i2s_pll", CLK_MASK_MUX | CLK_MASK_DIV, - PLIST("sclk_a", "epll"), - MUX(JZ_I2SCDR, 30, 1, 0xc), - DIV(JZ_I2SCDR, 0, 0, 8, 29, 28, 27), - NO_GATE - ), - - GENCLK(JZ4780_CLK_I2S, "i2s", CLK_MASK_MUX, - PLIST("ext", "i2s_pll"), - MUX(JZ_I2SCDR, 31, 1, 0xc), - NO_DIV, - NO_GATE - ), - - GENCLK(JZ4780_CLK_LCD0PIXCLK, "lcd0pixclk", CLK_MASK_MUX | CLK_MASK_DIV, - PLIST("sclk_a", "mpll", "vpll"), - MUX(JZ_LP0CDR, 30, 2, 0xe), - DIV(JZ_LP0CDR, 0, 0, 8, 28, 27, 26), - NO_GATE - ), - - GENCLK(JZ4780_CLK_LCD1PIXCLK, "lcd1pixclk", CLK_MASK_MUX | CLK_MASK_DIV, - PLIST("sclk_a", "mpll", "vpll"), - MUX(JZ_LP1CDR, 30, 2, 0xe), - DIV(JZ_LP1CDR, 0, 0, 8, 28, 27, 26), - NO_GATE - ), - - GENCLK(JZ4780_CLK_MSCMUX, "msc_mux", CLK_MASK_MUX, - PLIST("sclk_a", "mpll"), - MUX(JZ_MSC0CDR, 30, 2, 0x6), - NO_DIV, - NO_GATE - ), - - GENCLK(JZ4780_CLK_MSC0, "msc0", CLK_MASK_DIV | CLK_MASK_GATE, - PLIST("msc_mux"), - NO_MUX, - DIV(JZ_MSC0CDR, 0, 1, 8, 29, 28, 27), - GATEBIT(3) - ), - - GENCLK(JZ4780_CLK_MSC1, "msc1", CLK_MASK_DIV | CLK_MASK_GATE, - PLIST("msc_mux"), - NO_MUX, - DIV(JZ_MSC1CDR, 0, 1, 8, 29, 28, 27), - GATEBIT(11) - ), - - GENCLK(JZ4780_CLK_MSC2, "msc2", CLK_MASK_DIV | CLK_MASK_GATE, - PLIST("msc_mux"), - NO_MUX, - DIV(JZ_MSC2CDR, 0, 1, 8, 29, 28, 27), - GATEBIT(12) - ), - - GENCLK(JZ4780_CLK_UHC, "uhc", CLK_MASK_MUX | CLK_MASK_DIV | CLK_MASK_GATE, - PLIST("sclk_a", "mpll", "epll", "otg_phy"), - MUX(JZ_UHCCDR, 30, 2, 0xf), - DIV(JZ_UHCCDR, 0, 0, 8, 29, 28, 27), - GATEBIT(24) - ), - - GENCLK(JZ4780_CLK_SSIPLL, "ssi_pll", CLK_MASK_MUX | CLK_MASK_DIV, - PLIST("sclk_a", "mpll"), - MUX(JZ_SSICDR, 30, 1, 0xc), - DIV(JZ_SSICDR, 0, 0, 8, 29, 28, 27), - NO_GATE - ), - - GENCLK(JZ4780_CLK_SSI, "ssi", CLK_MASK_MUX, - PLIST("ext", "ssi_pll"), - MUX(JZ_SSICDR, 31, 1, 0xc), - NO_DIV, - NO_GATE - ), - - GENCLK(JZ4780_CLK_CIMMCLK, "cim_mclk", CLK_MASK_MUX | CLK_MASK_DIV, - PLIST("sclk_a", "mpll"), - MUX(JZ_CIMCDR, 31, 1, 0xc), - DIV(JZ_CIMCDR, 0, 0, 8, 30, 29, 28), - NO_GATE - ), - - GENCLK(JZ4780_CLK_PCMPLL, "pcm_pll", CLK_MASK_MUX | CLK_MASK_DIV, - PLIST("sclk_a", "mpll", "epll", "vpll"), - MUX(JZ_PCMCDR, 29, 2, 0xf), - DIV(JZ_PCMCDR, 0, 0, 8, 28, 27, 26), - NO_GATE - ), - - GENCLK(JZ4780_CLK_PCM, "pcm", CLK_MASK_MUX | CLK_MASK_GATE, - PLIST("ext", "pcm_pll"), - MUX(JZ_PCMCDR, 31, 1, 0xc), - NO_DIV, - GATEBIT(32 + 3) - ), - - GENCLK(JZ4780_CLK_GPU, "gpu", CLK_MASK_MUX | CLK_MASK_DIV | CLK_MASK_GATE, - PLIST("sclk_a", "mpll", "epll"), - MUX(JZ_GPUCDR, 30, 2, 0x7), - DIV(JZ_GPUCDR, 0, 0, 4, 29, 28, 27), - GATEBIT(32 + 4) - ), - - GENCLK(JZ4780_CLK_HDMI, "hdmi", CLK_MASK_MUX | CLK_MASK_DIV | CLK_MASK_GATE, - PLIST("sclk_a", "mpll", "vpll"), - MUX(JZ_HDMICDR, 30, 2, 0xe), - DIV(JZ_HDMICDR, 0, 0, 8, 29, 28, 26), - GATEBIT(32 + 9) - ), - - GENCLK(JZ4780_CLK_BCH, "bch", CLK_MASK_MUX | CLK_MASK_DIV | CLK_MASK_GATE, - PLIST("sclk_a", "mpll", "epll"), - MUX(JZ_BCHCDR, 30, 2, 0x7), - DIV(JZ_BCHCDR, 0, 0, 4, 29, 28, 27), - GATEBIT(1) - ), -}; - -static struct jz4780_clk_gate_def gate_clks[] = { - GATE(JZ4780_CLK_NEMC, "nemc", "ahb2", 0), - GATE(JZ4780_CLK_OTG0, "otg0", "ext", 2), - GATE(JZ4780_CLK_SSI0, "ssi0", "ssi", 4), - GATE(JZ4780_CLK_SMB0, "smb0", "pclk", 5), - GATE(JZ4780_CLK_SMB1, "smb1", "pclk", 6), - GATE(JZ4780_CLK_SCC, "scc", "ext", 7), - GATE(JZ4780_CLK_AIC, "aic", "ext", 8), - GATE(JZ4780_CLK_TSSI0, "tssi0", "ext", 9), - GATE(JZ4780_CLK_OWI, "owi", "ext", 10), - GATE(JZ4780_CLK_KBC, "kbc", "ext", 13), - GATE(JZ4780_CLK_SADC, "sadc", "ext", 14), - GATE(JZ4780_CLK_UART0, "uart0", "ext", 15), - GATE(JZ4780_CLK_UART1, "uart1", "ext", 16), - GATE(JZ4780_CLK_UART2, "uart2", "ext", 17), - GATE(JZ4780_CLK_UART3, "uart3", "ext", 18), - GATE(JZ4780_CLK_SSI1, "ssi1", "ssi", 19), - GATE(JZ4780_CLK_SSI2, "ssi2", "ssi", 20), - GATE(JZ4780_CLK_PDMA, "pdma", "ext", 21), - GATE(JZ4780_CLK_GPS, "gps", "ext", 22), - GATE(JZ4780_CLK_MAC, "mac", "ext", 23), - GATE(JZ4780_CLK_SMB2, "smb2", "pclk", 25), - GATE(JZ4780_CLK_CIM, "cim", "ext", 26), - GATE(JZ4780_CLK_LCD, "lcd", "ext", 28), - GATE(JZ4780_CLK_TVE, "tve", "lcd", 27), - GATE(JZ4780_CLK_IPU, "ipu", "ext", 29), - GATE(JZ4780_CLK_DDR0, "ddr0", "ddr", 30), - GATE(JZ4780_CLK_DDR1, "ddr1", "ddr", 31), - GATE(JZ4780_CLK_SMB3, "smb3", "pclk", 32 + 0), - GATE(JZ4780_CLK_TSSI1, "tssi1", "ext", 32 + 1), - GATE(JZ4780_CLK_COMPRESS, "compress", "ext", 32 + 5), - GATE(JZ4780_CLK_AIC1, "aic1", "ext", 32 + 6), - GATE(JZ4780_CLK_GPVLC, "gpvlc", "ext", 32 + 7), - GATE(JZ4780_CLK_OTG1, "otg1", "ext", 32 + 8), - GATE(JZ4780_CLK_UART4, "uart4", "ext", 32 + 10), - GATE(JZ4780_CLK_AHBMON, "ahb_mon", "ext", 32 + 11), - GATE(JZ4780_CLK_SMB4, "smb4", "pclk", 32 + 12), - GATE(JZ4780_CLK_DES, "des", "ext", 32 + 13), - GATE(JZ4780_CLK_X2D, "x2d", "ext", 32 + 14), - GATE(JZ4780_CLK_CORE1, "core1", "cpu", 32 + 15), -}; - -static int -jz4780_clock_register(struct jz4780_clock_softc *sc) -{ - int i, ret; - - /* Register PLLs */ - for (i = 0; i < nitems(pll_clks); i++) { - struct clknode_init_def clkdef; - - clkdef.id = pll_clks[i].clk_id; - clkdef.name = __DECONST(char *, pll_clks[i].clk_name); - clkdef.parent_names = pll_clks[i].clk_pname; - clkdef.parent_cnt = 1; - clkdef.flags = CLK_NODE_STATIC_STRINGS; - - ret = jz4780_clk_pll_register(sc->clkdom, &clkdef, &sc->mtx, - sc->res[0], pll_clks[i].clk_reg); - if (ret != 0) - return (ret); - } - - /* Register OTG clock */ - for (i = 0; i < nitems(otg_clks); i++) { - struct clknode_init_def clkdef; - - clkdef.id = otg_clks[i].clk_id; - clkdef.name = __DECONST(char *, otg_clks[i].clk_name); - clkdef.parent_names = otg_clks[i].clk_pname; - clkdef.parent_cnt = 1; - clkdef.flags = CLK_NODE_STATIC_STRINGS; - - ret = jz4780_clk_otg_register(sc->clkdom, &clkdef, &sc->mtx, - sc->res[0]); - if (ret != 0) - return (ret); - } - - /* Register muxes and divisors */ - for (i = 0; i < nitems(gen_clks); i++) { - ret = jz4780_clk_gen_register(sc->clkdom, &gen_clks[i], - &sc->mtx, sc->res[0]); - if (ret != 0) - return (ret); - } - - /* Register simple gates */ - for (i = 0; i < nitems(gate_clks); i++) { - struct clk_gate_def gatedef; - - gatedef.clkdef.id = gate_clks[i].clk_id; - gatedef.clkdef.name = __DECONST(char *, gate_clks[i].clk_name); - gatedef.clkdef.parent_names = gate_clks[i].clk_pname; - gatedef.clkdef.parent_cnt = 1; - gatedef.clkdef.flags = CLK_NODE_STATIC_STRINGS; - - if (gate_clks[i].clk_bit < 32) { - gatedef.offset = JZ_CLKGR0; - gatedef.shift = gate_clks[i].clk_bit; - } else { - gatedef.offset = JZ_CLKGR1; - gatedef.shift = gate_clks[i].clk_bit - 32; - } - gatedef.mask = 1; - gatedef.on_value = 0; - gatedef.off_value = 1; - gatedef.gate_flags = 0; - - ret = clknode_gate_register(sc->clkdom, &gatedef); - if (ret != 0) - return (ret); - - } - - return (0); -} - -static int -jz4780_clock_fixup(struct jz4780_clock_softc *sc) -{ - struct clknode *clk_uhc; - int ret; - - /* - * Make UHC mux use MPLL as the source. It defaults to OTG_PHY - * and that somehow just does not work. - */ - clkdom_xlock(sc->clkdom); - - /* Assume the worst */ - ret = ENXIO; - - clk_uhc = clknode_find_by_id(sc->clkdom, JZ4780_CLK_UHC); - if (clk_uhc != NULL) { - ret = clknode_set_parent_by_name(clk_uhc, "mpll"); - if (ret != 0) - device_printf(sc->dev, - "unable to reparent uhc clock\n"); - else - ret = clknode_set_freq(clk_uhc, 48000000, 0, 0); - if (ret != 0) - device_printf(sc->dev, "unable to init uhc clock\n"); - } else - device_printf(sc->dev, "unable to lookup uhc clock\n"); - - clkdom_unlock(sc->clkdom); - return (ret); -} - -#define CGU_LOCK(sc) mtx_lock(&(sc)->mtx) -#define CGU_UNLOCK(sc) mtx_unlock(&(sc)->mtx) -#define CGU_LOCK_INIT(sc) \ - mtx_init(&(sc)->mtx, device_get_nameunit((sc)->dev), \ - "jz4780-cgu", MTX_DEF) -#define CGU_LOCK_DESTROY(sc) mtx_destroy(&(sc)->mtx); - -#define CSR_WRITE_4(sc, reg, val) bus_write_4((sc)->res[0], (reg), (val)) -#define CSR_READ_4(sc, reg) bus_read_4((sc)->res[0], (reg)) - -static int -jz4780_clock_probe(device_t dev) -{ - - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (!ofw_bus_is_compatible(dev, "ingenic,jz4780-cgu")) - return (ENXIO); - - device_set_desc(dev, "Ingenic jz4780 CGU"); - - return (BUS_PROBE_DEFAULT); -} - -static int -jz4780_clock_attach(device_t dev) -{ - struct jz4780_clock_softc *sc; - - sc = device_get_softc(dev); - if (bus_alloc_resources(dev, jz4780_clock_spec, sc->res)) { - device_printf(dev, "could not allocate resources for device\n"); - return (ENXIO); - } - - sc->dev = dev; - CGU_LOCK_INIT(sc); - - sc->clkdom = clkdom_create(dev); - if (sc->clkdom == NULL) - goto fail; - if (jz4780_clock_register(sc) != 0) - goto fail; - if (clkdom_finit(sc->clkdom) != 0) - goto fail; - if (jz4780_clock_fixup(sc) != 0) - goto fail; - if (bootverbose) - clkdom_dump(sc->clkdom); - - return (0); -fail: - bus_release_resources(dev, jz4780_clock_spec, sc->res); - CGU_LOCK_DESTROY(sc); - - return (ENXIO); -} - -static int -jz4780_clock_detach(device_t dev) -{ - struct jz4780_clock_softc *sc; - - sc = device_get_softc(dev); - bus_release_resources(dev, jz4780_clock_spec, sc->res); - CGU_LOCK_DESTROY(sc); - - return (0); -} - -static int -jz4780_clock_write_4(device_t dev, bus_addr_t addr, uint32_t val) -{ - struct jz4780_clock_softc *sc; - - sc = device_get_softc(dev); - CSR_WRITE_4(sc, addr, val); - return (0); -} - -static int -jz4780_clock_read_4(device_t dev, bus_addr_t addr, uint32_t *val) -{ - struct jz4780_clock_softc *sc; - - sc = device_get_softc(dev); - *val = CSR_READ_4(sc, addr); - return (0); -} - -static int -jz4780_clock_modify_4(device_t dev, bus_addr_t addr, uint32_t clear_mask, - uint32_t set_mask) -{ - struct jz4780_clock_softc *sc; - uint32_t val; - - sc = device_get_softc(dev); - val = CSR_READ_4(sc, addr); - val &= ~clear_mask; - val |= set_mask; - CSR_WRITE_4(sc, addr, val); - return (0); -} - -static void -jz4780_clock_device_lock(device_t dev) -{ - struct jz4780_clock_softc *sc; - - sc = device_get_softc(dev); - CGU_LOCK(sc); -} - -static void -jz4780_clock_device_unlock(device_t dev) -{ - struct jz4780_clock_softc *sc; - - sc = device_get_softc(dev); - CGU_UNLOCK(sc); -} - -static device_method_t jz4780_clock_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, jz4780_clock_probe), - DEVMETHOD(device_attach, jz4780_clock_attach), - DEVMETHOD(device_detach, jz4780_clock_detach), - - /* Clock device interface */ - DEVMETHOD(clkdev_write_4, jz4780_clock_write_4), - DEVMETHOD(clkdev_read_4, jz4780_clock_read_4), - DEVMETHOD(clkdev_modify_4, jz4780_clock_modify_4), - DEVMETHOD(clkdev_device_lock, jz4780_clock_device_lock), - DEVMETHOD(clkdev_device_unlock, jz4780_clock_device_unlock), - - DEVMETHOD_END -}; - -static driver_t jz4780_clock_driver = { - "cgu", - jz4780_clock_methods, - sizeof(struct jz4780_clock_softc), -}; - -static devclass_t jz4780_clock_devclass; - -EARLY_DRIVER_MODULE(jz4780_clock, simplebus, jz4780_clock_driver, - jz4780_clock_devclass, 0, 0, BUS_PASS_CPU + BUS_PASS_ORDER_LATE); - -static int -jz4780_ehci_clk_config(struct jz4780_clock_softc *sc) -{ - clk_t phy_clk, ext_clk; - uint64_t phy_freq; - int err; - - phy_clk = NULL; - ext_clk = NULL; - err = -1; - - /* Set phy timing by copying it from ext */ - if (clk_get_by_id(sc->dev, sc->clkdom, JZ4780_CLK_OTGPHY, - &phy_clk) != 0) - goto done; - if (clk_get_parent(phy_clk, &ext_clk) != 0) - goto done; - if (clk_get_freq(ext_clk, &phy_freq) != 0) - goto done; - if (clk_set_freq(phy_clk, phy_freq, 0) != 0) - goto done; - err = 0; -done: - clk_release(ext_clk); - clk_release(phy_clk); - - return (err); -} - -int -jz4780_ohci_enable(void) -{ - device_t dev; - struct jz4780_clock_softc *sc; - uint32_t reg; - - dev = devclass_get_device(jz4780_clock_devclass, 0); - if (dev == NULL) - return (-1); - - sc = device_get_softc(dev); - CGU_LOCK(sc); - - /* Do not force port1 to suspend mode */ - reg = CSR_READ_4(sc, JZ_OPCR); - reg |= OPCR_SPENDN1; - CSR_WRITE_4(sc, JZ_OPCR, reg); - - CGU_UNLOCK(sc); - return (0); -} - -int -jz4780_ehci_enable(void) -{ - device_t dev; - struct jz4780_clock_softc *sc; - uint32_t reg; - - dev = devclass_get_device(jz4780_clock_devclass, 0); - if (dev == NULL) - return (-1); - - sc = device_get_softc(dev); - - /* - * EHCI should use MPPL as a parent, but Linux configures OTG - * clock anyway. Follow their lead blindly. - */ - if (jz4780_ehci_clk_config(sc) != 0) - return (-1); - - CGU_LOCK(sc); - - /* Enable OTG, should not be necessary since we use PLL clock */ - reg = CSR_READ_4(sc, JZ_USBPCR); - reg &= ~(PCR_OTG_DISABLE); - CSR_WRITE_4(sc, JZ_USBPCR, reg); - - /* Do not force port1 to suspend mode */ - reg = CSR_READ_4(sc, JZ_OPCR); - reg |= OPCR_SPENDN1; - CSR_WRITE_4(sc, JZ_OPCR, reg); - - /* D- pulldown */ - reg = CSR_READ_4(sc, JZ_USBPCR1); - reg |= PCR_DMPD1; - CSR_WRITE_4(sc, JZ_USBPCR1, reg); - - /* D+ pulldown */ - reg = CSR_READ_4(sc, JZ_USBPCR1); - reg |= PCR_DPPD1; - CSR_WRITE_4(sc, JZ_USBPCR1, reg); - - /* 16 bit bus witdth for port 1*/ - reg = CSR_READ_4(sc, JZ_USBPCR1); - reg |= PCR_WORD_I_F1 | PCR_WORD_I_F0; - CSR_WRITE_4(sc, JZ_USBPCR1, reg); - - /* Reset USB */ - reg = CSR_READ_4(sc, JZ_USBPCR); - reg |= PCR_POR; - CSR_WRITE_4(sc, JZ_USBPCR, reg); - DELAY(1); - reg = CSR_READ_4(sc, JZ_USBPCR); - reg &= ~(PCR_POR); - CSR_WRITE_4(sc, JZ_USBPCR, reg); - - /* Soft-reset USB */ - reg = CSR_READ_4(sc, JZ_SRBC); - reg |= SRBC_UHC_SR; - CSR_WRITE_4(sc, JZ_SRBC, reg); - /* 300ms */ - DELAY(300*hz/1000); - - reg = CSR_READ_4(sc, JZ_SRBC); - reg &= ~(SRBC_UHC_SR); - CSR_WRITE_4(sc, JZ_SRBC, reg); - - /* 300ms */ - DELAY(300*hz/1000); - - CGU_UNLOCK(sc); - return (0); -} - -#define USBRESET_DETECT_TIME 0x96 - -int -jz4780_otg_enable(void) -{ - device_t dev; - struct jz4780_clock_softc *sc; - uint32_t reg; - - dev = devclass_get_device(jz4780_clock_devclass, 0); - if (dev == NULL) - return (-1); - - sc = device_get_softc(dev); - - CGU_LOCK(sc); - - /* Select Synopsys OTG mode */ - reg = CSR_READ_4(sc, JZ_USBPCR1); - reg |= PCR_SYNOPSYS; - - /* Set UTMI bus width to 16 bit */ - reg |= PCR_WORD_I_F0 | PCR_WORD_I_F1; - CSR_WRITE_4(sc, JZ_USBPCR1, reg); - - /* Blah */ - reg = CSR_READ_4(sc, JZ_USBVBFIL); - reg = REG_SET(reg, USBVBFIL_IDDIGFIL, 0); - reg = REG_SET(reg, USBVBFIL_USBVBFIL, 0); - CSR_WRITE_4(sc, JZ_USBVBFIL, reg); - - /* Setup reset detect time */ - reg = CSR_READ_4(sc, JZ_USBRDT); - reg = REG_SET(reg, USBRDT_USBRDT, USBRESET_DETECT_TIME); - reg |= USBRDT_VBFIL_LD_EN; - CSR_WRITE_4(sc, JZ_USBRDT, reg); - - /* Setup USBPCR bits */ - reg = CSR_READ_4(sc, JZ_USBPCR); - reg |= PCR_USB_MODE; - reg |= PCR_COMMONONN; - reg |= PCR_VBUSVLDEXT; - reg |= PCR_VBUSVLDEXTSEL; - reg &= ~(PCR_OTG_DISABLE); - CSR_WRITE_4(sc, JZ_USBPCR, reg); - - /* Reset USB */ - reg = CSR_READ_4(sc, JZ_USBPCR); - reg |= PCR_POR; - CSR_WRITE_4(sc, JZ_USBPCR, reg); - DELAY(1000); - reg = CSR_READ_4(sc, JZ_USBPCR); - reg &= ~(PCR_POR); - CSR_WRITE_4(sc, JZ_USBPCR, reg); - - /* Unsuspend OTG port */ - reg = CSR_READ_4(sc, JZ_OPCR); - reg |= OPCR_SPENDN0; - CSR_WRITE_4(sc, JZ_OPCR, reg); - - CGU_UNLOCK(sc); - return (0); -} Index: sys/mips/ingenic/jz4780_codec.h =================================================================== --- sys/mips/ingenic/jz4780_codec.h +++ /dev/null @@ -1,102 +0,0 @@ -/*- - * Copyright (c) 2016 Ruslan Bukin - * All rights reserved. - * - * This software was developed by SRI International and the University of - * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 - * ("CTSRD"), as part of the DARPA CRASH research programme. - * - * 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$ - */ - -#define CODEC_RGADW 0x00 /* Address, data in and write command */ -#define RGADW_ICRST (1 << 31) /* Reset internal CODEC */ -#define RGADW_RGWR (1 << 16) /* Issue a write command to CODEC */ -#define RGADW_RGADDR_S 8 /* CODEC register's address. */ -#define RGADW_RGADDR_M (0x7f << RGADW_RGADDR_S) -#define RGADW_RGDIN_S 0 /* CODEC register data to write */ -#define RGADW_RGDIN_M (0xff << RGADW_RGDIN_S) -#define CODEC_RGDATA 0x04 /* The data read out */ - -#define SR 0x00 /* Status Register */ -#define SR2 0x01 /* Status Register 2 */ -#define MR 0x07 /* Mode status register */ -#define AICR_DAC 0x08 /* DAC Audio Interface Control Register */ -#define DAC_ADWL_S 6 /* Audio Data Word Length for DAC path. */ -#define DAC_ADWL_M (0x3 << DAC_ADWL_S) -#define DAC_ADWL_16 (0 << DAC_ADWL_S) -#define AICR_DAC_SB (1 << 4) /* DAC audio interface in power-down mode */ -#define AUDIOIF_S 0 -#define AUDIOIF_M (0x3 << AUDIOIF_S) -#define AUDIOIF_I2S 0x3 /* I2S interface */ -#define AUDIOIF_DSP 0x2 /* DSP interface */ -#define AUDIOIF_LJ 0x1 /* Left-justified interface */ -#define AUDIOIF_P 0x0 /* Parallel interface */ -#define AICR_ADC 0x09 /* ADC Audio Interface Control Register */ -#define CR_LO 0x0B /* Differential line-out Control Register */ -#define CR_HP 0x0D /* HeadPhone Control Register */ -#define HP_MUTE (1 << 7) /* no signal on headphone outputs */ -#define HP_SB (1 << 4) /* power-down */ -#define CR_DMIC 0x10 /* Digital Microphone register */ -#define CR_MIC1 0x11 /* Microphone1 Control register */ -#define CR_MIC2 0x12 /* Microphone2 Control register */ -#define CR_LI1 0x13 /* Control Register for line1 inputs */ -#define CR_LI2 0x14 /* Control Register for line2 inputs */ -#define CR_DAC 0x17 /* DAC Control Register */ -#define DAC_MUTE (1 << 7) /* puts the DAC in soft mute mode */ -#define DAC_SB (1 << 4) /* power-down */ -#define CR_ADC 0x18 /* ADC Control Register */ -#define CR_MIX 0x19 /* Digital Mixer Control Register */ -#define DR_MIX 0x1A /* Digital Mixer Data Register */ -#define CR_VIC 0x1B /* Control Register for the ViC */ -#define VIC_SB_SLEEP (1 << 1) /* sleep mode */ -#define VIC_SB (1 << 0) /* complete power-down */ -#define CR_CK 0x1C /* Clock Control Register */ -#define FCR_DAC 0x1D /* DAC Frequency Control Register */ -#define FCR_DAC_48 8 /* 48 kHz. */ -#define FCR_DAC_96 10 /* 96 kHz. */ -#define FCR_ADC 0x20 /* ADC Frequency Control Register */ -#define CR_TIMER_MSB 0x21 /* MSB of programmable counter */ -#define CR_TIMER_LSB 0x22 /* LSB of programmable counter */ -#define ICR 0x23 /* Interrupt Control Register */ -#define IMR 0x24 /* Interrupt Mask Register */ -#define IFR 0x25 /* Interrupt Flag Register */ -#define IMR2 0x26 /* Interrupt Mask Register 2 */ -#define IFR2 0x27 /* Interrupt Flag Register 2 */ -#define GCR_HPL 0x28 /* Left channel headphone Control Gain Register */ -#define GCR_HPR 0x29 /* Right channel headphone Control Gain Register */ -#define GCR_LIBYL 0x2A /* Left channel bypass line Control Gain Register */ -#define GCR_LIBYR 0x2B /* Right channel bypass line Control Gain Register */ -#define GCR_DACL 0x2C /* Left channel DAC Gain Control Register */ -#define GCR_DACR 0x2D /* Right channel DAC Gain Control Register */ -#define GCR_MIC1 0x2E /* Microphone 1 Gain Control Register */ -#define GCR_MIC2 0x2F /* Microphone 2 Gain Control Register */ -#define GCR_ADCL 0x30 /* Left ADC Gain Control Register */ -#define GCR_ADCR 0x31 /* Right ADC Gain Control Register */ -#define GCR_MIXDACL 0x34 /* DAC Digital Mixer Control Register */ -#define GCR_MIXDACR 0x35 /* DAC Digital Mixer Control Register */ -#define GCR_MIXADCL 0x36 /* ADC Digital Mixer Control Register */ -#define GCR_MIXADCR 0x37 /* ADC Digital Mixer Control Register */ -#define CR_ADC_AGC 0x3A /* Automatic Gain Control Register */ -#define DR_ADC_AGC 0x3B /* Automatic Gain Control Data Register */ Index: sys/mips/ingenic/jz4780_codec.c =================================================================== --- sys/mips/ingenic/jz4780_codec.c +++ /dev/null @@ -1,310 +0,0 @@ -/*- - * Copyright (c) 2016 Ruslan Bukin - * All rights reserved. - * - * This software was developed by SRI International and the University of - * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 - * ("CTSRD"), as part of the DARPA CRASH research programme. - * - * 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. - */ - -/* Ingenic JZ4780 CODEC. */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include - -#include - -#include -#include - -#define CI20_HP_PIN 13 -#define CI20_HP_PORT 3 - -struct codec_softc { - device_t dev; - struct resource *res[1]; - bus_space_tag_t bst; - bus_space_handle_t bsh; - clk_t clk; -}; - -static struct resource_spec codec_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE }, - { -1, 0 } -}; - -static int codec_probe(device_t dev); -static int codec_attach(device_t dev); -static int codec_detach(device_t dev); -void codec_print_registers(struct codec_softc *sc); - -static int -codec_write(struct codec_softc *sc, uint32_t reg, uint32_t val) -{ - uint32_t tmp; - - clk_enable(sc->clk); - - tmp = (reg << RGADW_RGADDR_S); - tmp |= (val << RGADW_RGDIN_S); - tmp |= RGADW_RGWR; - - WRITE4(sc, CODEC_RGADW, tmp); - - while(READ4(sc, CODEC_RGADW) & RGADW_RGWR) - ; - - clk_disable(sc->clk); - - return (0); -} - -static int -codec_read(struct codec_softc *sc, uint32_t reg) -{ - uint32_t tmp; - - clk_enable(sc->clk); - - tmp = (reg << RGADW_RGADDR_S); - WRITE4(sc, CODEC_RGADW, tmp); - - tmp = READ4(sc, CODEC_RGDATA); - - clk_disable(sc->clk); - - return (tmp); -} - -void -codec_print_registers(struct codec_softc *sc) -{ - - printf("codec SR %x\n", codec_read(sc, SR)); - printf("codec SR2 %x\n", codec_read(sc, SR2)); - printf("codec MR %x\n", codec_read(sc, MR)); - printf("codec AICR_DAC %x\n", codec_read(sc, AICR_DAC)); - printf("codec AICR_ADC %x\n", codec_read(sc, AICR_ADC)); - printf("codec CR_LO %x\n", codec_read(sc, CR_LO)); - printf("codec CR_HP %x\n", codec_read(sc, CR_HP)); - printf("codec CR_DMIC %x\n", codec_read(sc, CR_DMIC)); - printf("codec CR_MIC1 %x\n", codec_read(sc, CR_MIC1)); - printf("codec CR_MIC2 %x\n", codec_read(sc, CR_MIC2)); - printf("codec CR_LI1 %x\n", codec_read(sc, CR_LI1)); - printf("codec CR_LI2 %x\n", codec_read(sc, CR_LI2)); - printf("codec CR_DAC %x\n", codec_read(sc, CR_DAC)); - printf("codec CR_ADC %x\n", codec_read(sc, CR_ADC)); - printf("codec CR_MIX %x\n", codec_read(sc, CR_MIX)); - printf("codec DR_MIX %x\n", codec_read(sc, DR_MIX)); - printf("codec CR_VIC %x\n", codec_read(sc, CR_VIC)); - printf("codec CR_CK %x\n", codec_read(sc, CR_CK)); - printf("codec FCR_DAC %x\n", codec_read(sc, FCR_DAC)); - printf("codec FCR_ADC %x\n", codec_read(sc, FCR_ADC)); - printf("codec CR_TIMER_MSB %x\n", codec_read(sc, CR_TIMER_MSB)); - printf("codec CR_TIMER_LSB %x\n", codec_read(sc, CR_TIMER_LSB)); - printf("codec ICR %x\n", codec_read(sc, ICR)); - printf("codec IMR %x\n", codec_read(sc, IMR)); - printf("codec IFR %x\n", codec_read(sc, IFR)); - printf("codec IMR2 %x\n", codec_read(sc, IMR2)); - printf("codec IFR2 %x\n", codec_read(sc, IFR2)); - printf("codec GCR_HPL %x\n", codec_read(sc, GCR_HPL)); - printf("codec GCR_HPR %x\n", codec_read(sc, GCR_HPR)); - printf("codec GCR_LIBYL %x\n", codec_read(sc, GCR_LIBYL)); - printf("codec GCR_LIBYR %x\n", codec_read(sc, GCR_LIBYR)); - printf("codec GCR_DACL %x\n", codec_read(sc, GCR_DACL)); - printf("codec GCR_DACR %x\n", codec_read(sc, GCR_DACR)); - printf("codec GCR_MIC1 %x\n", codec_read(sc, GCR_MIC1)); - printf("codec GCR_MIC2 %x\n", codec_read(sc, GCR_MIC2)); - printf("codec GCR_ADCL %x\n", codec_read(sc, GCR_ADCL)); - printf("codec GCR_ADCR %x\n", codec_read(sc, GCR_ADCR)); - printf("codec GCR_MIXDACL %x\n", codec_read(sc, GCR_MIXDACL)); - printf("codec GCR_MIXDACR %x\n", codec_read(sc, GCR_MIXDACR)); - printf("codec GCR_MIXADCL %x\n", codec_read(sc, GCR_MIXADCL)); - printf("codec GCR_MIXADCR %x\n", codec_read(sc, GCR_MIXADCR)); - printf("codec CR_ADC_AGC %x\n", codec_read(sc, CR_ADC_AGC)); - printf("codec DR_ADC_AGC %x\n", codec_read(sc, DR_ADC_AGC)); -} - -/* - * CI20 board-specific - */ -static int -ci20_hp_unmute(struct codec_softc *sc) -{ - device_t dev; - int port; - int err; - int pin; - - pin = CI20_HP_PIN; - port = CI20_HP_PORT; - - dev = devclass_get_device(devclass_find("gpio"), port); - if (dev == NULL) - return (0); - - err = GPIO_PIN_SETFLAGS(dev, pin, GPIO_PIN_OUTPUT); - if (err != 0) { - device_printf(dev, "Cannot configure GPIO pin %d on %s\n", - pin, device_get_nameunit(dev)); - return (err); - } - - err = GPIO_PIN_SET(dev, pin, 0); - if (err != 0) { - device_printf(dev, "Cannot configure GPIO pin %d on %s\n", - pin, device_get_nameunit(dev)); - return (err); - } - - return (0); -} - -static int -codec_probe(device_t dev) -{ - - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (!ofw_bus_is_compatible(dev, "ingenic,jz4780-codec")) - return (ENXIO); - - device_set_desc(dev, "Ingenic JZ4780 CODEC"); - - return (BUS_PROBE_DEFAULT); -} - -static int -codec_attach(device_t dev) -{ - struct codec_softc *sc; - uint8_t reg; - - sc = device_get_softc(dev); - sc->dev = dev; - - if (bus_alloc_resources(dev, codec_spec, sc->res)) { - device_printf(dev, "could not allocate resources for device\n"); - return (ENXIO); - } - - /* Memory interface */ - sc->bst = rman_get_bustag(sc->res[0]); - sc->bsh = rman_get_bushandle(sc->res[0]); - - if (clk_get_by_ofw_name(dev, 0, "i2s", &sc->clk) != 0) { - device_printf(dev, "could not get i2s clock\n"); - bus_release_resources(dev, codec_spec, sc->res); - return (ENXIO); - } - - /* Initialize codec. */ - reg = codec_read(sc, CR_VIC); - reg &= ~(VIC_SB_SLEEP | VIC_SB); - codec_write(sc, CR_VIC, reg); - - DELAY(20000); - - reg = codec_read(sc, CR_DAC); - reg &= ~(DAC_SB | DAC_MUTE); - codec_write(sc, CR_DAC, reg); - - DELAY(10000); - - /* I2S, 16-bit, 48 kHz. */ - reg = codec_read(sc, AICR_DAC); - reg &= ~(AICR_DAC_SB | DAC_ADWL_M); - reg |= DAC_ADWL_16; - reg &= ~(AUDIOIF_M); - reg |= AUDIOIF_I2S; - codec_write(sc, AICR_DAC, reg); - - DELAY(10000); - - reg = FCR_DAC_48; - codec_write(sc, FCR_DAC, reg); - - DELAY(10000); - - /* Unmute headphones. */ - reg = codec_read(sc, CR_HP); - reg &= ~(HP_SB | HP_MUTE); - codec_write(sc, CR_HP, reg); - - ci20_hp_unmute(sc); - - return (0); -} - -static int -codec_detach(device_t dev) -{ - struct codec_softc *sc; - - sc = device_get_softc(dev); - - bus_release_resources(dev, codec_spec, sc->res); - - return (0); -} - -static device_method_t codec_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, codec_probe), - DEVMETHOD(device_attach, codec_attach), - DEVMETHOD(device_detach, codec_detach), - - DEVMETHOD_END -}; - -static driver_t codec_driver = { - "codec", - codec_methods, - sizeof(struct codec_softc), -}; - -static devclass_t codec_devclass; - -DRIVER_MODULE(codec, simplebus, codec_driver, codec_devclass, 0, 0); Index: sys/mips/ingenic/jz4780_common.h =================================================================== --- sys/mips/ingenic/jz4780_common.h +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * Copyright (c) 2016 Ruslan Bukin - * All rights reserved. - * - * This software was developed by SRI International and the University of - * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 - * ("CTSRD"), as part of the DARPA CRASH research programme. - * - * 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$ - */ - -#define READ4(_sc, _reg) \ - bus_space_read_4(_sc->bst, _sc->bsh, _reg) -#define WRITE4(_sc, _reg, _val) \ - bus_space_write_4(_sc->bst, _sc->bsh, _reg, _val) Index: sys/mips/ingenic/jz4780_cpuregs.h =================================================================== --- sys/mips/ingenic/jz4780_cpuregs.h +++ /dev/null @@ -1,73 +0,0 @@ -/*- - * Copyright (c) 2015 Alexander Kabaev - * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef JZ4780_CPUREGS_H -#define JZ4780_CPUREGS_H - -/* Core control register */ -#define JZ_CORECTL_SLP1M_SHIFT 17 -#define JZ_CORECTL_SLP1M (1u << JZ_CORECTL_SLP1M_SHIFT) -#define JZ_CORECTL_SLP0M_SHIFT 16 -#define JZ_CORECTL_SLP0M (1u << JZ_CORECTL_SLP0M_SHIFT) -#define JZ_CORECTL_RPC1_SHIFT 9 -#define JZ_CORECTL_RPC1 (1u << JZ_CORECTL_RPC1_SHIFT) -#define JZ_CORECTL_RPC0_SHIFT 8 -#define JZ_CORECTL_RPC0 (1u << JZ_CORECTL_RPC0_SHIFT) -#define JZ_CORECTL_SWRST1_SHIFT 1 -#define JZ_CORECTL_SWRST1 (1u << JZ_CORECTL_SWRST1_SHIFT) -#define JZ_CORECTL_SWRST0_SHIFT 0 -#define JZ_CORECTL_SWRST0 (1u << JZ_CORECTL_SWRST0_SHIFT) - -/* Core status register */ -#define JZ_CORESTS_SLP1_SHIFT 17 -#define JZ_CORESTS_SLP1 (1u << JZ_CORESTS_SLP1_SHIFT) -#define JZ_CORESTS_SLP0_SHIFT 16 -#define JZ_CORESTS_SLP0 (1u << JZ_CORESTS_SLP0_SHIFT) -#define JZ_CORESTS_IRQ1P_SHIFT 9 -#define JZ_CORESTS_IRQ1P (1u << JZ_CORESTS_IRQ1P_SHIFT) -#define JZ_CORESTS_IRQ0P_SHIFT 8 -#define JZ_CORESTS_IRQ0P (1u << JZ_CORESTS_IRQ0P_SHIFT) -#define JZ_CORESTS_MIRQ1P_SHIFT 1 -#define JZ_CORESTS_MIRQ1P (1u << JZ_CORESTS_MIRQ1P_SHIFT) -#define JZ_CORESTS_MIRQ0P_SHIFT 0 -#define JZ_CORESTS_MIRQ0P (1u << JZ_CORESTS_MIRQ0P_SHIFT) - -/* Reset entry and IRQ mask */ -#define JZ_REIM_ENTRY_SHIFT 16 -#define JZ_REIM_ENTRY_WIDTH 16 -#define JZ_REIM_ENTRY_MASK (0xFFFFu << JZ_REIM_ENTRY_SHIFT) -#define JZ_REIM_IRQ1M_SHIFT 9 -#define JZ_REIM_IRQ1M (1u << JZ_REIM_IRQ1M_SHIFT) -#define JZ_REIM_IRQ0M_SHIFT 8 -#define JZ_REIM_IRQ0M (1u << JZ_REIM_IRQ0M_SHIFT) -#define JZ_REIM_MIRQ1M_SHIFT 1 -#define JZ_REIM_MIRQ1M (1u << JZ_REIM_MIRQ1M_SHIFT) -#define JZ_REIM_MIRQ0M_SHIFT 0 -#define JZ_REIM_MIRQ0M (1u << JZ_REIM_MIRQ0M_SHIFT) - -#endif /* JZ4780_CPUREGS_H */ Index: sys/mips/ingenic/jz4780_dme.c =================================================================== --- sys/mips/ingenic/jz4780_dme.c +++ /dev/null @@ -1,124 +0,0 @@ -/*- - * Copyright 2015 Alexander Kabaev - * 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. - */ - -/* - * Ingenic JZ4780 NAND and External Memory Controller (NEMC) driver. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -struct jz4780_dme_softc { - device_t dev; - struct resource *res[2]; -}; - -static struct resource_spec jz4780_dme_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE }, - { SYS_RES_MEMORY, 1, RF_ACTIVE }, - { -1, 0 } -}; - -static int jz4780_dme_probe(device_t dev); -static int jz4780_dme_attach(device_t dev); -static int jz4780_dme_detach(device_t dev); - -static int -jz4780_dme_probe(device_t dev) -{ - - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (!ofw_bus_is_compatible(dev, "davicom,dm9000")) - return (ENXIO); - - device_set_desc(dev, "Davicom DM9000C 10/100BaseTX"); - - return (BUS_PROBE_DEFAULT); -} - -static int -jz4780_dme_attach(device_t dev) -{ - struct jz4780_dme_softc *sc = device_get_softc(dev); - - sc->dev = dev; - - if (bus_alloc_resources(dev, jz4780_dme_spec, sc->res)) { - device_printf(dev, "could not allocate resources for device\n"); - return (ENXIO); - } - - return (0); -} - -static int -jz4780_dme_detach(device_t dev) -{ - struct jz4780_dme_softc *sc = device_get_softc(dev); - - bus_release_resources(dev, jz4780_dme_spec, sc->res); - return (0); -} - -static device_method_t jz4780_dme_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, jz4780_dme_probe), - DEVMETHOD(device_attach, jz4780_dme_attach), - DEVMETHOD(device_detach, jz4780_dme_detach), - - DEVMETHOD_END -}; - -static driver_t jz4780_dme_driver = { - "dme", - jz4780_dme_methods, - sizeof(struct jz4780_dme_softc), -}; - -static devclass_t jz4780_dme_devclass; - -DRIVER_MODULE(jz4780_dme, simplebus, jz4780_dme_driver, - jz4780_dme_devclass, 0, 0); Index: sys/mips/ingenic/jz4780_dwc_fdt.c =================================================================== --- sys/mips/ingenic/jz4780_dwc_fdt.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright 2015 Alexander Kabaev . - * 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 - -static device_probe_t jz4780_dwc_otg_probe; -static device_attach_t jz4780_dwc_otg_attach; -static device_detach_t jz4780_dwc_otg_detach; - -struct jz4780_dwc_otg_softc { - struct dwc_otg_fdt_softc base; /* storage for DWC OTG code */ - clk_t phy_clk; - clk_t otg_clk; -}; - -static int -jz4780_dwc_otg_clk_enable(device_t dev) -{ - struct jz4780_dwc_otg_softc *sc; - int err; - - sc = device_get_softc(dev); - - /* Configure and enable phy clock */ - err = clk_get_by_ofw_name(dev, 0, "otg_phy", &sc->phy_clk); - if (err != 0) { - device_printf(dev, "unable to lookup %s clock\n", "otg_phy"); - return (err); - } - err = clk_set_freq(sc->phy_clk, 48000000, 0); - if (err != 0) { - device_printf(dev, "unable to set %s clock to 48 kHZ\n", - "otg_phy"); - return (err); - } - err = clk_enable(sc->phy_clk); - if (err != 0) { - device_printf(dev, "unable to enable %s clock\n", "otg_phy"); - return (err); - } - - /* Configure and enable otg1 clock */ - err = clk_get_by_ofw_name(dev, 0, "otg1", &sc->otg_clk); - if (err != 0) { - device_printf(dev, "unable to lookup %s clock\n", "otg1"); - return (err); - } - err = clk_enable(sc->phy_clk); - if (err != 0) { - device_printf(dev, "unable to enable %s clock\n", "otg1"); - return (err); - } - - return (0); -} - -static int -jz4780_dwc_otg_probe(device_t dev) -{ - - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (!ofw_bus_is_compatible(dev, "ingenic,jz4780-otg")) - return (ENXIO); - - device_set_desc(dev, "DWC OTG 2.0 integrated USB controller (jz4780)"); - - return (BUS_PROBE_VENDOR); -} - -static int -jz4780_dwc_otg_attach(device_t dev) -{ - struct jz4780_dwc_otg_softc *sc; - struct resource *res; - int err, rid; - - sc = device_get_softc(dev); - - err = jz4780_dwc_otg_clk_enable(dev); - if (err != 0) - goto fail; - - err = jz4780_otg_enable(); - if (err != 0) { - device_printf(dev, "CGU failed to enable OTG\n"); - goto fail; - } - - /* Voodoo: Switch off VBUS overcurrent detection in OTG PHY */ - res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); - if (res != NULL) { - uint32_t reg; - - reg = bus_read_4(res, JZ_DWC2_GUSBCFG); - reg |= 0xc; - bus_write_4(res, JZ_DWC2_GUSBCFG, reg); - bus_release_resource(dev, SYS_RES_MEMORY, rid, res); - } - - sc->base.sc_otg.sc_phy_type = DWC_OTG_PHY_UTMI; - sc->base.sc_otg.sc_phy_bits = 16; - - err = dwc_otg_attach(dev); - if (err != 0) - goto fail; - - return (0); -fail: - if (sc->otg_clk) - clk_release(sc->otg_clk); - if (sc->phy_clk) - clk_release(sc->phy_clk); - return (err); -} - -static int -jz4780_dwc_otg_detach(device_t dev) -{ - struct jz4780_dwc_otg_softc *sc; - int err; - - err = dwc_otg_detach(dev); - if (err != 0) - return (err); - - sc = device_get_softc(dev); - if (sc->otg_clk) - clk_release(sc->otg_clk); - if (sc->phy_clk) - clk_release(sc->phy_clk); - return (0); -} - -static device_method_t jz4780_dwc_otg_methods[] = { - /* bus interface */ - DEVMETHOD(device_probe, jz4780_dwc_otg_probe), - DEVMETHOD(device_attach, jz4780_dwc_otg_attach), - DEVMETHOD(device_detach, jz4780_dwc_otg_detach), - - DEVMETHOD_END -}; - -static devclass_t jz4780_dwc_otg_devclass; - -DEFINE_CLASS_1(jzotg, jz4780_dwc_otg_driver, jz4780_dwc_otg_methods, - sizeof(struct jz4780_dwc_otg_softc), dwc_otg_driver); -DRIVER_MODULE(jzotg, simplebus, jz4780_dwc_otg_driver, - jz4780_dwc_otg_devclass, 0, 0); -MODULE_DEPEND(jzotg, usb, 1, 1, 1); Index: sys/mips/ingenic/jz4780_efuse.c =================================================================== --- sys/mips/ingenic/jz4780_efuse.c +++ /dev/null @@ -1,213 +0,0 @@ -/*- - * Copyright (c) 2015 Alexander Kabaev - * 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 - -static struct ofw_compat_data compat_data[] = { - {"ingenic,jz4780-efuse", 1}, - {NULL, 0} -}; - -struct jz4780_efuse_data { - uint32_t serial_num; - uint32_t date; - uint8_t nanufacturer[2]; - uint8_t macaddr[6]; -} __packed; - -static struct resource_spec jz4780_efuse_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE }, - { -1, 0 } -}; - -struct jz4780_efuse_softc { - device_t dev; - struct resource *res[1]; - struct jz4780_efuse_data data; -}; - -#define CSR_WRITE_4(sc, reg, val) \ - bus_write_4((sc)->res[0], (reg), (val)) -#define CSR_READ_4(sc, reg) \ - bus_read_4((sc)->res[0], (reg)) - -#define JZ_EFUSE_BANK_SIZE (4096 / 8) /* Bank size is 4096 bits */ - -static int -jz4780_efuse_probe(device_t dev) -{ - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) - return (ENXIO); - - return (BUS_PROBE_DEFAULT); -} - -static void -jz4780_efuse_read_chunk(struct jz4780_efuse_softc *sc, int addr, uint8_t *buf, int len) -{ - uint32_t abuf; - int i, count; - - /* Setup to read proper bank */ - CSR_WRITE_4(sc, JZ_EFUCTRL, JZ_EFUSE_READ | - (addr < JZ_EFUSE_BANK_SIZE ? 0: JZ_EFUSE_BANK) | - (addr << JZ_EFUSE_ADDR_SHIFT) | - ((len - 1) << JZ_EFUSE_SIZE_SHIFT)); - /* Wait for read to complete */ - while ((CSR_READ_4(sc, JZ_EFUSTATE) & JZ_EFUSE_RD_DONE) == 0) - DELAY(1000); - - /* Round to 4 bytes for the simple loop below */ - count = len & ~3; - - for (i = 0; i < count; i += 4) { - abuf = CSR_READ_4(sc, JZ_EFUDATA0 + i); - memcpy(buf, &abuf, 4); - buf += 4; - } - - /* Read partial word and assign it byte-by-byte */ - if (i < len) { - abuf = CSR_READ_4(sc, JZ_EFUDATA0 + i); - for (/* none */; i < len; i++) { - buf[i] = abuf & 0xff; - abuf >>= 8; - } - } -} - -static void -jz4780_efuse_read(struct jz4780_efuse_softc *sc, int addr, void *buf, int len) -{ - int chunk; - - while (len > 0) { - chunk = (len > 32) ? 32 : len; - jz4780_efuse_read_chunk(sc, addr, buf, chunk); - len -= chunk; - buf = (void *)((uintptr_t)buf + chunk); - addr += chunk; - } -} - -static void -jz4780_efuse_update_kenv(struct jz4780_efuse_softc *sc) -{ - char macstr[sizeof("xx:xx:xx:xx:xx:xx")]; - - /* - * Update hint in kernel env only if none is available yet. - * It is quite possible one was set by command line already. - */ - if (kern_getenv("hint.dme.0.macaddr") == NULL) { - snprintf(macstr, sizeof(macstr), "%6D", - sc->data.macaddr, ":"); - kern_setenv("hint.dme.0.macaddr", macstr); - } -} - -static int -jz4780_efuse_attach(device_t dev) -{ - struct jz4780_efuse_softc *sc; - - sc = device_get_softc(dev); - sc->dev = dev; - - if (bus_alloc_resources(dev, jz4780_efuse_spec, sc->res)) { - device_printf(dev, "could not allocate resources for device\n"); - return (ENXIO); - } - - /* - * Default RD_STROBE to 4 h2clk cycles, should already be set to 4 by reset - * but configure it anyway. - */ - CSR_WRITE_4(sc, JZ_EFUCFG, 0x00040000); - - /* Read user-id segment */ - jz4780_efuse_read(sc, 0x18, &sc->data, sizeof(sc->data)); - - /* - * Set resource hints for the dme device to discover its - * MAC address, if not set already. - */ - jz4780_efuse_update_kenv(sc); - - /* Resource conflicts with NEMC, release early */ - bus_release_resources(dev, jz4780_efuse_spec, sc->res); - return (0); -} - -static int -jz4780_efuse_detach(device_t dev) -{ - - return (0); -} - -static device_method_t jz4780_efuse_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, jz4780_efuse_probe), - DEVMETHOD(device_attach, jz4780_efuse_attach), - DEVMETHOD(device_detach, jz4780_efuse_detach), - - DEVMETHOD_END -}; - -static driver_t jz4780_efuse_driver = { - "efuse", - jz4780_efuse_methods, - sizeof(struct jz4780_efuse_softc), -}; - -static devclass_t jz4780_efuse_devclass; -EARLY_DRIVER_MODULE(jz4780_efuse, simplebus, jz4780_efuse_driver, - jz4780_efuse_devclass, 0, 0, BUS_PASS_TIMER); Index: sys/mips/ingenic/jz4780_ehci.c =================================================================== --- sys/mips/ingenic/jz4780_ehci.c +++ /dev/null @@ -1,345 +0,0 @@ -/*- - * Copyright (c) 2015 Oleksandr Tymoshenko . - * 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. - */ - -/* - * JZ4780 attachment driver for the USB Enhanced Host Controller. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include "opt_bus.h" - -#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 EHCI_HC_DEVSTR "Ingenic JZ4780 EHCI" - -struct jz4780_ehci_softc { - ehci_softc_t base; /* storage for EHCI code */ - clk_t clk; - struct gpiobus_pin *gpio_vbus; -}; - -static device_probe_t jz4780_ehci_probe; -static device_attach_t jz4780_ehci_attach; -static device_detach_t jz4780_ehci_detach; - -static int -jz4780_ehci_vbus_gpio_enable(device_t dev) -{ - struct gpiobus_pin *gpio_vbus; - struct jz4780_ehci_softc *sc; - int err; - - sc = device_get_softc(dev); - - err = ofw_gpiobus_parse_gpios(dev, "ingenic,vbus-gpio", &gpio_vbus); - /* - * The pin can ne already mapped by other device. Optimistically - * surge ahead. - */ - if (err <= 0) - return (0); - - sc->gpio_vbus = gpio_vbus; - if (err > 1) { - device_printf(dev, "too many vbus gpios\n"); - return (ENXIO); - } - - if (sc->gpio_vbus != NULL) { - err = GPIO_PIN_SETFLAGS(sc->gpio_vbus->dev, sc->gpio_vbus->pin, - GPIO_PIN_OUTPUT); - if (err != 0) { - device_printf(dev, "Cannot configure GPIO pin %d on %s\n", - sc->gpio_vbus->pin, device_get_nameunit(sc->gpio_vbus->dev)); - return (err); - } - - err = GPIO_PIN_SET(sc->gpio_vbus->dev, sc->gpio_vbus->pin, 1); - if (err != 0) { - device_printf(dev, "Cannot configure GPIO pin %d on %s\n", - sc->gpio_vbus->pin, device_get_nameunit(sc->gpio_vbus->dev)); - return (err); - } - } - return (0); -} - -static int -jz4780_ehci_clk_enable(device_t dev) -{ - struct jz4780_ehci_softc *sc; - int err; - - sc = device_get_softc(dev); - - err = clk_get_by_ofw_index(dev, 0, 0, &sc->clk); - if (err != 0) { - device_printf(dev, "unable to lookup device clock\n"); - return (err); - } - err = clk_enable(sc->clk); - if (err != 0) { - device_printf(dev, "unable to enable device clock\n"); - return (err); - } - err = clk_set_freq(sc->clk, 48000000, 0); - if (err != 0) { - device_printf(dev, "unable to set device clock to 48 kHZ\n"); - return (err); - } - return (0); -} - -static void -jz4780_ehci_intr(void *arg) -{ - - ehci_interrupt(arg); -} - -static int -jz4780_ehci_probe(device_t dev) -{ - - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (!ofw_bus_is_compatible(dev, "ingenic,jz4780-ehci")) - return (ENXIO); - - device_set_desc(dev, EHCI_HC_DEVSTR); - - return (BUS_PROBE_DEFAULT); -} - -static int -jz4780_ehci_attach(device_t dev) -{ - struct jz4780_ehci_softc *isc; - ehci_softc_t *sc; - int err; - int rid; - uint32_t reg; - - isc = device_get_softc(dev); - sc = &isc->base; - - /* initialise some bus fields */ - sc->sc_bus.parent = dev; - sc->sc_bus.devices = sc->sc_devices; - sc->sc_bus.devices_max = EHCI_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), &ehci_iterate_hw_softc)) { - return (ENOMEM); - } - - sc->sc_bus.usbrev = USB_REV_2_0; - - err = jz4780_ehci_vbus_gpio_enable(dev); - if (err) - goto error; - - rid = 0; - sc->sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); - if (!sc->sc_io_res) { - device_printf(dev, "Could not map memory\n"); - goto error; - } - - /* - * Craft special resource for bus space ops that handle - * byte-alignment of non-word addresses. - */ - 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); - - err = jz4780_ehci_clk_enable(dev); - if (err) - goto error; - - if (jz4780_ehci_enable() != 0) { - device_printf(dev, "CGU failed to enable EHCI\n"); - err = ENXIO; - goto error; - } - - EWRITE4(sc, EHCI_USBINTR, 0); - - 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) { - device_printf(dev, "Could not allocate irq\n"); - goto error; - } - sc->sc_bus.bdev = device_add_child(dev, "usbus", -1); - if (!sc->sc_bus.bdev) { - device_printf(dev, "Could not add USB device\n"); - goto error; - } - device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus); - device_set_desc(sc->sc_bus.bdev, EHCI_HC_DEVSTR); - - sprintf(sc->sc_vendor, "Ingenic"); - - err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, - NULL, jz4780_ehci_intr, sc, &sc->sc_intr_hdl); - if (err) { - device_printf(dev, "Could not setup irq, %d\n", err); - sc->sc_intr_hdl = NULL; - goto error; - } - - err = ehci_init(sc); - if (!err) { - /* Voodoo: set utmi data bus width on controller to 16 bit */ - reg = EREAD4(sc, JZ_EHCI_REG_UTMI_BUS); - reg |= UTMI_BUS_WIDTH; - EWRITE4(sc, JZ_EHCI_REG_UTMI_BUS, reg); - - err = device_probe_and_attach(sc->sc_bus.bdev); - } - if (err) { - device_printf(dev, "USB init failed err=%d\n", err); - goto error; - } - return (0); - -error: - jz4780_ehci_detach(dev); - return (ENXIO); -} - -static int -jz4780_ehci_detach(device_t dev) -{ - struct jz4780_ehci_softc *isc; - ehci_softc_t *sc; - device_t bdev; - int err; - - isc = device_get_softc(dev); - sc = &isc->base; - - if (sc->sc_bus.bdev) { - bdev = sc->sc_bus.bdev; - device_detach(bdev); - device_delete_child(dev, bdev); - } - /* during module unload there are lots of children leftover */ - device_delete_children(dev); - - if (sc->sc_irq_res && sc->sc_intr_hdl) { - /* - * only call ehci_detach() after ehci_init() - */ - ehci_detach(sc); - - err = bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intr_hdl); - - if (err) - /* XXX or should we panic? */ - device_printf(dev, "Could not tear down irq, %d\n", - err); - 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_MEMORY, 0, - sc->sc_io_res); - sc->sc_io_res = NULL; - } - - if (isc->clk) - clk_release(isc->clk); - - usb_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc); - free(isc->gpio_vbus, M_DEVBUF); - return (0); -} - -static device_method_t ehci_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, jz4780_ehci_probe), - DEVMETHOD(device_attach, jz4780_ehci_attach), - DEVMETHOD(device_detach, jz4780_ehci_detach), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - - DEVMETHOD_END -}; - -static driver_t ehci_driver = { - .name = "ehci", - .methods = ehci_methods, - .size = sizeof(struct jz4780_ehci_softc), -}; - -static devclass_t ehci_devclass; - -DRIVER_MODULE(ehci, simplebus, ehci_driver, ehci_devclass, 0, 0); -MODULE_DEPEND(ehci, usb, 1, 1, 1); -MODULE_DEPEND(ehci, gpio, 1, 1, 1); Index: sys/mips/ingenic/jz4780_gpio.c =================================================================== --- sys/mips/ingenic/jz4780_gpio.c +++ /dev/null @@ -1,840 +0,0 @@ -/*- - * Copyright 2015 Alexander Kabaev - * 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 "opt_platform.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include - -#include -#include - -#include "jz4780_gpio_if.h" -#include "gpio_if.h" -#include "pic_if.h" - -#define JZ4780_GPIO_PINS 32 - -enum pin_function { - JZ_FUNC_DEV_0, - JZ_FUNC_DEV_1, - JZ_FUNC_DEV_2, - JZ_FUNC_DEV_3, - JZ_FUNC_GPIO, - JZ_FUNC_INTR, -}; - -struct jz4780_gpio_pin { - struct intr_irqsrc pin_irqsrc; - enum intr_trigger intr_trigger; - enum intr_polarity intr_polarity; - enum pin_function pin_func; - uint32_t pin_caps; - uint32_t pin_flags; - uint32_t pin_num; - char pin_name[GPIOMAXNAME]; -}; - -struct jz4780_gpio_softc { - device_t dev; - device_t busdev; - struct resource *res[2]; - struct mtx mtx; - struct jz4780_gpio_pin pins[JZ4780_GPIO_PINS]; - void *intrhand; -}; - -static struct resource_spec jz4780_gpio_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE }, - { SYS_RES_IRQ, 0, RF_ACTIVE }, - { -1, 0 } -}; - -static int jz4780_gpio_probe(device_t dev); -static int jz4780_gpio_attach(device_t dev); -static int jz4780_gpio_detach(device_t dev); -static int jz4780_gpio_intr(void *arg); - -#define JZ4780_GPIO_LOCK(sc) mtx_lock_spin(&(sc)->mtx) -#define JZ4780_GPIO_UNLOCK(sc) mtx_unlock_spin(&(sc)->mtx) -#define JZ4780_GPIO_LOCK_INIT(sc) \ - mtx_init(&(sc)->mtx, device_get_nameunit((sc)->dev), \ - "jz4780_gpio", MTX_SPIN) -#define JZ4780_GPIO_LOCK_DESTROY(sc) mtx_destroy(&(sc)->mtx); - -#define CSR_WRITE_4(sc, reg, val) bus_write_4((sc)->res[0], (reg), (val)) -#define CSR_READ_4(sc, reg) bus_read_4((sc)->res[0], (reg)) - -static int -jz4780_gpio_probe(device_t dev) -{ - phandle_t node; - - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - /* We only like particular parent */ - if (!ofw_bus_is_compatible(device_get_parent(dev), - "ingenic,jz4780-pinctrl")) - return (ENXIO); - - /* ... and only specific children os that parent */ - node = ofw_bus_get_node(dev); - if (!OF_hasprop(node, "gpio-controller")) - return (ENXIO); - - device_set_desc(dev, "Ingenic JZ4780 GPIO Controller"); - - return (BUS_PROBE_DEFAULT); -} - -static int -jz4780_gpio_pin_set_func(struct jz4780_gpio_softc *sc, uint32_t pin, - uint32_t func) -{ - uint32_t mask = (1u << pin); - - if (func > (uint32_t)JZ_FUNC_DEV_3) - return (EINVAL); - - CSR_WRITE_4(sc, JZ_GPIO_INTC, mask); - CSR_WRITE_4(sc, JZ_GPIO_MASKC, mask); - if (func & 2) - CSR_WRITE_4(sc, JZ_GPIO_PAT1S, mask); - else - CSR_WRITE_4(sc, JZ_GPIO_PAT1C, mask); - if (func & 1) - CSR_WRITE_4(sc, JZ_GPIO_PAT0S, mask); - else - CSR_WRITE_4(sc, JZ_GPIO_PAT0C, mask); - - sc->pins[pin].pin_flags &= ~(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT); - sc->pins[pin].pin_func = (enum pin_function)func; - return (0); -} - -static int -jz4780_gpio_pin_set_direction(struct jz4780_gpio_softc *sc, - uint32_t pin, uint32_t dir) -{ - uint32_t mask = (1u << pin); - - switch (dir) { - case GPIO_PIN_OUTPUT: - if (sc->pins[pin].pin_caps & dir) - CSR_WRITE_4(sc, JZ_GPIO_PAT1C, mask); - else - return (EINVAL); - break; - case GPIO_PIN_INPUT: - if (sc->pins[pin].pin_caps & dir) - CSR_WRITE_4(sc, JZ_GPIO_PAT1S, mask); - else - return (EINVAL); - break; - } - - sc->pins[pin].pin_flags &= ~(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT); - sc->pins[pin].pin_flags |= dir; - return (0); -} - -static int -jz4780_gpio_pin_set_bias(struct jz4780_gpio_softc *sc, - uint32_t pin, uint32_t bias) -{ - uint32_t mask = (1u << pin); - - switch (bias) { - case GPIO_PIN_PULLUP: - case GPIO_PIN_PULLDOWN: - if (sc->pins[pin].pin_caps & bias) - CSR_WRITE_4(sc, JZ_GPIO_DPULLC, mask); - else - return (EINVAL); - break; - case 0: - CSR_WRITE_4(sc, JZ_GPIO_DPULLS, mask); - break; - default: - return (ENOTSUP); - } - - sc->pins[pin].pin_flags &= ~(GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN); - sc->pins[pin].pin_flags |= bias; - return (0); -} - -/* - * Decode pin configuration using this map - */ -#if 0 -INT MASK PAT1 PAT0 -1 x 0 0 /* intr, level, low */ -1 x 0 1 /* intr, level, high */ -1 x 1 0 /* intr, edge, falling */ -1 x 1 1 /* intr, edge, rising */ -0 0 0 0 /* function, func 0 */ -0 0 0 1 /* function, func 1 */ -0 0 1 0 /* function, func 2 */ -0 0 1 0 /* function, func 3 */ -0 1 0 0 /* gpio, output 0 */ -0 1 0 1 /* gpio, output 1 */ -0 1 1 x /* gpio, input */ -#endif - -static void -jz4780_gpio_pin_probe(struct jz4780_gpio_softc *sc, uint32_t pin) -{ - uint32_t mask = (1u << pin); - uint32_t val; - - /* Clear cached gpio config */ - sc->pins[pin].pin_flags = 0; - - /* First check if pin is in interrupt mode */ - val = CSR_READ_4(sc, JZ_GPIO_INT); - if (val & mask) { - /* Pin is in interrupt mode, decode interrupt triggering mode */ - val = CSR_READ_4(sc, JZ_GPIO_PAT1); - if (val & mask) - sc->pins[pin].intr_trigger = INTR_TRIGGER_EDGE; - else - sc->pins[pin].intr_trigger = INTR_TRIGGER_LEVEL; - /* Decode interrupt polarity */ - val = CSR_READ_4(sc, JZ_GPIO_PAT0); - if (val & mask) - sc->pins[pin].intr_polarity = INTR_POLARITY_HIGH; - else - sc->pins[pin].intr_polarity = INTR_POLARITY_LOW; - - sc->pins[pin].pin_func = JZ_FUNC_INTR; - sc->pins[pin].pin_flags = 0; - return; - } - /* Next check if pin is in gpio mode */ - val = CSR_READ_4(sc, JZ_GPIO_MASK); - if (val & mask) { - /* Pin is in gpio mode, decode direction and bias */ - val = CSR_READ_4(sc, JZ_GPIO_PAT1); - if (val & mask) - sc->pins[pin].pin_flags |= GPIO_PIN_INPUT; - else - sc->pins[pin].pin_flags |= GPIO_PIN_OUTPUT; - /* Check for bias */ - val = CSR_READ_4(sc, JZ_GPIO_DPULL); - if ((val & mask) == 0) - sc->pins[pin].pin_flags |= sc->pins[pin].pin_caps & - (GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN); - sc->pins[pin].pin_func = JZ_FUNC_GPIO; - return; - } - /* By exclusion, pin is in alternate function mode */ - val = CSR_READ_4(sc, JZ_GPIO_DPULL); - if ((val & mask) == 0) - sc->pins[pin].pin_flags = sc->pins[pin].pin_caps & - (GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN); - val = ((CSR_READ_4(sc, JZ_GPIO_PAT1) & mask) >> pin) << 1; - val = val | ((CSR_READ_4(sc, JZ_GPIO_PAT1) & mask) >> pin); - sc->pins[pin].pin_func = (enum pin_function)val; -} - -static int -jz4780_gpio_register_isrcs(struct jz4780_gpio_softc *sc) -{ - int error; - uint32_t irq, i; - struct intr_irqsrc *isrc; - const char *name; - - name = device_get_nameunit(sc->dev); - for (irq = 0; irq < JZ4780_GPIO_PINS; irq++) { - isrc = &sc->pins[irq].pin_irqsrc; - error = intr_isrc_register(isrc, sc->dev, 0, "%s,%d", - name, irq); - if (error != 0) { - for (i = 0; i < irq; i++) - intr_isrc_deregister(&sc->pins[i].pin_irqsrc); - device_printf(sc->dev, "%s failed", __func__); - return (error); - } - } - - return (0); -} - -static int -jz4780_gpio_attach(device_t dev) -{ - struct jz4780_gpio_softc *sc = device_get_softc(dev); - phandle_t node; - uint32_t i, pd_pins, pu_pins; - - sc->dev = dev; - - if (bus_alloc_resources(dev, jz4780_gpio_spec, sc->res)) { - device_printf(dev, "could not allocate resources for device\n"); - return (ENXIO); - } - - JZ4780_GPIO_LOCK_INIT(sc); - - node = ofw_bus_get_node(dev); - OF_getencprop(node, "ingenic,pull-ups", &pu_pins, sizeof(pu_pins)); - OF_getencprop(node, "ingenic,pull-downs", &pd_pins, sizeof(pd_pins)); - - for (i = 0; i < JZ4780_GPIO_PINS; i++) { - sc->pins[i].pin_num = i; - sc->pins[i].pin_caps |= GPIO_PIN_INPUT | GPIO_PIN_OUTPUT; - if (pu_pins & (1 << i)) - sc->pins[i].pin_caps |= GPIO_PIN_PULLUP; - if (pd_pins & (1 << i)) - sc->pins[i].pin_caps |= GPIO_PIN_PULLDOWN; - sc->pins[i].intr_polarity = INTR_POLARITY_CONFORM; - sc->pins[i].intr_trigger = INTR_TRIGGER_CONFORM; - - snprintf(sc->pins[i].pin_name, GPIOMAXNAME - 1, "gpio%c%d", - device_get_unit(dev) + 'a', i); - sc->pins[i].pin_name[GPIOMAXNAME - 1] = '\0'; - - jz4780_gpio_pin_probe(sc, i); - } - - if (jz4780_gpio_register_isrcs(sc) != 0) - goto fail; - - if (intr_pic_register(dev, OF_xref_from_node(node)) == NULL) { - device_printf(dev, "could not register PIC\n"); - goto fail; - } - - if (bus_setup_intr(dev, sc->res[1], INTR_TYPE_MISC | INTR_MPSAFE, - jz4780_gpio_intr, NULL, sc, &sc->intrhand) != 0) - goto fail_pic; - - sc->busdev = gpiobus_attach_bus(dev); - if (sc->busdev == NULL) - goto fail_pic; - - return (0); -fail_pic: - intr_pic_deregister(dev, OF_xref_from_node(node)); -fail: - if (sc->intrhand != NULL) - bus_teardown_intr(dev, sc->res[1], sc->intrhand); - bus_release_resources(dev, jz4780_gpio_spec, sc->res); - JZ4780_GPIO_LOCK_DESTROY(sc); - return (ENXIO); -} - -static int -jz4780_gpio_detach(device_t dev) -{ - struct jz4780_gpio_softc *sc = device_get_softc(dev); - - bus_release_resources(dev, jz4780_gpio_spec, sc->res); - JZ4780_GPIO_LOCK_DESTROY(sc); - return (0); -} - -static int -jz4780_gpio_configure_pin(device_t dev, uint32_t pin, uint32_t func, - uint32_t flags) -{ - struct jz4780_gpio_softc *sc; - int retval; - - if (pin >= JZ4780_GPIO_PINS) - return (EINVAL); - - sc = device_get_softc(dev); - JZ4780_GPIO_LOCK(sc); - retval = jz4780_gpio_pin_set_func(sc, pin, func); - if (retval == 0) - retval = jz4780_gpio_pin_set_bias(sc, pin, flags); - JZ4780_GPIO_UNLOCK(sc); - return (retval); -} - -static device_t -jz4780_gpio_get_bus(device_t dev) -{ - struct jz4780_gpio_softc *sc; - - sc = device_get_softc(dev); - - return (sc->busdev); -} - -static int -jz4780_gpio_pin_max(device_t dev, int *maxpin) -{ - - *maxpin = JZ4780_GPIO_PINS - 1; - return (0); -} - -static int -jz4780_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) -{ - struct jz4780_gpio_softc *sc; - - if (pin >= JZ4780_GPIO_PINS) - return (EINVAL); - - sc = device_get_softc(dev); - JZ4780_GPIO_LOCK(sc); - *caps = sc->pins[pin].pin_caps; - JZ4780_GPIO_UNLOCK(sc); - - return (0); -} - -static int -jz4780_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) -{ - struct jz4780_gpio_softc *sc; - - if (pin >= JZ4780_GPIO_PINS) - return (EINVAL); - - sc = device_get_softc(dev); - JZ4780_GPIO_LOCK(sc); - *flags = sc->pins[pin].pin_flags; - JZ4780_GPIO_UNLOCK(sc); - - return (0); -} - -static int -jz4780_gpio_pin_getname(device_t dev, uint32_t pin, char *name) -{ - struct jz4780_gpio_softc *sc; - - if (pin >= JZ4780_GPIO_PINS) - return (EINVAL); - - sc = device_get_softc(dev); - strncpy(name, sc->pins[pin].pin_name, GPIOMAXNAME - 1); - name[GPIOMAXNAME - 1] = '\0'; - - return (0); -} - -static int -jz4780_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) -{ - struct jz4780_gpio_softc *sc; - int retval; - - if (pin >= JZ4780_GPIO_PINS) - return (EINVAL); - - sc = device_get_softc(dev); - JZ4780_GPIO_LOCK(sc); - retval = jz4780_gpio_pin_set_direction(sc, pin, - flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)); - if (retval == 0) - retval = jz4780_gpio_pin_set_bias(sc, pin, - flags & (GPIO_PIN_PULLDOWN | GPIO_PIN_PULLUP)); - JZ4780_GPIO_UNLOCK(sc); - - return (retval); -} - -static int -jz4780_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) -{ - struct jz4780_gpio_softc *sc; - uint32_t mask; - int retval; - - if (pin >= JZ4780_GPIO_PINS) - return (EINVAL); - - retval = EINVAL; - mask = (1u << pin); - sc = device_get_softc(dev); - JZ4780_GPIO_LOCK(sc); - if (sc->pins[pin].pin_func == JZ_FUNC_GPIO) { - CSR_WRITE_4(sc, value ? JZ_GPIO_PAT0S : JZ_GPIO_PAT0C, mask); - retval = 0; - } - JZ4780_GPIO_UNLOCK(sc); - - return (retval); -} - -static int -jz4780_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) -{ - struct jz4780_gpio_softc *sc; - uint32_t data, mask; - - if (pin >= JZ4780_GPIO_PINS) - return (EINVAL); - - mask = (1u << pin); - sc = device_get_softc(dev); - JZ4780_GPIO_LOCK(sc); - data = CSR_READ_4(sc, JZ_GPIO_PIN); - JZ4780_GPIO_UNLOCK(sc); - *val = (data & mask) ? 1 : 0; - - return (0); -} - -static int -jz4780_gpio_pin_toggle(device_t dev, uint32_t pin) -{ - struct jz4780_gpio_softc *sc; - uint32_t data, mask; - int retval; - - if (pin >= JZ4780_GPIO_PINS) - return (EINVAL); - - retval = EINVAL; - mask = (1u << pin); - sc = device_get_softc(dev); - JZ4780_GPIO_LOCK(sc); - if (sc->pins[pin].pin_func == JZ_FUNC_GPIO && - sc->pins[pin].pin_flags & GPIO_PIN_OUTPUT) { - data = CSR_READ_4(sc, JZ_GPIO_PIN); - CSR_WRITE_4(sc, (data & mask) ? JZ_GPIO_PAT0C : JZ_GPIO_PAT0S, - mask); - retval = 0; - } - JZ4780_GPIO_UNLOCK(sc); - - return (retval); -} - -#ifdef FDT -static int -jz_gpio_map_intr_fdt(device_t dev, struct intr_map_data *data, u_int *irqp, - enum intr_polarity *polp, enum intr_trigger *trigp) -{ - struct jz4780_gpio_softc *sc; - struct intr_map_data_fdt *daf; - - sc = device_get_softc(dev); - daf = (struct intr_map_data_fdt *)data; - - if (data == NULL || data->type != INTR_MAP_DATA_FDT || - daf->ncells == 0 || daf->ncells > 2) - return (EINVAL); - - *irqp = daf->cells[0]; - if (daf->ncells == 1) { - *trigp = INTR_TRIGGER_CONFORM; - *polp = INTR_POLARITY_CONFORM; - return (0); - } - - switch (daf->cells[1]) - { - case IRQ_TYPE_EDGE_RISING: - *trigp = INTR_TRIGGER_EDGE; - *polp = INTR_POLARITY_HIGH; - break; - case IRQ_TYPE_EDGE_FALLING: - *trigp = INTR_TRIGGER_EDGE; - *polp = INTR_POLARITY_LOW; - break; - case IRQ_TYPE_LEVEL_HIGH: - *trigp = INTR_TRIGGER_LEVEL; - *polp = INTR_POLARITY_HIGH; - break; - case IRQ_TYPE_LEVEL_LOW: - *trigp = INTR_TRIGGER_LEVEL; - *polp = INTR_POLARITY_LOW; - break; - default: - device_printf(sc->dev, "unsupported trigger/polarity 0x%2x\n", - daf->cells[1]); - return (ENOTSUP); - } - - return (0); -} -#endif - -static int -jz_gpio_map_intr(device_t dev, struct intr_map_data *data, u_int *irqp, - enum intr_polarity *polp, enum intr_trigger *trigp) -{ - struct jz4780_gpio_softc *sc; - enum intr_polarity pol; - enum intr_trigger trig; - u_int irq; - - sc = device_get_softc(dev); - switch (data->type) { -#ifdef FDT - case INTR_MAP_DATA_FDT: - if (jz_gpio_map_intr_fdt(dev, data, &irq, &pol, &trig) != 0) - return (EINVAL); - break; -#endif - default: - return (EINVAL); - } - - if (irq >= nitems(sc->pins)) - return (EINVAL); - - *irqp = irq; - if (polp != NULL) - *polp = pol; - if (trigp != NULL) - *trigp = trig; - return (0); -} - -static int -jz4780_gpio_pic_map_intr(device_t dev, struct intr_map_data *data, - struct intr_irqsrc **isrcp) -{ - struct jz4780_gpio_softc *sc; - int retval; - u_int irq; - - retval = jz_gpio_map_intr(dev, data, &irq, NULL, NULL); - if (retval == 0) { - sc = device_get_softc(dev); - *isrcp = &sc->pins[irq].pin_irqsrc; - } - return (retval); -} - -static int -jz4780_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc, - struct resource *res, struct intr_map_data *data) -{ - struct jz4780_gpio_softc *sc; - struct jz4780_gpio_pin *pin; - enum intr_polarity pol; - enum intr_trigger trig; - uint32_t mask, irq; - - if (data == NULL) - return (ENOTSUP); - - /* Get config for resource. */ - if (jz_gpio_map_intr(dev, data, &irq, &pol, &trig)) - return (EINVAL); - - pin = __containerof(isrc, struct jz4780_gpio_pin, pin_irqsrc); - if (isrc != &pin->pin_irqsrc) - return (EINVAL); - - /* Compare config if this is not first setup. */ - if (isrc->isrc_handlers != 0) { - if ((pol != INTR_POLARITY_CONFORM && pol != pin->intr_polarity) || - (trig != INTR_TRIGGER_CONFORM && trig != pin->intr_trigger)) - return (EINVAL); - else - return (0); - } - - if (pol == INTR_POLARITY_CONFORM) - pol = INTR_POLARITY_LOW; /* just pick some */ - if (trig == INTR_TRIGGER_CONFORM) - trig = INTR_TRIGGER_EDGE; /* just pick some */ - - sc = device_get_softc(dev); - mask = 1u << pin->pin_num; - - JZ4780_GPIO_LOCK(sc); - CSR_WRITE_4(sc, JZ_GPIO_MASKS, mask); - CSR_WRITE_4(sc, JZ_GPIO_INTS, mask); - - if (trig == INTR_TRIGGER_LEVEL) - CSR_WRITE_4(sc, JZ_GPIO_PAT1C, mask); - else - CSR_WRITE_4(sc, JZ_GPIO_PAT1S, mask); - - if (pol == INTR_POLARITY_LOW) - CSR_WRITE_4(sc, JZ_GPIO_PAT0C, mask); - else - CSR_WRITE_4(sc, JZ_GPIO_PAT0S, mask); - - pin->pin_func = JZ_FUNC_INTR; - pin->intr_trigger = trig; - pin->intr_polarity = pol; - - CSR_WRITE_4(sc, JZ_GPIO_FLAGC, mask); - CSR_WRITE_4(sc, JZ_GPIO_MASKC, mask); - JZ4780_GPIO_UNLOCK(sc); - return (0); -} - -static void -jz4780_gpio_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc) -{ - struct jz4780_gpio_softc *sc; - struct jz4780_gpio_pin *pin; - - sc = device_get_softc(dev); - pin = __containerof(isrc, struct jz4780_gpio_pin, pin_irqsrc); - - CSR_WRITE_4(sc, JZ_GPIO_MASKC, 1u << pin->pin_num); -} - -static void -jz4780_gpio_pic_disable_intr(device_t dev, struct intr_irqsrc *isrc) -{ - struct jz4780_gpio_softc *sc; - struct jz4780_gpio_pin *pin; - - sc = device_get_softc(dev); - pin = __containerof(isrc, struct jz4780_gpio_pin, pin_irqsrc); - - CSR_WRITE_4(sc, JZ_GPIO_MASKS, 1u << pin->pin_num); -} - -static void -jz4780_gpio_pic_pre_ithread(device_t dev, struct intr_irqsrc *isrc) -{ - - jz4780_gpio_pic_disable_intr(dev, isrc); -} - -static void -jz4780_gpio_pic_post_ithread(device_t dev, struct intr_irqsrc *isrc) -{ - - jz4780_gpio_pic_enable_intr(dev, isrc); -} - -static void -jz4780_gpio_pic_post_filter(device_t dev, struct intr_irqsrc *isrc) -{ - struct jz4780_gpio_softc *sc; - struct jz4780_gpio_pin *pin; - - sc = device_get_softc(dev); - pin = __containerof(isrc, struct jz4780_gpio_pin, pin_irqsrc); - - CSR_WRITE_4(sc, JZ_GPIO_FLAGC, 1u << pin->pin_num); -} - -static int -jz4780_gpio_intr(void *arg) -{ - struct jz4780_gpio_softc *sc; - uint32_t i, interrupts; - - sc = arg; - interrupts = CSR_READ_4(sc, JZ_GPIO_FLAG); - - for (i = 0; interrupts != 0; i++, interrupts >>= 1) { - if ((interrupts & 0x1) == 0) - continue; - if (intr_isrc_dispatch(&sc->pins[i].pin_irqsrc, - curthread->td_intr_frame) != 0) { - device_printf(sc->dev, "spurious interrupt %d\n", i); - PIC_DISABLE_INTR(sc->dev, &sc->pins[i].pin_irqsrc); - } - } - - return (FILTER_HANDLED); -} - -static phandle_t -jz4780_gpio_bus_get_node(device_t bus, device_t dev) -{ - - return (ofw_bus_get_node(bus)); -} - -static device_method_t jz4780_gpio_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, jz4780_gpio_probe), - DEVMETHOD(device_attach, jz4780_gpio_attach), - DEVMETHOD(device_detach, jz4780_gpio_detach), - - /* GPIO protocol */ - DEVMETHOD(gpio_get_bus, jz4780_gpio_get_bus), - DEVMETHOD(gpio_pin_max, jz4780_gpio_pin_max), - DEVMETHOD(gpio_pin_getname, jz4780_gpio_pin_getname), - DEVMETHOD(gpio_pin_getflags, jz4780_gpio_pin_getflags), - DEVMETHOD(gpio_pin_getcaps, jz4780_gpio_pin_getcaps), - DEVMETHOD(gpio_pin_setflags, jz4780_gpio_pin_setflags), - DEVMETHOD(gpio_pin_get, jz4780_gpio_pin_get), - DEVMETHOD(gpio_pin_set, jz4780_gpio_pin_set), - DEVMETHOD(gpio_pin_toggle, jz4780_gpio_pin_toggle), - - /* Custom interface to set pin function */ - DEVMETHOD(jz4780_gpio_configure_pin, jz4780_gpio_configure_pin), - - /* Interrupt controller interface */ - DEVMETHOD(pic_setup_intr, jz4780_gpio_pic_setup_intr), - DEVMETHOD(pic_enable_intr, jz4780_gpio_pic_enable_intr), - DEVMETHOD(pic_disable_intr, jz4780_gpio_pic_disable_intr), - DEVMETHOD(pic_map_intr, jz4780_gpio_pic_map_intr), - DEVMETHOD(pic_post_filter, jz4780_gpio_pic_post_filter), - DEVMETHOD(pic_post_ithread, jz4780_gpio_pic_post_ithread), - DEVMETHOD(pic_pre_ithread, jz4780_gpio_pic_pre_ithread), - - /* ofw_bus interface */ - DEVMETHOD(ofw_bus_get_node, jz4780_gpio_bus_get_node), - - DEVMETHOD_END -}; - -static driver_t jz4780_gpio_driver = { - "gpio", - jz4780_gpio_methods, - sizeof(struct jz4780_gpio_softc), -}; - -static devclass_t jz4780_gpio_devclass; - -EARLY_DRIVER_MODULE(jz4780_gpio, simplebus, jz4780_gpio_driver, - jz4780_gpio_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE); Index: sys/mips/ingenic/jz4780_gpio_if.m =================================================================== --- sys/mips/ingenic/jz4780_gpio_if.m +++ /dev/null @@ -1,41 +0,0 @@ -#- -# Copyright (c) 2015 Alexander Kabaev -# 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$ -# - -#include - -INTERFACE jz4780_gpio; - -/** - * Configures pin as specified by FDT pinctrl entry - */ -METHOD int configure_pin { - device_t dev; - uint32_t gpio; - uint32_t func; - uint32_t flags; -}; Index: sys/mips/ingenic/jz4780_intr.c =================================================================== --- sys/mips/ingenic/jz4780_intr.c +++ /dev/null @@ -1,333 +0,0 @@ -/*- - * Copyright (c) 2015 Alexander Kabaev - * 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, - * without modification, immediately at the beginning of the file. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 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 "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 -#include -#include - -#include - -#include "pic_if.h" - -#define JZ4780_NIRQS 64 - -static int jz4780_pic_intr(void *); - -struct jz4780_pic_isrc { - struct intr_irqsrc isrc; - u_int irq; -}; - -struct jz4780_pic_softc { - device_t pic_dev; - void * pic_intrhand; - struct resource * pic_res[2]; - struct jz4780_pic_isrc pic_irqs[JZ4780_NIRQS]; - uint32_t nirqs; -}; - -#define PIC_INTR_ISRC(sc, irq) (&(sc)->pic_irqs[(irq)].isrc) - -static struct resource_spec jz4780_pic_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE }, /* Registers */ - { SYS_RES_IRQ, 0, RF_ACTIVE }, /* Parent interrupt */ - { -1, 0 } -}; - -static struct ofw_compat_data compat_data[] = { - {"ingenic,jz4780-intc", true}, - {NULL, false} -}; - -#define READ4(_sc, _reg) bus_read_4((_sc)->pic_res[0], _reg) -#define WRITE4(_sc, _reg, _val) bus_write_4((_sc)->pic_res[0], _reg, _val) - -static int -jz4780_pic_probe(device_t dev) -{ - - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) - return (ENXIO); - device_set_desc(dev, "JZ4780 Interrupt Controller"); - return (BUS_PROBE_DEFAULT); -} - -static inline void -pic_irq_unmask(struct jz4780_pic_softc *sc, u_int irq) -{ - if (irq < 32) - WRITE4(sc, JZ_ICMCR0, (1u << irq)); - else - WRITE4(sc, JZ_ICMCR1, (1u << (irq - 32))); -} - -static inline void -pic_irq_mask(struct jz4780_pic_softc *sc, u_int irq) -{ - if (irq < 32) - WRITE4(sc, JZ_ICMSR0, (1u << irq)); - else - WRITE4(sc, JZ_ICMSR1, (1u << (irq - 32))); -} - -static inline intptr_t -pic_xref(device_t dev) -{ - return (OF_xref_from_node(ofw_bus_get_node(dev))); -} - -static int -jz4780_pic_register_isrcs(struct jz4780_pic_softc *sc) -{ - int error; - uint32_t irq, i; - struct intr_irqsrc *isrc; - const char *name; - - name = device_get_nameunit(sc->pic_dev); - for (irq = 0; irq < sc->nirqs; irq++) { - sc->pic_irqs[irq].irq = irq; - isrc = PIC_INTR_ISRC(sc, irq); - error = intr_isrc_register(isrc, sc->pic_dev, 0, "%s,%d", - name, irq); - if (error != 0) { - for (i = 0; i < irq; i++) - intr_isrc_deregister(PIC_INTR_ISRC(sc, irq)); - device_printf(sc->pic_dev, "%s failed", __func__); - return (error); - } - } - - return (0); -} - -static int -jz4780_pic_attach(device_t dev) -{ - struct jz4780_pic_softc *sc; - intptr_t xref; - - xref = pic_xref(dev); - - sc = device_get_softc(dev); - - if (bus_alloc_resources(dev, jz4780_pic_spec, sc->pic_res)) { - device_printf(dev, "could not allocate resources\n"); - return (ENXIO); - } - - sc->pic_dev = dev; - - /* Set the number of interrupts */ - sc->nirqs = nitems(sc->pic_irqs); - - /* Mask all interrupts */ - WRITE4(sc, JZ_ICMR0, 0xFFFFFFFF); - WRITE4(sc, JZ_ICMR1, 0xFFFFFFFF); - - /* Register the interrupts */ - if (jz4780_pic_register_isrcs(sc) != 0) { - device_printf(dev, "could not register PIC ISRCs\n"); - goto cleanup; - } - - /* - * Now, when everything is initialized, it's right time to - * register interrupt controller to interrupt framefork. - */ - if (intr_pic_register(dev, xref) == NULL) { - device_printf(dev, "could not register PIC\n"); - goto cleanup; - } - - if (bus_setup_intr(dev, sc->pic_res[1], INTR_TYPE_CLK, - jz4780_pic_intr, NULL, sc, &sc->pic_intrhand)) { - device_printf(dev, "could not setup irq handler\n"); - intr_pic_deregister(dev, xref); - goto cleanup; - } - - return (0); - -cleanup: - bus_release_resources(dev, jz4780_pic_spec, sc->pic_res); - - return(ENXIO); -} - -static int -jz4780_pic_intr(void *arg) -{ - struct jz4780_pic_softc *sc = arg; - struct intr_irqsrc *isrc; - struct thread *td; - uint32_t i, intr; - - td = curthread; - /* Workaround: do not inflate intr nesting level */ - td->td_intr_nesting_level--; - - intr = READ4(sc, JZ_ICPR0); - while ((i = fls(intr)) != 0) { - i--; - intr &= ~(1u << i); - - isrc = PIC_INTR_ISRC(sc, i); - if (intr_isrc_dispatch(isrc, curthread->td_intr_frame) != 0) { - device_printf(sc->pic_dev, "Stray interrupt %u detected\n", i); - pic_irq_mask(sc, i); - continue; - } - } - - KASSERT(i == 0, ("all interrupts handled")); - - intr = READ4(sc, JZ_ICPR1); - while ((i = fls(intr)) != 0) { - i--; - intr &= ~(1u << i); - i += 32; - - isrc = PIC_INTR_ISRC(sc, i); - if (intr_isrc_dispatch(isrc, curthread->td_intr_frame) != 0) { - device_printf(sc->pic_dev, "Stray interrupt %u detected\n", i); - pic_irq_mask(sc, i); - continue; - } - } - - KASSERT(i == 0, ("all interrupts handled")); - td->td_intr_nesting_level++; - - return (FILTER_HANDLED); -} - -static int -jz4780_pic_map_intr(device_t dev, struct intr_map_data *data, - struct intr_irqsrc **isrcp) -{ -#ifdef FDT - struct jz4780_pic_softc *sc; - struct intr_map_data_fdt *daf; - - sc = device_get_softc(dev); - daf = (struct intr_map_data_fdt *)data; - - if (data == NULL || data->type != INTR_MAP_DATA_FDT || - daf->ncells != 1 || daf->cells[0] >= sc->nirqs) - return (EINVAL); - - *isrcp = PIC_INTR_ISRC(sc, daf->cells[0]); - return (0); -#else - return (EINVAL); -#endif -} - -static void -jz4780_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc) -{ - struct jz4780_pic_isrc *pic_isrc; - - pic_isrc = (struct jz4780_pic_isrc *)isrc; - pic_irq_unmask(device_get_softc(dev), pic_isrc->irq); -} - -static void -jz4780_pic_disable_intr(device_t dev, struct intr_irqsrc *isrc) -{ - struct jz4780_pic_isrc *pic_isrc; - - pic_isrc = (struct jz4780_pic_isrc *)isrc; - pic_irq_mask(device_get_softc(dev), pic_isrc->irq); -} - -static void -jz4780_pic_pre_ithread(device_t dev, struct intr_irqsrc *isrc) -{ - - jz4780_pic_disable_intr(dev, isrc); -} - -static void -jz4780_pic_post_ithread(device_t dev, struct intr_irqsrc *isrc) -{ - - jz4780_pic_enable_intr(dev, isrc); -} - -static device_method_t jz4780_pic_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, jz4780_pic_probe), - DEVMETHOD(device_attach, jz4780_pic_attach), - /* Interrupt controller interface */ - DEVMETHOD(pic_enable_intr, jz4780_pic_enable_intr), - DEVMETHOD(pic_disable_intr, jz4780_pic_disable_intr), - DEVMETHOD(pic_map_intr, jz4780_pic_map_intr), - DEVMETHOD(pic_post_ithread, jz4780_pic_post_ithread), - DEVMETHOD(pic_pre_ithread, jz4780_pic_pre_ithread), - { 0, 0 } -}; - -static driver_t jz4780_pic_driver = { - "intc", - jz4780_pic_methods, - sizeof(struct jz4780_pic_softc), -}; - -static devclass_t jz4780_pic_devclass; - -EARLY_DRIVER_MODULE(intc, ofwbus, jz4780_pic_driver, jz4780_pic_devclass, 0, 0, - BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE); Index: sys/mips/ingenic/jz4780_lcd.h =================================================================== --- sys/mips/ingenic/jz4780_lcd.h +++ /dev/null @@ -1,204 +0,0 @@ -/*- - * Copyright (c) 2016 Jared McNeill - * 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. - * - * $FreeBSD$ - */ - -/* - * Ingenic JZ4780 LCD Controller - */ - -#ifndef __JZ4780_LCD_H__ -#define __JZ4780_LCD_H__ - -#define LCDCFG 0x0000 -#define LCDCFG_LCDPIN (1 << 31) -#define LCDCFG_TVEPEH (1 << 30) -#define LCDCFG_NEWDES (1 << 28) -#define LCDCFG_PALBP (1 << 27) -#define LCDCFG_TVEN (1 << 26) -#define LCDCFG_RECOVER (1 << 25) -#define LCDCFG_PSM (1 << 23) -#define LCDCFG_CLSM (1 << 22) -#define LCDCFG_SPLM (1 << 21) -#define LCDCFG_REVM (1 << 20) -#define LCDCFG_HSYNM (1 << 19) -#define LCDCFG_VSYNM (1 << 18) -#define LCDCFG_INVDAT (1 << 17) -#define LCDCFG_SYNDIR (1 << 16) -#define LCDCFG_PSP (1 << 15) -#define LCDCFG_CLSP (1 << 14) -#define LCDCFG_SPLP (1 << 13) -#define LCDCFG_REVP (1 << 12) -#define LCDCFG_HSP (1 << 11) -#define LCDCFG_PCP (1 << 10) -#define LCDCFG_DEP (1 << 9) -#define LCDCFG_VSP (1 << 8) -#define LCDCFG_18_16 (1 << 7) -#define LCDCFG_24 (1 << 6) -#define LCDCFG_MODE (0xf << 0) -#define LCDCTRL 0x0030 -#define LCDCTRL_PINMD (1 << 31) -#define LCDCTRL_BST (0x7 << 28) -#define LCDCTRL_BST_4 (0 << 28) -#define LCDCTRL_BST_8 (1 << 28) -#define LCDCTRL_BST_16 (2 << 28) -#define LCDCTRL_BST_32 (3 << 28) -#define LCDCTRL_BST_64 (4 << 28) -#define LCDCTRL_OUTRGB (1 << 27) -#define LCDCTRL_OFUP (1 << 26) -#define LCDCTRL_DACTE (1 << 14) -#define LCDCTRL_EOFM (1 << 13) -#define LCDCTRL_SOFM (1 << 12) -#define LCDCTRL_OFUM (1 << 11) -#define LCDCTRL_IFUM0 (1 << 10) -#define LCDCTRL_IFUM1 (1 << 9) -#define LCDCTRL_LDDM (1 << 8) -#define LCDCTRL_QDM (1 << 7) -#define LCDCTRL_BEDN (1 << 6) -#define LCDCTRL_PEDN (1 << 5) -#define LCDCTRL_DIS (1 << 4) -#define LCDCTRL_ENA (1 << 3) -#define LCDCTRL_BPP0 (0x7 << 0) -#define LCDCTRL_BPP0_1 (0 << 0) -#define LCDCTRL_BPP0_2 (1 << 0) -#define LCDCTRL_BPP0_4 (2 << 0) -#define LCDCTRL_BPP0_8 (3 << 0) -#define LCDCTRL_BPP0_15_16 (4 << 0) -#define LCDCTRL_BPP0_18_24 (5 << 0) -#define LCDCTRL_BPP0_24_COMP (6 << 0) -#define LCDCTRL_BPP0_30 (7 << 0) -#define LCDCTR -#define LCDSTATE 0x0034 -#define LCDSTATE_QD (1 << 7) -#define LCDSTATE_EOF (1 << 5) -#define LCDSTATE_SOF (1 << 4) -#define LCDSTATE_OUT (1 << 3) -#define LCDSTATE_IFU0 (1 << 2) -#define LCDSTATE_IFU1 (1 << 1) -#define LCDSTATE_LDD (1 << 0) -#define LCDOSDC 0x0100 -#define LCDOSDCTRL 0x0104 -#define LCDOSDS 0x0108 -#define LCDBGC0 0x010c -#define LCDBGC1 0x02c4 -#define LCDKEY0 0x0110 -#define LCDKEY1 0x0114 -#define LCDALPHA 0x0118 -#define LCDIPUR 0x011c -#define LCDRGBC 0x0090 -#define LCDRGBC_RGBDM (1 << 15) -#define LCDRGBC_DMM (1 << 14) -#define LCDRGBC_422 (1 << 8) -#define LCDRGBC_RGBFMT (1 << 7) -#define LCDRGBC_ODDRGB (0x7 << 4) -#define LCDRGBC_EVENRGB (0x7 << 0) -#define LCDVAT 0x000c -#define LCDVAT_HT_SHIFT 16 -#define LCDVAT_VT_SHIFT 0 -#define LCDDAH 0x0010 -#define LCDDAH_HDS_SHIFT 16 -#define LCDDAH_HDE_SHIFT 0 -#define LCDDAV 0x0014 -#define LCDDAV_VDS_SHIFT 16 -#define LCDDAV_VDE_SHIFT 0 -#define LCDXYP0 0x0120 -#define LCDXYP1 0x0124 -#define LCDSIZE0 0x0128 -#define LCDSIZE1 0x012c -#define LCDVSYNC 0x0004 -#define LCDHSYNC 0x0008 -#define LCDPS 0x0018 -#define LCDCLS 0x001c -#define LCDSPL 0x0020 -#define LCDREV 0x0024 -#define LCDIID 0x0038 -#define LCDDA0 0x0040 -#define LCDSA0 0x0044 -#define LCDFID0 0x0048 -#define LCDCMD0 0x004c -#define LCDCMD_SOFINT (1 << 31) -#define LCDCMD_EOFINT (1 << 30) -#define LCDCMD_CMD (1 << 29) -#define LCDCMD_COMPE (1 << 27) -#define LCDCMD_FRM_EN (1 << 26) -#define LCDCMD_FIELD_SEL (1 << 25) -#define LCDCMD_16X16BLOCK (1 << 24) -#define LCDCMD_LEN (0xffffff << 0) -#define LCDOFFS0 0x0060 -#define LCDPW0 0x0064 -#define LCDCNUM0 0x0068 -#define LCDPOS0 LCDCNUM0 -#define LCDPOS_ALPHAMD1 (1 << 31) -#define LCDPOS_RGB01 (1 << 30) -#define LCDPOS_BPP01 (0x7 << 27) -#define LCDPOS_BPP01_15_16 (4 << 27) -#define LCDPOS_BPP01_18_24 (5 << 27) -#define LCDPOS_BPP01_24_COMP (6 << 27) -#define LCDPOS_BPP01_30 (7 << 27) -#define LCDPOS_PREMULTI01 (1 << 26) -#define LCDPOS_COEF_SLE01 (0x3 << 24) -#define LCDPOS_COEF_BLE01_1 (1 << 24) -#define LCDPOS_YPOS01 (0xfff << 12) -#define LCDPOS_XPOS01 (0xfff << 0) -#define LCDDESSIZE0 0x006c -#define LCDDESSIZE_ALPHA (0xff << 24) -#define LCDDESSIZE_HEIGHT (0xfff << 12) -#define LCDDESSIZE_HEIGHT_SHIFT 12 -#define LCDDESSIZE_WIDTH (0xfff << 0) -#define LCDDESSIZE_WIDTH_SHIFT 0 -#define LCDDA1 0x0050 -#define LCDSA1 0x0054 -#define LCDFID1 0x0058 -#define LCDCMD1 0x005c -#define LCDOFFS1 0x0070 -#define LCDPW1 0x0074 -#define LCDCNUM1 0x0078 -#define LCDPOS1 LCDCNUM1 -#define LCDDESSIZE1 0x007c -#define LCDPCFG 0x02c0 -#define LCDDUALCTRL 0x02c8 -#define LCDENH_CFG 0x0400 -#define LCDENH_CSCCFG 0x0404 -#define LCDENH_LUMACFG 0x0408 -#define LCDENH_CHROCFG0 0x040c -#define LCDENH_CHROCFG1 0x0410 -#define LCDENH_DITHERCFG 0x0414 -#define LCDENH_STATUS 0x0418 -#define LCDENH_GAMMA 0x0800 /* base */ -#define LCDENH_VEE 0x1000 /* base */ - -struct lcd_frame_descriptor { - uint32_t next; - uint32_t physaddr; - uint32_t id; - uint32_t cmd; - uint32_t offs; - uint32_t pw; - uint32_t cnum_pos; - uint32_t dessize; -} __packed; - -#endif /* !__JZ4780_LCD_H__ */ Index: sys/mips/ingenic/jz4780_lcd.c =================================================================== --- sys/mips/ingenic/jz4780_lcd.c +++ /dev/null @@ -1,575 +0,0 @@ -/*- - * Copyright (c) 2016 Jared McNeill - * 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. - * - * $FreeBSD$ - */ - -/* - * Ingenic JZ4780 LCD Controller - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include - -#include - -#include - -#include "fb_if.h" -#include "hdmi_if.h" - -#define FB_DEFAULT_W 800 -#define FB_DEFAULT_H 600 -#define FB_DEFAULT_REF 60 -#define FB_BPP 32 -#define FB_ALIGN (16 * 4) -#define FB_MAX_BW (1920 * 1080 * 60) -#define FB_MAX_W 2048 -#define FB_MAX_H 2048 -#define FB_DIVIDE(x, y) (((x) + ((y) / 2)) / (y)) - -#define PCFG_MAGIC 0xc7ff2100 - -#define DOT_CLOCK_TO_HZ(c) ((c) * 1000) - -#ifndef VM_MEMATTR_WRITE_COMBINING -#define VM_MEMATTR_WRITE_COMBINING VM_MEMATTR_UNCACHEABLE -#endif - -struct jzlcd_softc { - device_t dev; - device_t fbdev; - struct resource *res[1]; - - /* Clocks */ - clk_t clk; - clk_t clk_pix; - - /* Framebuffer */ - struct fb_info info; - size_t fbsize; - bus_addr_t paddr; - vm_offset_t vaddr; - - /* HDMI */ - eventhandler_tag hdmi_evh; - - /* Frame descriptor DMA */ - bus_dma_tag_t fdesc_tag; - bus_dmamap_t fdesc_map; - bus_addr_t fdesc_paddr; - struct lcd_frame_descriptor *fdesc; -}; - -static struct resource_spec jzlcd_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE }, - { -1, 0 } -}; - -#define LCD_READ(sc, reg) bus_read_4((sc)->res[0], (reg)) -#define LCD_WRITE(sc, reg, val) bus_write_4((sc)->res[0], (reg), (val)) - -static int -jzlcd_allocfb(struct jzlcd_softc *sc) -{ - sc->vaddr = kmem_alloc_contig(sc->fbsize, M_NOWAIT | M_ZERO, 0, ~0, - FB_ALIGN, 0, VM_MEMATTR_WRITE_COMBINING); - if (sc->vaddr == 0) { - device_printf(sc->dev, "failed to allocate FB memory\n"); - return (ENOMEM); - } - sc->paddr = pmap_kextract(sc->vaddr); - - return (0); -} - -static void -jzlcd_freefb(struct jzlcd_softc *sc) -{ - kmem_free(sc->vaddr, sc->fbsize); -} - -static void -jzlcd_start(struct jzlcd_softc *sc) -{ - uint32_t ctrl; - - /* Clear status registers */ - LCD_WRITE(sc, LCDSTATE, 0); - LCD_WRITE(sc, LCDOSDS, 0); - /* Enable the controller */ - ctrl = LCD_READ(sc, LCDCTRL); - ctrl |= LCDCTRL_ENA; - ctrl &= ~LCDCTRL_DIS; - LCD_WRITE(sc, LCDCTRL, ctrl); -} - -static void -jzlcd_stop(struct jzlcd_softc *sc) -{ - uint32_t ctrl; - - ctrl = LCD_READ(sc, LCDCTRL); - if ((ctrl & LCDCTRL_ENA) != 0) { - /* Disable the controller and wait for it to stop */ - ctrl |= LCDCTRL_DIS; - LCD_WRITE(sc, LCDCTRL, ctrl); - while ((LCD_READ(sc, LCDSTATE) & LCDSTATE_LDD) == 0) - DELAY(100); - } - /* Clear all status except for disable */ - LCD_WRITE(sc, LCDSTATE, LCD_READ(sc, LCDSTATE) & ~LCDSTATE_LDD); -} - -static void -jzlcd_setup_descriptor(struct jzlcd_softc *sc, const struct videomode *mode, - u_int desno) -{ - struct lcd_frame_descriptor *fdesc; - int line_sz; - - /* Frame size is specified in # words */ - line_sz = (mode->hdisplay * FB_BPP) >> 3; - line_sz = ((line_sz + 3) & ~3) / 4; - - fdesc = sc->fdesc + desno; - - if (desno == 0) - fdesc->next = sc->fdesc_paddr + - sizeof(struct lcd_frame_descriptor); - else - fdesc->next = sc->fdesc_paddr; - fdesc->physaddr = sc->paddr; - fdesc->id = desno; - fdesc->cmd = LCDCMD_FRM_EN | (line_sz * mode->vdisplay); - fdesc->offs = 0; - fdesc->pw = 0; - fdesc->cnum_pos = LCDPOS_BPP01_18_24 | - LCDPOS_PREMULTI01 | - (desno == 0 ? LCDPOS_COEF_BLE01_1 : LCDPOS_COEF_SLE01); - fdesc->dessize = LCDDESSIZE_ALPHA | - ((mode->vdisplay - 1) << LCDDESSIZE_HEIGHT_SHIFT) | - ((mode->hdisplay - 1) << LCDDESSIZE_WIDTH_SHIFT); -} - -static int -jzlcd_set_videomode(struct jzlcd_softc *sc, const struct videomode *mode) -{ - u_int hbp, hfp, hsw, vbp, vfp, vsw; - u_int hds, hde, ht, vds, vde, vt; - uint32_t ctrl; - int error; - - hbp = mode->htotal - mode->hsync_end; - hfp = mode->hsync_start - mode->hdisplay; - hsw = mode->hsync_end - mode->hsync_start; - vbp = mode->vtotal - mode->vsync_end; - vfp = mode->vsync_start - mode->vdisplay; - vsw = mode->vsync_end - mode->vsync_start; - - hds = hsw + hbp; - hde = hds + mode->hdisplay; - ht = hde + hfp; - - vds = vsw + vbp; - vde = vds + mode->vdisplay; - vt = vde + vfp; - - /* Setup timings */ - LCD_WRITE(sc, LCDVAT, - (ht << LCDVAT_HT_SHIFT) | (vt << LCDVAT_VT_SHIFT)); - LCD_WRITE(sc, LCDDAH, - (hds << LCDDAH_HDS_SHIFT) | (hde << LCDDAH_HDE_SHIFT)); - LCD_WRITE(sc, LCDDAV, - (vds << LCDDAV_VDS_SHIFT) | (vde << LCDDAV_VDE_SHIFT)); - LCD_WRITE(sc, LCDHSYNC, hsw); - LCD_WRITE(sc, LCDVSYNC, vsw); - - /* Set configuration */ - LCD_WRITE(sc, LCDCFG, LCDCFG_NEWDES | LCDCFG_RECOVER | LCDCFG_24 | - LCDCFG_PSM | LCDCFG_CLSM | LCDCFG_SPLM | LCDCFG_REVM | LCDCFG_PCP); - ctrl = LCD_READ(sc, LCDCTRL); - ctrl &= ~LCDCTRL_BST; - ctrl |= LCDCTRL_BST_64 | LCDCTRL_OFUM; - LCD_WRITE(sc, LCDCTRL, ctrl); - LCD_WRITE(sc, LCDPCFG, PCFG_MAGIC); - LCD_WRITE(sc, LCDRGBC, LCDRGBC_RGBFMT); - - /* Update registers */ - LCD_WRITE(sc, LCDSTATE, 0); - - /* Setup frame descriptors */ - jzlcd_setup_descriptor(sc, mode, 0); - jzlcd_setup_descriptor(sc, mode, 1); - bus_dmamap_sync(sc->fdesc_tag, sc->fdesc_map, BUS_DMASYNC_PREWRITE); - - /* Setup DMA channels */ - LCD_WRITE(sc, LCDDA0, sc->fdesc_paddr - + sizeof(struct lcd_frame_descriptor)); - LCD_WRITE(sc, LCDDA1, sc->fdesc_paddr); - - /* Set display clock */ - error = clk_set_freq(sc->clk_pix, DOT_CLOCK_TO_HZ(mode->dot_clock), 0); - if (error != 0) { - device_printf(sc->dev, "failed to set pixel clock to %u Hz\n", - DOT_CLOCK_TO_HZ(mode->dot_clock)); - return (error); - } - - return (0); -} - -static int -jzlcd_configure(struct jzlcd_softc *sc, const struct videomode *mode) -{ - size_t fbsize; - int error; - - fbsize = round_page(mode->hdisplay * mode->vdisplay * (FB_BPP / NBBY)); - - /* Detach the old FB device */ - if (sc->fbdev != NULL) { - device_delete_child(sc->dev, sc->fbdev); - sc->fbdev = NULL; - } - - /* If the FB size has changed, free the old FB memory */ - if (sc->fbsize > 0 && sc->fbsize != fbsize) { - jzlcd_freefb(sc); - sc->vaddr = 0; - } - - /* Allocate the FB if necessary */ - sc->fbsize = fbsize; - if (sc->vaddr == 0) { - error = jzlcd_allocfb(sc); - if (error != 0) { - device_printf(sc->dev, "failed to allocate FB memory\n"); - return (ENXIO); - } - } - - /* Setup video mode */ - error = jzlcd_set_videomode(sc, mode); - if (error != 0) - return (error); - - /* Attach framebuffer device */ - sc->info.fb_name = device_get_nameunit(sc->dev); - sc->info.fb_vbase = (intptr_t)sc->vaddr; - sc->info.fb_pbase = sc->paddr; - sc->info.fb_size = sc->fbsize; - sc->info.fb_bpp = sc->info.fb_depth = FB_BPP; - sc->info.fb_stride = mode->hdisplay * (FB_BPP / NBBY); - sc->info.fb_width = mode->hdisplay; - sc->info.fb_height = mode->vdisplay; -#ifdef VM_MEMATTR_WRITE_COMBINING - sc->info.fb_flags = FB_FLAG_MEMATTR; - sc->info.fb_memattr = VM_MEMATTR_WRITE_COMBINING; -#endif - sc->fbdev = device_add_child(sc->dev, "fbd", device_get_unit(sc->dev)); - if (sc->fbdev == NULL) { - device_printf(sc->dev, "failed to add fbd child\n"); - return (ENOENT); - } - - error = device_probe_and_attach(sc->fbdev); - if (error != 0) { - device_printf(sc->dev, "failed to attach fbd device\n"); - return (error); - } - - return (0); -} - -static int -jzlcd_get_bandwidth(const struct videomode *mode) -{ - int refresh; - - refresh = FB_DIVIDE(FB_DIVIDE(DOT_CLOCK_TO_HZ(mode->dot_clock), - mode->htotal), mode->vtotal); - - return mode->hdisplay * mode->vdisplay * refresh; -} - -static int -jzlcd_mode_supported(const struct videomode *mode) -{ - /* Width and height must be less than 2048 */ - if (mode->hdisplay > FB_MAX_W || mode->vdisplay > FB_MAX_H) - return (0); - - /* Bandwidth check */ - if (jzlcd_get_bandwidth(mode) > FB_MAX_BW) - return (0); - - /* Interlace modes not yet supported by the driver */ - if ((mode->flags & VID_INTERLACE) != 0) - return (0); - - return (1); -} - -static const struct videomode * -jzlcd_find_mode(struct edid_info *ei) -{ - const struct videomode *best; - int n, bw, best_bw; - - /* If the preferred mode is OK, just use it */ - if (jzlcd_mode_supported(ei->edid_preferred_mode) != 0) - return ei->edid_preferred_mode; - - /* Pick the mode with the highest bandwidth requirements */ - best = NULL; - best_bw = 0; - for (n = 0; n < ei->edid_nmodes; n++) { - if (jzlcd_mode_supported(&ei->edid_modes[n]) == 0) - continue; - bw = jzlcd_get_bandwidth(&ei->edid_modes[n]); - if (bw > FB_MAX_BW) - continue; - if (best == NULL || bw > best_bw) { - best = &ei->edid_modes[n]; - best_bw = bw; - } - } - - return best; -} - -static void -jzlcd_hdmi_event(void *arg, device_t hdmi_dev) -{ - const struct videomode *mode; - struct videomode hdmi_mode; - struct jzlcd_softc *sc; - struct edid_info ei; - uint8_t *edid; - uint32_t edid_len; - int error; - - sc = arg; - edid = NULL; - edid_len = 0; - mode = NULL; - - error = HDMI_GET_EDID(hdmi_dev, &edid, &edid_len); - if (error != 0) { - device_printf(sc->dev, "failed to get EDID: %d\n", error); - } else { - error = edid_parse(edid, &ei); - if (error != 0) { - device_printf(sc->dev, "failed to parse EDID: %d\n", - error); - } else { - if (bootverbose) - edid_print(&ei); - - mode = jzlcd_find_mode(&ei); - } - } - - /* If a suitable mode could not be found, try the default */ - if (mode == NULL) - mode = pick_mode_by_ref(FB_DEFAULT_W, FB_DEFAULT_H, - FB_DEFAULT_REF); - - if (mode == NULL) { - device_printf(sc->dev, "failed to find usable video mode\n"); - return; - } - - if (bootverbose) - device_printf(sc->dev, "using %dx%d\n", - mode->hdisplay, mode->vdisplay); - - /* Stop the controller */ - jzlcd_stop(sc); - - /* Configure LCD controller */ - error = jzlcd_configure(sc, mode); - if (error != 0) { - device_printf(sc->dev, "failed to configure FB: %d\n", error); - return; - } - - /* Enable HDMI TX */ - hdmi_mode = *mode; - HDMI_SET_VIDEOMODE(hdmi_dev, &hdmi_mode); - - /* Start the controller! */ - jzlcd_start(sc); -} - -static void -jzlcd_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) -{ - if (error != 0) - return; - *(bus_addr_t *)arg = segs[0].ds_addr; -} - -static int -jzlcd_probe(device_t dev) -{ - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (!ofw_bus_is_compatible(dev, "ingenic,jz4780-lcd")) - return (ENXIO); - - device_set_desc(dev, "Ingenic JZ4780 LCD Controller"); - return (BUS_PROBE_DEFAULT); -} - -static int -jzlcd_attach(device_t dev) -{ - struct jzlcd_softc *sc; - int error; - - sc = device_get_softc(dev); - - sc->dev = dev; - - if (bus_alloc_resources(dev, jzlcd_spec, sc->res)) { - device_printf(dev, "cannot allocate resources for device\n"); - goto failed; - } - - if (clk_get_by_ofw_name(dev, 0, "lcd_clk", &sc->clk) != 0 || - clk_get_by_ofw_name(dev, 0, "lcd_pixclk", &sc->clk_pix) != 0) { - device_printf(dev, "cannot get clocks\n"); - goto failed; - } - if (clk_enable(sc->clk) != 0 || clk_enable(sc->clk_pix) != 0) { - device_printf(dev, "cannot enable clocks\n"); - goto failed; - } - - error = bus_dma_tag_create( - bus_get_dma_tag(dev), - sizeof(struct lcd_frame_descriptor), 0, - BUS_SPACE_MAXADDR_32BIT, - BUS_SPACE_MAXADDR, - NULL, NULL, - sizeof(struct lcd_frame_descriptor) * 2, 1, - sizeof(struct lcd_frame_descriptor) * 2, - 0, - NULL, NULL, - &sc->fdesc_tag); - if (error != 0) { - device_printf(dev, "cannot create bus dma tag\n"); - goto failed; - } - - error = bus_dmamem_alloc(sc->fdesc_tag, (void **)&sc->fdesc, - BUS_DMA_NOCACHE | BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->fdesc_map); - if (error != 0) { - device_printf(dev, "cannot allocate dma descriptor\n"); - goto dmaalloc_failed; - } - - error = bus_dmamap_load(sc->fdesc_tag, sc->fdesc_map, sc->fdesc, - sizeof(struct lcd_frame_descriptor) * 2, jzlcd_dmamap_cb, - &sc->fdesc_paddr, 0); - if (error != 0) { - device_printf(dev, "cannot load dma map\n"); - goto dmaload_failed; - } - - sc->hdmi_evh = EVENTHANDLER_REGISTER(hdmi_event, - jzlcd_hdmi_event, sc, 0); - - return (0); - -dmaload_failed: - bus_dmamem_free(sc->fdesc_tag, sc->fdesc, sc->fdesc_map); -dmaalloc_failed: - bus_dma_tag_destroy(sc->fdesc_tag); -failed: - if (sc->clk_pix != NULL) - clk_release(sc->clk); - if (sc->clk != NULL) - clk_release(sc->clk); - if (sc->res != NULL) - bus_release_resources(dev, jzlcd_spec, sc->res); - - return (ENXIO); -} - -static struct fb_info * -jzlcd_fb_getinfo(device_t dev) -{ - struct jzlcd_softc *sc; - - sc = device_get_softc(dev); - - return (&sc->info); -} - -static device_method_t jzlcd_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, jzlcd_probe), - DEVMETHOD(device_attach, jzlcd_attach), - - /* FB interface */ - DEVMETHOD(fb_getinfo, jzlcd_fb_getinfo), - - DEVMETHOD_END -}; - -static driver_t jzlcd_driver = { - "fb", - jzlcd_methods, - sizeof(struct jzlcd_softc), -}; - -static devclass_t jzlcd_devclass; - -DRIVER_MODULE(fb, simplebus, jzlcd_driver, jzlcd_devclass, 0, 0); Index: sys/mips/ingenic/jz4780_machdep.c =================================================================== --- sys/mips/ingenic/jz4780_machdep.c +++ /dev/null @@ -1,253 +0,0 @@ -/*- - * Copyright (c) 2009 Oleksandr Tymoshenko - * Copyright (c) 2015 Alexander Kabaev - * 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 "opt_ddb.h" -#include "opt_platform.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef FDT -#include -#include -#endif - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -uint32_t * const led = (uint32_t *)0xb0010548; - -extern char edata[], end[]; -static char boot1_env[4096]; - -void -platform_cpu_init(void) -{ - uint32_t reg; - - /* - * Do not expect mbox interrups while writing - * mbox - */ - reg = mips_rd_xburst_reim(); - reg &= ~JZ_REIM_MIRQ0M; - mips_wr_xburst_reim(reg); - - /* Clean mailboxes */ - mips_wr_xburst_mbox0(0); - mips_wr_xburst_mbox1(0); - mips_wr_xburst_core_sts(~JZ_CORESTS_MIRQ0P); - - /* Unmask mbox interrupts */ - reg |= JZ_REIM_MIRQ0M; - mips_wr_xburst_reim(reg); -} - -void -platform_reset(void) -{ - /* - * For now, provoke a watchdog reset in about a second, so UART buffers - * have a fighting chance to flush before we pull the plug - */ - writereg(JZ_TCU_BASE + JZ_WDOG_TCER, 0); /* disable watchdog */ - writereg(JZ_TCU_BASE + JZ_WDOG_TCNT, 0); /* reset counter */ - writereg(JZ_TCU_BASE + JZ_WDOG_TDR, 128); /* wait for ~1s */ - writereg(JZ_TCU_BASE + JZ_WDOG_TCSR, TCSR_RTC_EN | TCSR_DIV_256); - writereg(JZ_TCU_BASE + JZ_WDOG_TCER, TCER_ENABLE); /* fire! */ - - /* Wait for reset */ - while (1) - ; -} - -static void -mips_init(void) -{ - int i; -#ifdef FDT - struct mem_region mr[FDT_MEM_REGIONS]; - uint64_t val; - int mr_cnt; - int j; -#endif - - for (i = 0; i < 10; i++) { - phys_avail[i] = 0; - } - - /* The minimal amount of memory Ingenic SoC can have. */ - dump_avail[0] = phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end); - physmem = realmem = btoc(32 * 1024 * 1024); - - /* - * X1000 mips cpu special. - * TODO: do anyone know what is this ? - */ - __asm( - "li $2, 0xa9000000 \n\t" - "mtc0 $2, $5, 4 \n\t" - "nop \n\t" - ::"r"(2)); - -#ifdef FDT - if (fdt_get_mem_regions(mr, &mr_cnt, &val) == 0) { - - physmem = realmem = btoc(val); - - KASSERT((phys_avail[0] >= mr[0].mr_start) && \ - (phys_avail[0] < (mr[0].mr_start + mr[0].mr_size)), - ("First region is not within FDT memory range")); - - /* Limit size of the first region */ - phys_avail[1] = (mr[0].mr_start + MIN(mr[0].mr_size, ctob(realmem))); - dump_avail[1] = phys_avail[1]; - - /* Add the rest of regions */ - for (i = 1, j = 2; i < mr_cnt; i++, j+=2) { - phys_avail[j] = mr[i].mr_start; - phys_avail[j+1] = (mr[i].mr_start + mr[i].mr_size); - dump_avail[j] = phys_avail[j]; - dump_avail[j+1] = phys_avail[j+1]; - } - } -#endif - - init_param1(); - init_param2(physmem); - mips_cpu_init(); - pmap_bootstrap(); - mips_proc0_init(); - mutex_init(); - kdb_init(); - led[0] = 0x8000; -#ifdef KDB - if (boothowto & RB_KDB) - kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); -#endif -} - -#ifdef FDT -static void -_parse_bootargs(char *cmdline) -{ - char *v; - - while ((v = strsep(&cmdline, " \n")) != NULL) { - if (*v == '\0') - continue; - boothowto |= boot_parse_arg(v); - } -} -#endif - -void -platform_start(__register_t a0, __register_t a1, - __register_t a2 __unused, __register_t a3 __unused) -{ - char **argv; - int argc; - vm_offset_t kernend; -#ifdef FDT - vm_offset_t dtbp; - phandle_t chosen; - char buf[2048]; /* early stack supposedly big enough */ -#endif - /* - * clear the BSS and SBSS segments, this should be first call in - * the function - */ - kernend = (vm_offset_t)&end; - memset(&edata, 0, kernend - (vm_offset_t)(&edata)); - - mips_postboot_fixup(); - - /* Initialize pcpu stuff */ - mips_pcpu0_init(); - - /* Something to hold kernel env until kmem is available */ - init_static_kenv(boot1_env, sizeof(boot1_env)); -#ifdef FDT - /* - * Find the dtb passed in by the boot loader (currently fictional). - */ - dtbp = (vm_offset_t)NULL; - -#if defined(FDT_DTB_STATIC) - /* - * In case the device tree blob was not retrieved (from metadata) try - * to use the statically embedded one. - */ - if (dtbp == (vm_offset_t)NULL) - dtbp = (vm_offset_t)&fdt_static_dtb; -#else -#error "Non-static FDT not supported on JZ4780" -#endif - if (OF_install(OFW_FDT, 0) == FALSE) - while (1); - if (OF_init((void *)dtbp) != 0) - while (1); -#endif - - cninit(); -#ifdef FDT - /* - * Get bootargs from FDT if specified. - */ - chosen = OF_finddevice("/chosen"); - if (OF_getprop(chosen, "bootargs", buf, sizeof(buf)) != -1) - boothowto |= boot_parse_cmdline(buf); -#endif - /* Parse cmdline from U-Boot */ - argc = a0; - argv = (char **)a1; - boothowto |= boot_parse_cmdline(argc, argv); - - mips_init(); -} Index: sys/mips/ingenic/jz4780_mmc.c =================================================================== --- sys/mips/ingenic/jz4780_mmc.c +++ /dev/null @@ -1,992 +0,0 @@ -/*- - * Copyright (c) 2015 Alexander Kabaev - * 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 - -#undef JZ_MMC_DEBUG - -#define JZ_MSC_MEMRES 0 -#define JZ_MSC_IRQRES 1 -#define JZ_MSC_RESSZ 2 -#define JZ_MSC_DMA_SEGS 128 -#define JZ_MSC_DMA_MAX_SIZE MAXPHYS - -#define JZ_MSC_INT_ERR_BITS (JZ_INT_CRC_RES_ERR | JZ_INT_CRC_READ_ERR | \ - JZ_INT_CRC_WRITE_ERR | JZ_INT_TIMEOUT_RES | \ - JZ_INT_TIMEOUT_READ) -static int jz4780_mmc_pio_mode = 0; - -TUNABLE_INT("hw.jz.mmc.pio_mode", &jz4780_mmc_pio_mode); - -struct jz4780_mmc_dma_desc { - uint32_t dma_next; - uint32_t dma_phys; - uint32_t dma_len; - uint32_t dma_cmd; -}; - -struct jz4780_mmc_softc { - bus_space_handle_t sc_bsh; - bus_space_tag_t sc_bst; - device_t sc_dev; - clk_t sc_clk; - int sc_bus_busy; - int sc_resid; - int sc_timeout; - struct callout sc_timeoutc; - struct mmc_host sc_host; - struct mmc_request * sc_req; - struct mtx sc_mtx; - struct resource * sc_res[JZ_MSC_RESSZ]; - uint32_t sc_intr_seen; - uint32_t sc_intr_mask; - uint32_t sc_intr_wait; - void * sc_intrhand; - uint32_t sc_cmdat; - - /* Fields required for DMA access. */ - bus_addr_t sc_dma_desc_phys; - bus_dmamap_t sc_dma_map; - bus_dma_tag_t sc_dma_tag; - void * sc_dma_desc; - bus_dmamap_t sc_dma_buf_map; - bus_dma_tag_t sc_dma_buf_tag; - int sc_dma_inuse; - int sc_dma_map_err; - uint32_t sc_dma_ctl; -}; - -static struct resource_spec jz4780_mmc_res_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE }, - { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, - { -1, 0, 0 } -}; - -static int jz4780_mmc_probe(device_t); -static int jz4780_mmc_attach(device_t); -static int jz4780_mmc_detach(device_t); -static int jz4780_mmc_setup_dma(struct jz4780_mmc_softc *); -static int jz4780_mmc_reset(struct jz4780_mmc_softc *); -static void jz4780_mmc_intr(void *); -static int jz4780_mmc_enable_clock(struct jz4780_mmc_softc *); -static int jz4780_mmc_config_clock(struct jz4780_mmc_softc *, uint32_t); - -static int jz4780_mmc_update_ios(device_t, device_t); -static int jz4780_mmc_request(device_t, device_t, struct mmc_request *); -static int jz4780_mmc_get_ro(device_t, device_t); -static int jz4780_mmc_acquire_host(device_t, device_t); -static int jz4780_mmc_release_host(device_t, device_t); - -#define JZ_MMC_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) -#define JZ_MMC_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) -#define JZ_MMC_READ_2(_sc, _reg) \ - bus_space_read_2((_sc)->sc_bst, (_sc)->sc_bsh, _reg) -#define JZ_MMC_WRITE_2(_sc, _reg, _value) \ - bus_space_write_2((_sc)->sc_bst, (_sc)->sc_bsh, _reg, _value) -#define JZ_MMC_READ_4(_sc, _reg) \ - bus_space_read_4((_sc)->sc_bst, (_sc)->sc_bsh, _reg) -#define JZ_MMC_WRITE_4(_sc, _reg, _value) \ - bus_space_write_4((_sc)->sc_bst, (_sc)->sc_bsh, _reg, _value) - -static int -jz4780_mmc_probe(device_t dev) -{ - - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - if (!ofw_bus_is_compatible(dev, "ingenic,jz4780-mmc")) - return (ENXIO); - if (device_get_unit(dev) > 0) /* XXXKAN */ - return (ENXIO); - device_set_desc(dev, "Ingenic JZ4780 Integrated MMC/SD controller"); - - return (BUS_PROBE_DEFAULT); -} - -static int -jz4780_mmc_attach(device_t dev) -{ - struct jz4780_mmc_softc *sc; - struct sysctl_ctx_list *ctx; - struct sysctl_oid_list *tree; - device_t child; - ssize_t len; - pcell_t prop; - phandle_t node; - - sc = device_get_softc(dev); - sc->sc_dev = dev; - sc->sc_req = NULL; - if (bus_alloc_resources(dev, jz4780_mmc_res_spec, sc->sc_res) != 0) { - device_printf(dev, "cannot allocate device resources\n"); - return (ENXIO); - } - sc->sc_bst = rman_get_bustag(sc->sc_res[JZ_MSC_MEMRES]); - sc->sc_bsh = rman_get_bushandle(sc->sc_res[JZ_MSC_MEMRES]); - if (bus_setup_intr(dev, sc->sc_res[JZ_MSC_IRQRES], - INTR_TYPE_MISC | INTR_MPSAFE, NULL, jz4780_mmc_intr, sc, - &sc->sc_intrhand)) { - bus_release_resources(dev, jz4780_mmc_res_spec, sc->sc_res); - device_printf(dev, "cannot setup interrupt handler\n"); - return (ENXIO); - } - sc->sc_timeout = 10; - ctx = device_get_sysctl_ctx(dev); - tree = SYSCTL_CHILDREN(device_get_sysctl_tree(dev)); - SYSCTL_ADD_INT(ctx, tree, OID_AUTO, "req_timeout", CTLFLAG_RW, - &sc->sc_timeout, 0, "Request timeout in seconds"); - mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), "jz4780_mmc", - MTX_DEF); - callout_init_mtx(&sc->sc_timeoutc, &sc->sc_mtx, 0); - - /* Reset controller. */ - if (jz4780_mmc_reset(sc) != 0) { - device_printf(dev, "cannot reset the controller\n"); - goto fail; - } - if (jz4780_mmc_pio_mode == 0 && jz4780_mmc_setup_dma(sc) != 0) { - device_printf(sc->sc_dev, "Couldn't setup DMA!\n"); - jz4780_mmc_pio_mode = 1; - } - if (bootverbose) - device_printf(sc->sc_dev, "DMA status: %s\n", - jz4780_mmc_pio_mode ? "disabled" : "enabled"); - - node = ofw_bus_get_node(dev); - /* Determine max operating frequency */ - sc->sc_host.f_max = 24000000; - len = OF_getencprop(node, "max-frequency", &prop, sizeof(prop)); - if (len / sizeof(prop) == 1) - sc->sc_host.f_max = prop; - sc->sc_host.f_min = sc->sc_host.f_max / 128; - - sc->sc_host.host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340; - sc->sc_host.caps = MMC_CAP_HSPEED; - sc->sc_host.mode = mode_sd; - /* - * Check for bus-width property, default to both 4 and 8 bit - * if no bus width is specified. - */ - len = OF_getencprop(node, "bus-width", &prop, sizeof(prop)); - if (len / sizeof(prop) != 1) - sc->sc_host.caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA; - else if (prop == 8) - sc->sc_host.caps |= MMC_CAP_8_BIT_DATA; - else if (prop == 4) - sc->sc_host.caps |= MMC_CAP_4_BIT_DATA; - /* Activate the module clock. */ - if (jz4780_mmc_enable_clock(sc) != 0) { - device_printf(dev, "cannot activate mmc clock\n"); - goto fail; - } - - child = device_add_child(dev, "mmc", -1); - if (child == NULL) { - device_printf(dev, "attaching MMC bus failed!\n"); - goto fail; - } - if (device_probe_and_attach(child) != 0) { - device_printf(dev, "attaching MMC child failed!\n"); - device_delete_child(dev, child); - goto fail; - } - - return (0); - -fail: - callout_drain(&sc->sc_timeoutc); - mtx_destroy(&sc->sc_mtx); - bus_teardown_intr(dev, sc->sc_res[JZ_MSC_IRQRES], sc->sc_intrhand); - bus_release_resources(dev, jz4780_mmc_res_spec, sc->sc_res); - if (sc->sc_clk != NULL) - clk_release(sc->sc_clk); - return (ENXIO); -} - -static int -jz4780_mmc_detach(device_t dev) -{ - - return (EBUSY); -} - -static int -jz4780_mmc_enable_clock(struct jz4780_mmc_softc *sc) -{ - int err; - - err = clk_get_by_ofw_name(sc->sc_dev, 0, "mmc", &sc->sc_clk); - if (err == 0) - err = clk_enable(sc->sc_clk); - if (err == 0) - err = clk_set_freq(sc->sc_clk, sc->sc_host.f_max, 0); - if (err != 0) - clk_release(sc->sc_clk); - return (err); -} - -static void -jz4780_mmc_dma_desc_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int err) -{ - struct jz4780_mmc_softc *sc; - - sc = (struct jz4780_mmc_softc *)arg; - if (err) { - sc->sc_dma_map_err = err; - return; - } - sc->sc_dma_desc_phys = segs[0].ds_addr; -} - -static int -jz4780_mmc_setup_dma(struct jz4780_mmc_softc *sc) -{ - int dma_desc_size, error; - - /* Allocate the DMA descriptor memory. */ - dma_desc_size = sizeof(struct jz4780_mmc_dma_desc) * JZ_MSC_DMA_SEGS; - error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, - BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, - dma_desc_size, 1, dma_desc_size, 0, NULL, NULL, &sc->sc_dma_tag); - if (error) - return (error); - error = bus_dmamem_alloc(sc->sc_dma_tag, &sc->sc_dma_desc, - BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->sc_dma_map); - if (error) - return (error); - - error = bus_dmamap_load(sc->sc_dma_tag, sc->sc_dma_map, - sc->sc_dma_desc, dma_desc_size, jz4780_mmc_dma_desc_cb, sc, 0); - if (error) - return (error); - if (sc->sc_dma_map_err) - return (sc->sc_dma_map_err); - - /* Create the DMA map for data transfers. */ - error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, - BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, - JZ_MSC_DMA_MAX_SIZE * JZ_MSC_DMA_SEGS, JZ_MSC_DMA_SEGS, - JZ_MSC_DMA_MAX_SIZE, BUS_DMA_ALLOCNOW, NULL, NULL, - &sc->sc_dma_buf_tag); - if (error) - return (error); - error = bus_dmamap_create(sc->sc_dma_buf_tag, 0, - &sc->sc_dma_buf_map); - if (error) - return (error); - - return (0); -} - -static void -jz4780_mmc_dma_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int err) -{ - struct jz4780_mmc_dma_desc *dma_desc; - struct jz4780_mmc_softc *sc; - uint32_t dma_desc_phys; - int i; - - sc = (struct jz4780_mmc_softc *)arg; - sc->sc_dma_map_err = err; - dma_desc = sc->sc_dma_desc; - dma_desc_phys = sc->sc_dma_desc_phys; - - /* Note nsegs is guaranteed to be zero if err is non-zero. */ - for (i = 0; i < nsegs; i++) { - dma_desc[i].dma_phys = segs[i].ds_addr; - dma_desc[i].dma_len = segs[i].ds_len; - if (i < (nsegs - 1)) { - dma_desc_phys += sizeof(struct jz4780_mmc_dma_desc); - dma_desc[i].dma_next = dma_desc_phys; - dma_desc[i].dma_cmd = (i << 16) | JZ_DMA_LINK; - } else { - dma_desc[i].dma_next = 0; - dma_desc[i].dma_cmd = (i << 16) | JZ_DMA_ENDI; - } -#ifdef JZ_MMC_DEBUG - device_printf(sc->sc_dev, "%d: desc %#x phys %#x len %d next %#x cmd %#x\n", - i, dma_desc_phys - sizeof(struct jz4780_mmc_dma_desc), - dma_desc[i].dma_phys, dma_desc[i].dma_len, - dma_desc[i].dma_next, dma_desc[i].dma_cmd); -#endif - } -} - -static int -jz4780_mmc_prepare_dma(struct jz4780_mmc_softc *sc) -{ - bus_dmasync_op_t sync_op; - int error; - struct mmc_command *cmd; - uint32_t off; - - cmd = sc->sc_req->cmd; - if (cmd->data->len > JZ_MSC_DMA_MAX_SIZE * JZ_MSC_DMA_SEGS) - return (EFBIG); - error = bus_dmamap_load(sc->sc_dma_buf_tag, sc->sc_dma_buf_map, - cmd->data->data, cmd->data->len, jz4780_mmc_dma_cb, sc, - BUS_DMA_NOWAIT); - if (error) - return (error); - if (sc->sc_dma_map_err) - return (sc->sc_dma_map_err); - - sc->sc_dma_inuse = 1; - if (cmd->data->flags & MMC_DATA_WRITE) - sync_op = BUS_DMASYNC_PREWRITE; - else - sync_op = BUS_DMASYNC_PREREAD; - bus_dmamap_sync(sc->sc_dma_buf_tag, sc->sc_dma_buf_map, sync_op); - bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map, BUS_DMASYNC_PREWRITE); - - /* Configure default DMA parameters */ - sc->sc_dma_ctl = JZ_MODE_SEL | JZ_INCR_64 | JZ_DMAEN; - - /* Enable unaligned buffer handling */ - off = (uintptr_t)cmd->data->data & 3; - if (off != 0) - sc->sc_dma_ctl |= (off << JZ_AOFST_S) | JZ_ALIGNEN; - return (0); -} - -static void -jz4780_mmc_start_dma(struct jz4780_mmc_softc *sc) -{ - - /* Set the address of the first descriptor */ - JZ_MMC_WRITE_4(sc, JZ_MSC_DMANDA, sc->sc_dma_desc_phys); - /* Enable and start the dma engine */ - JZ_MMC_WRITE_4(sc, JZ_MSC_DMAC, sc->sc_dma_ctl); -} - -static int -jz4780_mmc_reset(struct jz4780_mmc_softc *sc) -{ - int timeout; - - /* Stop the clock */ - JZ_MMC_WRITE_4(sc, JZ_MSC_CTRL, JZ_CLOCK_STOP); - - timeout = 1000; - while (--timeout > 0) { - if ((JZ_MMC_READ_4(sc, JZ_MSC_STAT) & JZ_CLK_EN) == 0) - break; - DELAY(100); - } - if (timeout == 0) { - device_printf(sc->sc_dev, "Failed to stop clk.\n"); - return (ETIMEDOUT); - } - - /* Reset */ - JZ_MMC_WRITE_4(sc, JZ_MSC_CTRL, JZ_RESET); - - timeout = 10; - while (--timeout > 0) { - if ((JZ_MMC_READ_4(sc, JZ_MSC_STAT) & JZ_IS_RESETTING) == 0) - break; - DELAY(1000); - } - - if (timeout == 0) { - /* - * X1000 never clears reseting bit. - * Ignore for now. - */ - } - - /* Set the timeouts. */ - JZ_MMC_WRITE_4(sc, JZ_MSC_RESTO, 0xffff); - JZ_MMC_WRITE_4(sc, JZ_MSC_RDTO, 0xffffffff); - - /* Mask all interrupt initially */ - JZ_MMC_WRITE_4(sc, JZ_MSC_IMASK, 0xffffffff); - /* Clear pending interrupts. */ - JZ_MMC_WRITE_4(sc, JZ_MSC_IFLG, 0xffffffff); - - /* Remember interrupts we always want */ - sc->sc_intr_mask = JZ_MSC_INT_ERR_BITS; - - return (0); -} - -static void -jz4780_mmc_req_done(struct jz4780_mmc_softc *sc) -{ - struct mmc_command *cmd; - struct mmc_request *req; - bus_dmasync_op_t sync_op; - - cmd = sc->sc_req->cmd; - /* Reset the controller in case of errors */ - if (cmd->error != MMC_ERR_NONE) - jz4780_mmc_reset(sc); - /* Unmap DMA if necessary */ - if (sc->sc_dma_inuse == 1) { - if (cmd->data->flags & MMC_DATA_WRITE) - sync_op = BUS_DMASYNC_POSTWRITE; - else - sync_op = BUS_DMASYNC_POSTREAD; - bus_dmamap_sync(sc->sc_dma_buf_tag, sc->sc_dma_buf_map, - sync_op); - bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map, - BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->sc_dma_buf_tag, sc->sc_dma_buf_map); - } - req = sc->sc_req; - callout_stop(&sc->sc_timeoutc); - sc->sc_req = NULL; - sc->sc_resid = 0; - sc->sc_dma_inuse = 0; - sc->sc_dma_map_err = 0; - sc->sc_intr_wait = 0; - sc->sc_intr_seen = 0; - req->done(req); -} - -static void -jz4780_mmc_read_response(struct jz4780_mmc_softc *sc) -{ - struct mmc_command *cmd; - int i; - - cmd = sc->sc_req->cmd; - if (cmd->flags & MMC_RSP_PRESENT) { - if (cmd->flags & MMC_RSP_136) { - uint16_t val; - - val = JZ_MMC_READ_2(sc, JZ_MSC_RES); - for (i = 0; i < 4; i++) { - cmd->resp[i] = val << 24; - val = JZ_MMC_READ_2(sc, JZ_MSC_RES); - cmd->resp[i] |= val << 8; - val = JZ_MMC_READ_2(sc, JZ_MSC_RES); - cmd->resp[i] |= val >> 8; - } - } else { - cmd->resp[0] = JZ_MMC_READ_2(sc, JZ_MSC_RES) << 24; - cmd->resp[0] |= JZ_MMC_READ_2(sc, JZ_MSC_RES) << 8; - cmd->resp[0] |= JZ_MMC_READ_2(sc, JZ_MSC_RES) & 0xff; - } - } -} - -static void -jz4780_mmc_req_ok(struct jz4780_mmc_softc *sc) -{ - struct mmc_command *cmd; - - cmd = sc->sc_req->cmd; - /* All data has been transferred ? */ - if (cmd->data != NULL && (sc->sc_resid << 2) < cmd->data->len) - cmd->error = MMC_ERR_FAILED; - jz4780_mmc_req_done(sc); -} - -static void -jz4780_mmc_timeout(void *arg) -{ - struct jz4780_mmc_softc *sc; - - sc = (struct jz4780_mmc_softc *)arg; - if (sc->sc_req != NULL) { - device_printf(sc->sc_dev, "controller timeout, rint %#x stat %#x\n", - JZ_MMC_READ_4(sc, JZ_MSC_IFLG), JZ_MMC_READ_4(sc, JZ_MSC_STAT)); - sc->sc_req->cmd->error = MMC_ERR_TIMEOUT; - jz4780_mmc_req_done(sc); - } else - device_printf(sc->sc_dev, - "Spurious timeout - no active request\n"); -} - -static int -jz4780_mmc_pio_transfer(struct jz4780_mmc_softc *sc, struct mmc_data *data) -{ - uint32_t mask, *buf; - int i, write; - - buf = (uint32_t *)data->data; - write = (data->flags & MMC_DATA_WRITE) ? 1 : 0; - mask = write ? JZ_DATA_FIFO_FULL : JZ_DATA_FIFO_EMPTY; - for (i = sc->sc_resid; i < (data->len >> 2); i++) { - if ((JZ_MMC_READ_4(sc, JZ_MSC_STAT) & mask)) - return (1); - if (write) - JZ_MMC_WRITE_4(sc, JZ_MSC_TXFIFO, buf[i]); - else - buf[i] = JZ_MMC_READ_4(sc, JZ_MSC_RXFIFO); - sc->sc_resid = i + 1; - } - - /* Done with pio transfer, shut FIFO interrupts down */ - mask = JZ_MMC_READ_4(sc, JZ_MSC_IMASK); - mask |= (JZ_INT_TXFIFO_WR_REQ | JZ_INT_RXFIFO_RD_REQ); - JZ_MMC_WRITE_4(sc, JZ_MSC_IMASK, mask); - return (0); -} - -static void -jz4780_mmc_intr(void *arg) -{ - struct jz4780_mmc_softc *sc; - struct mmc_data *data; - uint32_t rint; - - sc = (struct jz4780_mmc_softc *)arg; - JZ_MMC_LOCK(sc); - rint = JZ_MMC_READ_4(sc, JZ_MSC_IFLG); -#if defined(JZ_MMC_DEBUG) - device_printf(sc->sc_dev, "rint: %#x, stat: %#x\n", - rint, JZ_MMC_READ_4(sc, JZ_MSC_STAT)); - if (sc->sc_dma_inuse == 1 && (sc->sc_intr_seen & JZ_INT_DMAEND) == 0) - device_printf(sc->sc_dev, "\tdmada %#x dmanext %#x dmac %#x" - " dmalen %d dmacmd %#x\n", - JZ_MMC_READ_4(sc, JZ_MSC_DMADA), - JZ_MMC_READ_4(sc, JZ_MSC_DMANDA), - JZ_MMC_READ_4(sc, JZ_MSC_DMAC), - JZ_MMC_READ_4(sc, JZ_MSC_DMALEN), - JZ_MMC_READ_4(sc, JZ_MSC_DMACMD)); -#endif - if (sc->sc_req == NULL) { - device_printf(sc->sc_dev, - "Spurious interrupt - no active request, rint: 0x%08X\n", - rint); - goto end; - } - if (rint & JZ_MSC_INT_ERR_BITS) { -#if defined(JZ_MMC_DEBUG) - device_printf(sc->sc_dev, "controller error, rint %#x stat %#x\n", - rint, JZ_MMC_READ_4(sc, JZ_MSC_STAT)); -#endif - if (rint & (JZ_INT_TIMEOUT_RES | JZ_INT_TIMEOUT_READ)) - sc->sc_req->cmd->error = MMC_ERR_TIMEOUT; - else - sc->sc_req->cmd->error = MMC_ERR_FAILED; - jz4780_mmc_req_done(sc); - goto end; - } - data = sc->sc_req->cmd->data; - /* Check for command response */ - if (rint & JZ_INT_END_CMD_RES) { - jz4780_mmc_read_response(sc); - if (sc->sc_dma_inuse == 1) - jz4780_mmc_start_dma(sc); - } - if (data != NULL) { - if (sc->sc_dma_inuse == 1 && (rint & JZ_INT_DMAEND)) - sc->sc_resid = data->len >> 2; - else if (sc->sc_dma_inuse == 0 && - (rint & (JZ_INT_TXFIFO_WR_REQ | JZ_INT_RXFIFO_RD_REQ))) - jz4780_mmc_pio_transfer(sc, data); - } - sc->sc_intr_seen |= rint; - if ((sc->sc_intr_seen & sc->sc_intr_wait) == sc->sc_intr_wait) - jz4780_mmc_req_ok(sc); -end: - JZ_MMC_WRITE_4(sc, JZ_MSC_IFLG, rint); - JZ_MMC_UNLOCK(sc); -} - -static int -jz4780_mmc_request(device_t bus, device_t child, struct mmc_request *req) -{ - struct jz4780_mmc_softc *sc; - struct mmc_command *cmd; - uint32_t cmdat, iwait; - int blksz; - - sc = device_get_softc(bus); - JZ_MMC_LOCK(sc); - if (sc->sc_req != NULL) { - JZ_MMC_UNLOCK(sc); - return (EBUSY); - } - /* Start with template value */ - cmdat = sc->sc_cmdat; - iwait = JZ_INT_END_CMD_RES; - - /* Configure response format */ - cmd = req->cmd; - switch (MMC_RSP(cmd->flags)) { - case MMC_RSP_R1: - case MMC_RSP_R1B: - cmdat |= JZ_RES_R1; - break; - case MMC_RSP_R2: - cmdat |= JZ_RES_R2; - break; - case MMC_RSP_R3: - cmdat |= JZ_RES_R3; - break; - }; - if (cmd->opcode == MMC_GO_IDLE_STATE) - cmdat |= JZ_INIT; - if (cmd->flags & MMC_RSP_BUSY) { - cmdat |= JZ_BUSY; - iwait |= JZ_INT_PRG_DONE; - } - - sc->sc_req = req; - sc->sc_resid = 0; - cmd->error = MMC_ERR_NONE; - - if (cmd->data != NULL) { - cmdat |= JZ_DATA_EN; - if (cmd->data->flags & MMC_DATA_MULTI) { - cmdat |= JZ_AUTO_CMD12; - iwait |= JZ_INT_AUTO_CMD12_DONE; - } - if (cmd->data->flags & MMC_DATA_WRITE) { - cmdat |= JZ_WRITE; - iwait |= JZ_INT_PRG_DONE; - } - if (cmd->data->flags & MMC_DATA_STREAM) - cmdat |= JZ_STREAM; - else - iwait |= JZ_INT_DATA_TRAN_DONE; - - blksz = min(cmd->data->len, MMC_SECTOR_SIZE); - JZ_MMC_WRITE_4(sc, JZ_MSC_BLKLEN, blksz); - JZ_MMC_WRITE_4(sc, JZ_MSC_NOB, cmd->data->len / blksz); - - /* Attempt to setup DMA for this transaction */ - if (jz4780_mmc_pio_mode == 0) - jz4780_mmc_prepare_dma(sc); - if (sc->sc_dma_inuse != 0) { - /* Wait for DMA completion interrupt */ - iwait |= JZ_INT_DMAEND; - } else { - iwait |= (cmd->data->flags & MMC_DATA_WRITE) ? - JZ_INT_TXFIFO_WR_REQ : JZ_INT_RXFIFO_RD_REQ; - JZ_MMC_WRITE_4(sc, JZ_MSC_DMAC, 0); - } - } - - sc->sc_intr_seen = 0; - sc->sc_intr_wait = iwait; - JZ_MMC_WRITE_4(sc, JZ_MSC_IMASK, ~(sc->sc_intr_mask | iwait)); - -#if defined(JZ_MMC_DEBUG) - device_printf(sc->sc_dev, - "REQUEST: CMD%u arg %#x flags %#x cmdat %#x sc_intr_wait = %#x\n", - cmd->opcode, cmd->arg, cmd->flags, cmdat, sc->sc_intr_wait); -#endif - - JZ_MMC_WRITE_4(sc, JZ_MSC_ARG, cmd->arg); - JZ_MMC_WRITE_4(sc, JZ_MSC_CMD, cmd->opcode); - JZ_MMC_WRITE_4(sc, JZ_MSC_CMDAT, cmdat); - - JZ_MMC_WRITE_4(sc, JZ_MSC_CTRL, JZ_START_OP | JZ_CLOCK_START); - - callout_reset(&sc->sc_timeoutc, sc->sc_timeout * hz, - jz4780_mmc_timeout, sc); - JZ_MMC_UNLOCK(sc); - - return (0); -} - -static int -jz4780_mmc_read_ivar(device_t bus, device_t child, int which, - uintptr_t *result) -{ - struct jz4780_mmc_softc *sc; - - sc = device_get_softc(bus); - switch (which) { - default: - return (EINVAL); - case MMCBR_IVAR_BUS_MODE: - *(int *)result = sc->sc_host.ios.bus_mode; - break; - case MMCBR_IVAR_BUS_WIDTH: - *(int *)result = sc->sc_host.ios.bus_width; - break; - case MMCBR_IVAR_CHIP_SELECT: - *(int *)result = sc->sc_host.ios.chip_select; - break; - case MMCBR_IVAR_CLOCK: - *(int *)result = sc->sc_host.ios.clock; - break; - case MMCBR_IVAR_F_MIN: - *(int *)result = sc->sc_host.f_min; - break; - case MMCBR_IVAR_F_MAX: - *(int *)result = sc->sc_host.f_max; - break; - case MMCBR_IVAR_HOST_OCR: - *(int *)result = sc->sc_host.host_ocr; - break; - case MMCBR_IVAR_MODE: - *(int *)result = sc->sc_host.mode; - break; - case MMCBR_IVAR_OCR: - *(int *)result = sc->sc_host.ocr; - break; - case MMCBR_IVAR_POWER_MODE: - *(int *)result = sc->sc_host.ios.power_mode; - break; - case MMCBR_IVAR_VDD: - *(int *)result = sc->sc_host.ios.vdd; - break; - case MMCBR_IVAR_CAPS: - *(int *)result = sc->sc_host.caps; - break; - case MMCBR_IVAR_MAX_DATA: - *(int *)result = 65535; - break; - case MMCBR_IVAR_TIMING: - *(int *)result = sc->sc_host.ios.timing; - break; - } - - return (0); -} - -static int -jz4780_mmc_write_ivar(device_t bus, device_t child, int which, - uintptr_t value) -{ - struct jz4780_mmc_softc *sc; - - sc = device_get_softc(bus); - switch (which) { - default: - return (EINVAL); - case MMCBR_IVAR_BUS_MODE: - sc->sc_host.ios.bus_mode = value; - break; - case MMCBR_IVAR_BUS_WIDTH: - sc->sc_host.ios.bus_width = value; - break; - case MMCBR_IVAR_CHIP_SELECT: - sc->sc_host.ios.chip_select = value; - break; - case MMCBR_IVAR_CLOCK: - sc->sc_host.ios.clock = value; - break; - case MMCBR_IVAR_MODE: - sc->sc_host.mode = value; - break; - case MMCBR_IVAR_OCR: - sc->sc_host.ocr = value; - break; - case MMCBR_IVAR_POWER_MODE: - sc->sc_host.ios.power_mode = value; - break; - case MMCBR_IVAR_VDD: - sc->sc_host.ios.vdd = value; - break; - case MMCBR_IVAR_TIMING: - sc->sc_host.ios.timing = 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 int -jz4780_mmc_disable_clock(struct jz4780_mmc_softc *sc) -{ - int timeout; - - JZ_MMC_WRITE_4(sc, JZ_MSC_CTRL, JZ_CLOCK_STOP); - - for (timeout = 1000; timeout > 0; timeout--) - if ((JZ_MMC_READ_4(sc, JZ_MSC_STAT) & JZ_CLK_EN) == 0) - return (0); - return (ETIMEDOUT); -} - -static int -jz4780_mmc_config_clock(struct jz4780_mmc_softc *sc, uint32_t freq) -{ - uint64_t rate; - uint32_t clk_freq; - int err, div; - - err = jz4780_mmc_disable_clock(sc); - if (err != 0) - return (err); - - clk_get_freq(sc->sc_clk, &rate); - clk_freq = (uint32_t)rate; - - div = 0; - while (clk_freq > freq) { - div++; - clk_freq >>= 1; - } - if (div >= 7) - div = 7; -#if defined(JZ_MMC_DEBUG) - if (div != JZ_MMC_READ_4(sc, JZ_MSC_CLKRT)) - device_printf(sc->sc_dev, - "UPDATE_IOS: clk -> %u\n", clk_freq); -#endif - JZ_MMC_WRITE_4(sc, JZ_MSC_CLKRT, div); - return (0); -} - -static int -jz4780_mmc_update_ios(device_t bus, device_t child) -{ - struct jz4780_mmc_softc *sc; - struct mmc_ios *ios; - int error; - - sc = device_get_softc(bus); - ios = &sc->sc_host.ios; - if (ios->clock) { - /* Set the MMC clock. */ - error = jz4780_mmc_config_clock(sc, ios->clock); - if (error != 0) - return (error); - } - - /* Set the bus width. */ - switch (ios->bus_width) { - case bus_width_1: - sc->sc_cmdat &= ~(JZ_BUS_WIDTH_M); - sc->sc_cmdat |= JZ_BUS_1BIT; - break; - case bus_width_4: - sc->sc_cmdat &= ~(JZ_BUS_WIDTH_M); - sc->sc_cmdat |= JZ_BUS_4BIT; - break; - case bus_width_8: - sc->sc_cmdat &= ~(JZ_BUS_WIDTH_M); - sc->sc_cmdat |= JZ_BUS_8BIT; - break; - } - return (0); -} - -static int -jz4780_mmc_get_ro(device_t bus, device_t child) -{ - - return (0); -} - -static int -jz4780_mmc_acquire_host(device_t bus, device_t child) -{ - struct jz4780_mmc_softc *sc; - int error; - - sc = device_get_softc(bus); - JZ_MMC_LOCK(sc); - while (sc->sc_bus_busy) { - error = msleep(sc, &sc->sc_mtx, PCATCH, "mmchw", 0); - if (error != 0) { - JZ_MMC_UNLOCK(sc); - return (error); - } - } - sc->sc_bus_busy++; - JZ_MMC_UNLOCK(sc); - - return (0); -} - -static int -jz4780_mmc_release_host(device_t bus, device_t child) -{ - struct jz4780_mmc_softc *sc; - - sc = device_get_softc(bus); - JZ_MMC_LOCK(sc); - sc->sc_bus_busy--; - wakeup(sc); - JZ_MMC_UNLOCK(sc); - - return (0); -} - -static device_method_t jz4780_mmc_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, jz4780_mmc_probe), - DEVMETHOD(device_attach, jz4780_mmc_attach), - DEVMETHOD(device_detach, jz4780_mmc_detach), - - /* Bus interface */ - DEVMETHOD(bus_read_ivar, jz4780_mmc_read_ivar), - DEVMETHOD(bus_write_ivar, jz4780_mmc_write_ivar), - - /* MMC bridge interface */ - DEVMETHOD(mmcbr_update_ios, jz4780_mmc_update_ios), - DEVMETHOD(mmcbr_request, jz4780_mmc_request), - DEVMETHOD(mmcbr_get_ro, jz4780_mmc_get_ro), - DEVMETHOD(mmcbr_acquire_host, jz4780_mmc_acquire_host), - DEVMETHOD(mmcbr_release_host, jz4780_mmc_release_host), - - DEVMETHOD_END -}; - -static devclass_t jz4780_mmc_devclass; - -static driver_t jz4780_mmc_driver = { - "jzmmc", - jz4780_mmc_methods, - sizeof(struct jz4780_mmc_softc), -}; - -DRIVER_MODULE(jzmmc, simplebus, jz4780_mmc_driver, jz4780_mmc_devclass, NULL, - NULL); -MMC_DECLARE_BRIDGE(jzmmc); Index: sys/mips/ingenic/jz4780_mp.c =================================================================== --- sys/mips/ingenic/jz4780_mp.c +++ /dev/null @@ -1,182 +0,0 @@ -/*- - * Copyright (c) 2015 Alexander Kabaev - * Copyright (c) 2004-2010 Juli Mallett - * 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$ - */ -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -void jz4780_mpentry(void); - -#define JZ4780_MAXCPU 2 - -void -platform_ipi_send(int cpuid) -{ - - if (cpuid == 0) - mips_wr_xburst_mbox0(1); - else - mips_wr_xburst_mbox1(1); -} - -void -platform_ipi_clear(void) -{ - int cpuid = PCPU_GET(cpuid); - uint32_t action; - - action = (cpuid == 0) ? mips_rd_xburst_mbox0() : mips_rd_xburst_mbox1(); - KASSERT(action == 1, ("CPU %d: unexpected IPIs: %#x", cpuid, action)); - mips_wr_xburst_core_sts(~(JZ_CORESTS_MIRQ0P << cpuid)); -} - -int -platform_processor_id(void) -{ - - return (mips_rd_ebase() & 7); -} - -int -platform_ipi_hardintr_num(void) -{ - - return (1); -} - -int -platform_ipi_softintr_num(void) -{ - - return (-1); -} - -void -platform_init_ap(int cpuid) -{ - unsigned reg; - - /* - * Clear any pending IPIs. - */ - mips_wr_xburst_core_sts(~(JZ_CORESTS_MIRQ0P << cpuid)); - - /* Allow IPI mbox for this core */ - reg = mips_rd_xburst_reim(); - reg |= (JZ_REIM_MIRQ0M << cpuid); - mips_wr_xburst_reim(reg); - - /* - * Unmask the ipi interrupts. - */ - reg = hard_int_mask(platform_ipi_hardintr_num()); - set_intr_mask(reg); -} - -void -platform_cpu_mask(cpuset_t *mask) -{ - uint32_t i, m; - - CPU_ZERO(mask); - for (i = 0, m = 1 ; i < JZ4780_MAXCPU; i++, m <<= 1) - CPU_SET(i, mask); -} - -struct cpu_group * -platform_smp_topo(void) -{ - return (smp_topo_none()); -} - -static void -jz4780_core_powerup(void) -{ - uint32_t reg; - - reg = readreg(JZ_CGU_BASE + JZ_LPCR); - reg &= ~LPCR_PD_SCPU; - writereg(JZ_CGU_BASE + JZ_LPCR, reg); - do { - reg = readreg(JZ_CGU_BASE + JZ_LPCR); - } while ((reg & LPCR_SCPUS) != 0); -} - -/* - * Spin up the second code. The code is roughly modeled after - * similar routine in Linux. - */ -int -platform_start_ap(int cpuid) -{ - uint32_t reg, addr; - - if (cpuid >= JZ4780_MAXCPU) - return (EINVAL); - - /* Figure out address of mpentry in KSEG1 */ - addr = MIPS_PHYS_TO_KSEG1(MIPS_KSEG0_TO_PHYS(jz4780_mpentry)); - KASSERT((addr & ~JZ_REIM_ENTRY_MASK) == 0, - ("Unaligned mpentry")); - - /* Configure core alternative entry point */ - reg = mips_rd_xburst_reim(); - reg &= ~JZ_REIM_ENTRY_MASK; - reg |= addr & JZ_REIM_ENTRY_MASK; - - /* Allow this core to get IPIs from one being started */ - reg |= JZ_REIM_MIRQ0M; - mips_wr_xburst_reim(reg); - - /* Force core into reset and enable use of alternate entry point */ - reg = mips_rd_xburst_core_ctl(); - reg |= (JZ_CORECTL_SWRST0 << cpuid) | (JZ_CORECTL_RPC0 << cpuid); - mips_wr_xburst_core_ctl(reg); - - /* Power the core up */ - jz4780_core_powerup(); - - /* Take the core out of reset */ - reg &= ~(JZ_CORECTL_SWRST0 << cpuid); - mips_wr_xburst_core_ctl(reg); - - return (0); -} Index: sys/mips/ingenic/jz4780_mpboot.S =================================================================== --- sys/mips/ingenic/jz4780_mpboot.S +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * Copyright (c) 2015 Alexander Kabaev - * 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$ - */ - -#include -#include "assym.inc" - - .text - .set noat - .set noreorder - .section .text.mpentry_jz4780 - .balign 0x10000 - -/* - * JZ4870 has stricter alignment requirement for - * CPU entry point. Enforce it in CPU-specific - * file. - */ -GLOBAL(jz4780_mpentry) - j mpentry - nop Index: sys/mips/ingenic/jz4780_nand.c =================================================================== --- sys/mips/ingenic/jz4780_nand.c +++ /dev/null @@ -1,123 +0,0 @@ -/*- - * Copyright 2015 Alexander Kabaev - * 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. - */ - -/* - * Ingenic JZ4780 NAND and External Memory Controller (NEMC) driver. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -struct jz4780_nand_softc { - device_t dev; - struct resource *res[1]; -}; - -static struct resource_spec jz4780_nand_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE }, - { -1, 0 } -}; - -static int jz4780_nand_probe(device_t dev); -static int jz4780_nand_attach(device_t dev); -static int jz4780_nand_detach(device_t dev); - -static int -jz4780_nand_probe(device_t dev) -{ - - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (!ofw_bus_is_compatible(dev, "ingenic,jz4780-nand")) - return (ENXIO); - - device_set_desc(dev, "Ingenic JZ4780 NAND Controller"); - - return (BUS_PROBE_DEFAULT); -} - -static int -jz4780_nand_attach(device_t dev) -{ - struct jz4780_nand_softc *sc = device_get_softc(dev); - - sc->dev = dev; - - if (bus_alloc_resources(dev, jz4780_nand_spec, sc->res)) { - device_printf(dev, "could not allocate resources for device\n"); - return (ENXIO); - } - - return (0); -} - -static int -jz4780_nand_detach(device_t dev) -{ - struct jz4780_nand_softc *sc = device_get_softc(dev); - - bus_release_resources(dev, jz4780_nand_spec, sc->res); - return (0); -} - -static device_method_t jz4780_nand_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, jz4780_nand_probe), - DEVMETHOD(device_attach, jz4780_nand_attach), - DEVMETHOD(device_detach, jz4780_nand_detach), - - DEVMETHOD_END -}; - -static driver_t jz4780_nand_driver = { - "nand", - jz4780_nand_methods, - sizeof(struct jz4780_nand_softc), -}; - -static devclass_t jz4780_nand_devclass; - -DRIVER_MODULE(jz4780_nand, simplebus, jz4780_nand_driver, - jz4780_nand_devclass, 0, 0); Index: sys/mips/ingenic/jz4780_nemc.c =================================================================== --- sys/mips/ingenic/jz4780_nemc.c +++ /dev/null @@ -1,373 +0,0 @@ -/*- - * Copyright 2015 Alexander Kabaev - * 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. - */ - -/* - * Ingenic JZ4780 NAND and External Memory Controller (NEMC) driver. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include - -#include - -struct jz4780_nemc_devinfo { - struct simplebus_devinfo sinfo; - uint32_t bank; -}; - -struct jz4780_nemc_softc { - struct simplebus_softc simplebus_sc; - device_t dev; - struct resource *res[1]; - uint32_t banks; - uint32_t clock_tick_psecs; - clk_t clk; -}; - -static struct resource_spec jz4780_nemc_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE }, - { -1, 0 } -}; - -#define CSR_WRITE_4(sc, reg, val) bus_write_4((sc)->res[0], reg, (val)) -#define CSR_READ_4(sc, reg) bus_read_4((sc)->res[0], reg) - -static int jz4780_nemc_probe(device_t dev); -static int jz4780_nemc_attach(device_t dev); -static int jz4780_nemc_detach(device_t dev); - -static int -jz4780_nemc_probe(device_t dev) -{ - - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (!ofw_bus_is_compatible(dev, "ingenic,jz4780-nemc")) - return (ENXIO); - - device_set_desc(dev, "Ingenic JZ4780 NEMC"); - - return (BUS_PROBE_DEFAULT); -} - -#define JZ4780_NEMC_NS_TO_TICKS(sc, val) howmany((val) * 1000, (sc)->clock_tick_psecs) - -/* Use table from JZ4780 programmers manual to convert ticks to tBP/tAW register values */ -static const uint8_t ticks_to_tBP_tAW[32] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, /* 1:1 mapping */ - 11, 11, /* 12 cycles */ - 12, 12, 12, /* 15 cycles */ - 13, 13, 13, 13, 13, /* 20 cycles */ - 14, 14, 14, 14, 14, /* 25 cycles */ - 15, 15, 15, 15, 15, 15 /* 31 cycles */ -}; - -static int -jz4780_nemc_configure_bank(struct jz4780_nemc_softc *sc, - device_t dev, u_int bank) -{ - uint32_t smcr, cycles; - phandle_t node; - pcell_t val; - - /* Check if bank is configured already */ - if (sc->banks & (1 << bank)) - return 0; - - smcr = CSR_READ_4(sc, JZ_NEMC_SMCR(bank)); - - smcr &= ~JZ_NEMC_SMCR_SMT_MASK; - smcr |= JZ_NEMC_SMCR_SMT_NORMAL << JZ_NEMC_SMCR_SMT_SHIFT; - - node = ofw_bus_get_node(dev); - if (OF_getencprop(node, "ingenic,nemc-tAS", &val, sizeof(val)) > 0) { - cycles = JZ4780_NEMC_NS_TO_TICKS(sc, val); - if (cycles > 15) { - device_printf(sc->dev, - "invalid value of %s %u (%u cycles), maximum %u cycles supported\n", - "ingenic,nemc-tAS", val, cycles, 15); - return -1; - } - smcr &= ~JZ_NEMC_SMCR_TAS_MASK; - smcr |= cycles << JZ_NEMC_SMCR_TAS_SHIFT; - } - - if (OF_getencprop(node, "ingenic,nemc-tAH", &val, sizeof(val)) > 0) { - cycles = JZ4780_NEMC_NS_TO_TICKS(sc, val); - if (cycles > 15) { - device_printf(sc->dev, - "invalid value of %s %u (%u cycles), maximum %u cycles supported\n", - "ingenic,nemc-tAH", val, cycles, 15); - return -1; - } - smcr &= ~JZ_NEMC_SMCR_TAH_MASK; - smcr |= cycles << JZ_NEMC_SMCR_TAH_SHIFT; - } - - if (OF_getencprop(node, "ingenic,nemc-tBP", &val, sizeof(val)) > 0) { - cycles = JZ4780_NEMC_NS_TO_TICKS(sc, val); - if (cycles > 31) { - device_printf(sc->dev, - "invalid value of %s %u (%u cycles), maximum %u cycles supported\n", - "ingenic,nemc-tBP", val, cycles, 15); - return -1; - } - smcr &= ~JZ_NEMC_SMCR_TBP_MASK; - smcr |= ticks_to_tBP_tAW[cycles] << JZ_NEMC_SMCR_TBP_SHIFT; - } - - if (OF_getencprop(node, "ingenic,nemc-tAW", &val, sizeof(val)) > 0) { - cycles = JZ4780_NEMC_NS_TO_TICKS(sc, val); - if (cycles > 31) { - device_printf(sc->dev, - "invalid value of %s %u (%u cycles), maximum %u cycles supported\n", - "ingenic,nemc-tAW", val, cycles, 15); - return -1; - } - smcr &= ~JZ_NEMC_SMCR_TAW_MASK; - smcr |= ticks_to_tBP_tAW[cycles] << JZ_NEMC_SMCR_TAW_SHIFT; - } - - if (OF_getencprop(node, "ingenic,nemc-tSTRV", &val, sizeof(val)) > 0) { - cycles = JZ4780_NEMC_NS_TO_TICKS(sc, val); - if (cycles > 63) { - device_printf(sc->dev, - "invalid value of %s %u (%u cycles), maximum %u cycles supported\n", - "ingenic,nemc-tSTRV", val, cycles, 15); - return -1; - } - smcr &= ~JZ_NEMC_SMCR_STRV_MASK; - smcr |= cycles << JZ_NEMC_SMCR_STRV_SHIFT; - } - CSR_WRITE_4(sc, JZ_NEMC_SMCR(bank), smcr); - sc->banks |= (1 << bank); - return 0; -} - -/* Wholesale copy of simplebus routine */ -static int -jz4780_nemc_fill_ranges(phandle_t node, struct simplebus_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 -jz4780_nemc_attach(device_t dev) -{ - struct jz4780_nemc_softc *sc = device_get_softc(dev); - phandle_t node; - uint64_t freq; - - sc->dev = dev; - - if (bus_alloc_resources(dev, jz4780_nemc_spec, sc->res)) { - device_printf(dev, "could not allocate resources for device\n"); - return (ENXIO); - } - - node = ofw_bus_get_node(dev); - - /* Initialize simplebus and enumerate resources */ - simplebus_init(dev, node); - - if (jz4780_nemc_fill_ranges(node, &sc->simplebus_sc) < 0) - goto error; - - /* Figure our underlying clock rate. */ - if (clk_get_by_ofw_index(dev, 0, 0, &sc->clk) != 0) { - device_printf(dev, "could not lookup device clock\n"); - goto error; - } - if (clk_enable(sc->clk) != 0) { - device_printf(dev, "could not enable device clock\n"); - goto error; - } - if (clk_get_freq(sc->clk, &freq) != 0) { - device_printf(dev, "could not determine clock speed\n"); - goto error; - } - - /* Convert clock frequency to picoseconds-per-tick value. */ - sc->clock_tick_psecs = (uint32_t)(1000000000000ULL / freq); - - /* - * Allow devices to identify. - */ - bus_generic_probe(dev); - - /* - * Now walk the tree and attach top level devices - */ - for (node = OF_child(node); node > 0; node = OF_peer(node)) - simplebus_add_device(dev, node, 0, NULL, -1, NULL); - - return (bus_generic_attach(dev)); -error: - jz4780_nemc_detach(dev); - return (ENXIO); -} - -static int -jz4780_nemc_detach(device_t dev) -{ - struct jz4780_nemc_softc *sc = device_get_softc(dev); - - bus_generic_detach(dev); - if (sc->clk != NULL) - clk_release(sc->clk); - bus_release_resources(dev, jz4780_nemc_spec, sc->res); - return (0); -} - -static int -jz4780_nemc_decode_bank(struct simplebus_softc *sc, struct resource *r, - u_int *bank) -{ - rman_res_t start, end; - int i; - - start = rman_get_start(r); - end = rman_get_end(r); - - /* Remap through ranges property */ - for (i = 0; i < sc->nranges; i++) { - if (start >= sc->ranges[i].host && end < - sc->ranges[i].host + sc->ranges[i].size) { - *bank = (sc->ranges[i].bus >> 32); - return (0); - } - } - return (1); -} - -static int -jz4780_nemc_activate_resource(device_t bus, device_t child, int type, int rid, - struct resource *r) -{ - struct jz4780_nemc_softc *sc; - u_int bank; - int err; - - if (type == SYS_RES_MEMORY) { - sc = device_get_softc(bus); - - /* Figure out on what bank device is residing */ - err = jz4780_nemc_decode_bank(&sc->simplebus_sc, r, &bank); - if (err == 0) { - /* Attempt to configure the bank if not done already */ - err = jz4780_nemc_configure_bank(sc, child, bank); - if (err != 0) - return (err); - } - } - - /* Call default implementation to finish the work */ - return (bus_generic_activate_resource(bus, child, - type, rid, r)); -} - -static device_method_t jz4780_nemc_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, jz4780_nemc_probe), - DEVMETHOD(device_attach, jz4780_nemc_attach), - DEVMETHOD(device_detach, jz4780_nemc_detach), - - /* Overrides to configure bank on resource activation */ - DEVMETHOD(bus_activate_resource, jz4780_nemc_activate_resource), - - DEVMETHOD_END -}; - -static devclass_t jz4780_nemc_devclass; -DEFINE_CLASS_1(nemc, jz4780_nemc_driver, jz4780_nemc_methods, - sizeof(struct jz4780_nemc_softc), simplebus_driver); -DRIVER_MODULE(jz4780_nemc, simplebus, jz4780_nemc_driver, - jz4780_nemc_devclass, 0, 0); Index: sys/mips/ingenic/jz4780_ohci.c =================================================================== --- sys/mips/ingenic/jz4780_ohci.c +++ /dev/null @@ -1,318 +0,0 @@ -/*- - * Copyright (c) 2015, Alexander Kabaev - * Copyright (c) 2009, Oleksandr Tymoshenko - * 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 unmodified, 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 - -static int jz4780_ohci_attach(device_t dev); -static int jz4780_ohci_detach(device_t dev); -static int jz4780_ohci_probe(device_t dev); - -struct jz4780_ohci_softc -{ - struct ohci_softc sc_ohci; - struct gpiobus_pin *gpio_vbus; - clk_t clk; -}; - -static int -jz4780_ohci_probe(device_t dev) -{ - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (!ofw_bus_is_compatible(dev, "ingenic,jz4780-ohci")) - return (ENXIO); - - device_set_desc(dev, "Ingenic JZ4780 OHCI"); - - return (BUS_PROBE_DEFAULT); -} - -static int -jz4780_ohci_vbus_gpio_enable(device_t dev, struct jz4780_ohci_softc *sc) -{ - struct gpiobus_pin *gpio_vbus; - int error; - - error = ofw_gpiobus_parse_gpios(dev, "ingenic,vbus-gpio", &gpio_vbus); - /* - * The pin can be mapped already by other device. Assume it also has need - * activated and proceed happily. - */ - if (error <= 0) - return (0); - - sc->gpio_vbus = gpio_vbus; - if (error > 1) { - device_printf(dev, "too many vbus gpios\n"); - return (ENXIO); - } - - if (sc->gpio_vbus != NULL) { - error = GPIO_PIN_SET(sc->gpio_vbus->dev, sc->gpio_vbus->pin, 1); - if (error != 0) { - device_printf(dev, "Cannot configure GPIO pin %d on %s\n", - sc->gpio_vbus->pin, device_get_nameunit(sc->gpio_vbus->dev)); - return (error); - } - - error = GPIO_PIN_SETFLAGS(sc->gpio_vbus->dev, sc->gpio_vbus->pin, - GPIO_PIN_OUTPUT); - if (error != 0) { - device_printf(dev, "Cannot configure GPIO pin %d on %s\n", - sc->gpio_vbus->pin, device_get_nameunit(sc->gpio_vbus->dev)); - return (error); - } - } - return (0); -} - -static int -jz4780_ohci_clk_enable(device_t dev) -{ - struct jz4780_ohci_softc *sc; - int err; - - sc = device_get_softc(dev); - - err = clk_get_by_ofw_index(dev, 0, 0, &sc->clk); - if (err != 0) { - device_printf(dev, "unable to lookup device clock\n"); - return (err); - } - err = clk_enable(sc->clk); - if (err != 0) { - device_printf(dev, "unable to enable device clock\n"); - return (err); - } - err = clk_set_freq(sc->clk, 48000000, 0); - if (err != 0) { - device_printf(dev, "unable to set device clock to 48 kHZ\n"); - return (err); - } - return (0); -} - -static int -jz4780_ohci_attach(device_t dev) -{ - struct jz4780_ohci_softc *sc = device_get_softc(dev); - int err; - int rid; - - /* initialize 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->sc_ohci.sc_dev = dev; - - /* frob vbus gpio */ - err = jz4780_ohci_vbus_gpio_enable(dev, sc); - if (err) - goto error; - - err = jz4780_ohci_clk_enable(dev); - if (err) - goto error; - - rid = 0; - sc->sc_ohci.sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - if (sc->sc_ohci.sc_io_res == NULL) { - 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 == NULL) { - err = ENOMEM; - goto error; - } - - if (jz4780_ohci_enable() != 0) { - device_printf(dev, "CGU failed to enable OHCI\n"); - err = ENXIO; - goto error; - } - - sc->sc_ohci.sc_bus.bdev = device_add_child(dev, "usbus", -1); - if (sc->sc_ohci.sc_bus.bdev == NULL) { - err = ENOMEM; - goto error; - } - device_set_ivars(sc->sc_ohci.sc_bus.bdev, &sc->sc_ohci.sc_bus); - - 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) { - err = ENXIO; - goto error; - } - - strlcpy(sc->sc_ohci.sc_vendor, "Ingenic", sizeof(sc->sc_ohci.sc_vendor)); - 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: - if (err) - jz4780_ohci_detach(dev); - return (err); -} - -static int -jz4780_ohci_detach(device_t dev) -{ - struct jz4780_ohci_softc *sc = device_get_softc(dev); - device_t bdev; - - if (sc->sc_ohci.sc_bus.bdev) { - bdev = sc->sc_ohci.sc_bus.bdev; - device_detach(bdev); - device_delete_child(dev, bdev); - } - /* 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. - */ - if (sc->sc_ohci.sc_io_res != NULL) { - bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl, - OHCI_CONTROL, 0); - } - - if (sc->sc_ohci.sc_intr_hdl) { - 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 && sc->sc_ohci.sc_intr_hdl) { - /* - * only call ohci_detach() after ohci_init() - */ - ohci_detach(&sc->sc_ohci); - - 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, 0, sc->sc_ohci.sc_io_res); - sc->sc_ohci.sc_io_res = NULL; - sc->sc_ohci.sc_io_tag = 0; - sc->sc_ohci.sc_io_hdl = 0; - } - - if (sc->clk != NULL) - clk_release(sc->clk); - - usb_bus_mem_free_all(&sc->sc_ohci.sc_bus, &ohci_iterate_hw_softc); - free(sc->gpio_vbus, M_DEVBUF); - return (0); -} - -static device_method_t ohci_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, jz4780_ohci_probe), - DEVMETHOD(device_attach, jz4780_ohci_attach), - DEVMETHOD(device_detach, jz4780_ohci_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 jz4780_ohci_softc), -}; - -static devclass_t ohci_devclass; - -DRIVER_MODULE(ohci, simplebus, ohci_driver, ohci_devclass, 0, 0); Index: sys/mips/ingenic/jz4780_pdma.h =================================================================== --- sys/mips/ingenic/jz4780_pdma.h +++ /dev/null @@ -1,109 +0,0 @@ -/*- - * Copyright (c) 2016 Ruslan Bukin - * All rights reserved. - * - * This software was developed by SRI International and the University of - * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 - * ("CTSRD"), as part of the DARPA CRASH research programme. - * - * 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$ - */ - -/* DMA Channel Registers */ -#define PDMA_DSA(n) (0x00 + 0x20 * n) /* Channel n Source Address */ -#define PDMA_DTA(n) (0x04 + 0x20 * n) /* Channel n Target Address */ -#define PDMA_DTC(n) (0x08 + 0x20 * n) /* Channel n Transfer Count */ -#define PDMA_DRT(n) (0x0C + 0x20 * n) /* Channel n Request Source */ -#define DRT_AUTO (1 << 3) /* Auto-request. */ -#define PDMA_DCS(n) (0x10 + 0x20 * n) /* Channel n Control/Status */ -#define DCS_NDES (1 << 31) /* Non-descriptor mode. */ -#define DCS_DES8 (1 << 30) /* Descriptor 8 Word. */ -#define DCS_AR (1 << 4) /* Address Error. */ -#define DCS_TT (1 << 3) /* Transfer Terminate. */ -#define DCS_HLT (1 << 2) /* DMA halt. */ -#define DCS_CTE (1 << 0) /* Channel transfer enable. */ -#define PDMA_DCM(n) (0x14 + 0x20 * n) /* Channel n Command */ -#define DCM_SAI (1 << 23) /* Source Address Increment. */ -#define DCM_DAI (1 << 22) /* Destination Address Increment. */ -#define DCM_SP_S 14 /* Source port width. */ -#define DCM_SP_M (0x3 << DCM_SP_S) -#define DCM_SP_1 (0x1 << DCM_SP_S) /* 1 byte */ -#define DCM_SP_2 (0x2 << DCM_SP_S) /* 2 bytes */ -#define DCM_SP_4 (0x0 << DCM_SP_S) /* 4 bytes */ -#define DCM_DP_S 12 /* Destination port width. */ -#define DCM_DP_M (0x3 << DCM_DP_S) -#define DCM_DP_1 (0x1 << DCM_DP_S) /* 1 byte */ -#define DCM_DP_2 (0x2 << DCM_DP_S) /* 2 bytes */ -#define DCM_DP_4 (0x0 << DCM_DP_S) /* 4 bytes */ -#define DCM_TSZ_S 8 /* Transfer Data Size of a data unit. */ -#define DCM_TSZ_M (0x7 << DCM_TSZ_S) -#define DCM_TSZ_A (0x7 << DCM_TSZ_S) /* Autonomy */ -#define DCM_TSZ_1 (0x1 << DCM_TSZ_S) -#define DCM_TSZ_2 (0x2 << DCM_TSZ_S) -#define DCM_TSZ_4 (0x0 << DCM_TSZ_S) -#define DCM_TSZ_16 (0x3 << DCM_TSZ_S) -#define DCM_TSZ_32 (0x4 << DCM_TSZ_S) -#define DCM_TSZ_64 (0x5 << DCM_TSZ_S) -#define DCM_TSZ_128 (0x6 << DCM_TSZ_S) -#define DCM_TIE (1 << 1) /* Transfer Interrupt Enable (TIE). */ -#define DCM_LINK (1 << 0) /* Descriptor Link Enable. */ -#define PDMA_DDA(n) (0x18 + 0x20 * n) /* Channel n Descriptor Address */ -#define PDMA_DSD(n) (0x1C + 0x20 * n) /* Channel n Stride Difference */ - -/* Global Control Registers */ -#define PDMA_DMAC 0x1000 /* DMA Control */ -#define DMAC_FMSC (1 << 31) -#define DMAC_INTCC_S 17 -#define DMAC_INTCC_M (0x1f << DMAC_INTCC_S) -#define DMAC_INTCE (1 << 16) /* Permit INTC_IRQ to be bound to one of programmable channel. */ -#define DMAC_HLT (1 << 3) /* Global halt status */ -#define DMAC_AR (1 << 2) /* Global address error status */ -#define DMAC_DMAE (1 << 0) /* Enable DMA. */ -#define PDMA_DIRQP 0x1004 /* DMA Interrupt Pending */ -#define PDMA_DDB 0x1008 /* DMA Doorbell */ -#define PDMA_DDS 0x100C /* DMA Doorbell Set */ -#define PDMA_DIP 0x1010 /* Descriptor Interrupt Pending */ -#define PDMA_DIC 0x1014 /* Descriptor Interrupt Clear */ -#define PDMA_DMACP 0x101C /* DMA Channel Programmable */ -#define PDMA_DSIRQP 0x1020 /* Channel soft IRQ to MCU */ -#define PDMA_DSIRQM 0x1024 /* Channel soft IRQ mask */ -#define PDMA_DCIRQP 0x1028 /* Channel IRQ to MCU */ -#define PDMA_DCIRQM 0x102C /* Channel IRQ to MCU mask */ -#define PDMA_DMCS 0x1030 /* MCU Control and Status */ -#define PDMA_DMNMB 0x1034 /* MCU Normal Mailbox */ -#define PDMA_DMSMB 0x1038 /* MCU Security Mailbox */ -#define PDMA_DMINT 0x103C /* MCU Interrupt */ - -struct pdma_hwdesc { - uint32_t dcm; /* DMA Channel Command */ - uint32_t dsa; /* DMA Source Address */ - uint32_t dta; /* DMA Target Address */ - uint32_t dtc; /* DMA Transfer Counter */ - uint32_t sd; /* Stride Address */ - uint32_t drt; /* DMA Request Type */ - uint32_t reserved[2]; -}; - -#define CHAN_DESC_COUNT 4096 -#define CHAN_DESC_SIZE (sizeof(struct pdma_hwdesc) * CHAN_DESC_COUNT) Index: sys/mips/ingenic/jz4780_pdma.c =================================================================== --- sys/mips/ingenic/jz4780_pdma.c +++ /dev/null @@ -1,585 +0,0 @@ -/*- - * Copyright (c) 2016-2018 Ruslan Bukin - * All rights reserved. - * - * This software was developed by SRI International and the University of - * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 - * ("CTSRD"), as part of the DARPA CRASH research programme. - * - * 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. - */ - -/* Ingenic JZ4780 PDMA Controller. */ - -#include -__FBSDID("$FreeBSD$"); - -#include "opt_platform.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifdef FDT -#include -#include -#include -#endif - -#include - -#include -#include - -#include "xdma_if.h" - -#define PDMA_DEBUG -#undef PDMA_DEBUG - -#ifdef PDMA_DEBUG -#define dprintf(fmt, ...) printf(fmt, ##__VA_ARGS__) -#else -#define dprintf(fmt, ...) -#endif - -#define PDMA_DESC_RING_ALIGN 2048 - -struct pdma_softc { - device_t dev; - struct resource *res[2]; - bus_space_tag_t bst; - bus_space_handle_t bsh; - void *ih; -}; - -struct pdma_fdt_data { - int tx; - int rx; - int chan; -}; - -struct pdma_channel { - struct pdma_fdt_data data; - int cur_desc; - int used; - int index; - int flags; -#define CHAN_DESCR_RELINK (1 << 0) - - /* Descriptors */ - bus_dma_tag_t desc_tag; - bus_dmamap_t desc_map; - struct pdma_hwdesc *desc_ring; - bus_addr_t desc_ring_paddr; - - /* xDMA */ - xdma_channel_t *xchan; - struct xdma_request *req; -}; - -#define PDMA_NCHANNELS 32 -struct pdma_channel pdma_channels[PDMA_NCHANNELS]; - -static struct resource_spec pdma_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE }, - { SYS_RES_IRQ, 0, RF_ACTIVE }, - { -1, 0 } -}; - -static int pdma_probe(device_t dev); -static int pdma_attach(device_t dev); -static int pdma_detach(device_t dev); -static int chan_start(struct pdma_softc *sc, struct pdma_channel *chan); - -static void -pdma_intr(void *arg) -{ - struct xdma_request *req; - xdma_transfer_status_t status; - struct pdma_channel *chan; - struct pdma_softc *sc; - xdma_channel_t *xchan; - int pending; - int i; - - sc = arg; - - pending = READ4(sc, PDMA_DIRQP); - - /* Ack all the channels. */ - WRITE4(sc, PDMA_DIRQP, 0); - - for (i = 0; i < PDMA_NCHANNELS; i++) { - if (pending & (1 << i)) { - chan = &pdma_channels[i]; - xchan = chan->xchan; - req = chan->req; - - /* TODO: check for AR, HLT error bits here. */ - - /* Disable channel */ - WRITE4(sc, PDMA_DCS(chan->index), 0); - - if (chan->flags & CHAN_DESCR_RELINK) { - /* Enable again */ - chan->cur_desc = (chan->cur_desc + 1) % \ - req->block_num; - chan_start(sc, chan); - } - - status.error = 0; - xdma_callback(chan->xchan, &status); - } - } -} - -static int -pdma_probe(device_t dev) -{ - - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (!ofw_bus_is_compatible(dev, "ingenic,jz4780-dma")) - return (ENXIO); - - device_set_desc(dev, "Ingenic JZ4780 PDMA Controller"); - - return (BUS_PROBE_DEFAULT); -} - -static int -pdma_attach(device_t dev) -{ - struct pdma_softc *sc; - phandle_t xref, node; - int err; - int reg; - - sc = device_get_softc(dev); - sc->dev = dev; - - if (bus_alloc_resources(dev, pdma_spec, sc->res)) { - device_printf(dev, "could not allocate resources for device\n"); - return (ENXIO); - } - - /* Memory interface */ - sc->bst = rman_get_bustag(sc->res[0]); - sc->bsh = rman_get_bushandle(sc->res[0]); - - /* Setup interrupt handler */ - err = bus_setup_intr(dev, sc->res[1], INTR_TYPE_MISC | INTR_MPSAFE, - NULL, pdma_intr, sc, &sc->ih); - if (err) { - device_printf(dev, "Unable to alloc interrupt resource.\n"); - return (ENXIO); - } - - node = ofw_bus_get_node(dev); - xref = OF_xref_from_node(node); - OF_device_register_xref(xref, dev); - - reg = READ4(sc, PDMA_DMAC); - reg &= ~(DMAC_HLT | DMAC_AR); - reg |= (DMAC_DMAE); - WRITE4(sc, PDMA_DMAC, reg); - - WRITE4(sc, PDMA_DMACP, 0); - - return (0); -} - -static int -pdma_detach(device_t dev) -{ - struct pdma_softc *sc; - - sc = device_get_softc(dev); - - bus_release_resources(dev, pdma_spec, sc->res); - - return (0); -} - -static int -chan_start(struct pdma_softc *sc, struct pdma_channel *chan) -{ - struct xdma_channel *xchan; - - xchan = chan->xchan; - - /* 8 byte descriptor. */ - WRITE4(sc, PDMA_DCS(chan->index), DCS_DES8); - WRITE4(sc, PDMA_DDA(chan->index), - chan->desc_ring_paddr + 8 * 4 * chan->cur_desc); - - WRITE4(sc, PDMA_DDS, (1 << chan->index)); - - /* Channel transfer enable. */ - WRITE4(sc, PDMA_DCS(chan->index), (DCS_DES8 | DCS_CTE)); - - return (0); -} - -static int -chan_stop(struct pdma_softc *sc, struct pdma_channel *chan) -{ - int timeout; - - WRITE4(sc, PDMA_DCS(chan->index), 0); - - timeout = 100; - - do { - if ((READ4(sc, PDMA_DCS(chan->index)) & DCS_CTE) == 0) { - break; - } - } while (timeout--); - - if (timeout == 0) { - device_printf(sc->dev, "%s: Can't stop channel %d\n", - __func__, chan->index); - } - - return (0); -} - -static void -dwc_get1paddr(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 -pdma_channel_setup_descriptors(device_t dev, struct pdma_channel *chan) -{ - struct pdma_softc *sc; - int error; - - sc = device_get_softc(dev); - - /* - * Set up TX descriptor ring, descriptors, and dma maps. - */ - error = bus_dma_tag_create( - bus_get_dma_tag(sc->dev), /* Parent tag. */ - PDMA_DESC_RING_ALIGN, 0, /* alignment, boundary */ - BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filter, filterarg */ - CHAN_DESC_SIZE, 1, /* maxsize, nsegments */ - CHAN_DESC_SIZE, /* maxsegsize */ - 0, /* flags */ - NULL, NULL, /* lockfunc, lockarg */ - &chan->desc_tag); - if (error != 0) { - device_printf(sc->dev, - "could not create TX ring DMA tag.\n"); - return (-1); - } - - error = bus_dmamem_alloc(chan->desc_tag, (void**)&chan->desc_ring, - BUS_DMA_COHERENT | BUS_DMA_WAITOK | BUS_DMA_ZERO, - &chan->desc_map); - if (error != 0) { - device_printf(sc->dev, - "could not allocate TX descriptor ring.\n"); - return (-1); - } - - error = bus_dmamap_load(chan->desc_tag, chan->desc_map, - chan->desc_ring, CHAN_DESC_SIZE, dwc_get1paddr, - &chan->desc_ring_paddr, 0); - if (error != 0) { - device_printf(sc->dev, - "could not load TX descriptor ring map.\n"); - return (-1); - } - - return (0); -} - -static int -pdma_channel_alloc(device_t dev, struct xdma_channel *xchan) -{ - struct pdma_channel *chan; - struct pdma_softc *sc; - int i; - - sc = device_get_softc(dev); - - for (i = 0; i < PDMA_NCHANNELS; i++) { - chan = &pdma_channels[i]; - if (chan->used == 0) { - chan->xchan = xchan; - xchan->chan = (void *)chan; - chan->used = 1; - chan->index = i; - - pdma_channel_setup_descriptors(dev, chan); - - return (0); - } - } - - return (-1); -} - -static int -pdma_channel_free(device_t dev, struct xdma_channel *xchan) -{ - struct pdma_channel *chan; - struct pdma_softc *sc; - - sc = device_get_softc(dev); - - chan = (struct pdma_channel *)xchan->chan; - chan->used = 0; - - return (0); -} - -static int -access_width(struct xdma_request *req, uint32_t *dcm, uint32_t *max_width) -{ - - *dcm = 0; - *max_width = max(req->src_width, req->dst_width); - - switch (req->src_width) { - case 1: - *dcm |= DCM_SP_1; - break; - case 2: - *dcm |= DCM_SP_2; - break; - case 4: - *dcm |= DCM_SP_4; - break; - default: - return (-1); - } - - switch (req->dst_width) { - case 1: - *dcm |= DCM_DP_1; - break; - case 2: - *dcm |= DCM_DP_2; - break; - case 4: - *dcm |= DCM_DP_4; - break; - default: - return (-1); - } - - switch (*max_width) { - case 1: - *dcm |= DCM_TSZ_1; - break; - case 2: - *dcm |= DCM_TSZ_2; - break; - case 4: - *dcm |= DCM_TSZ_4; - break; - default: - return (-1); - }; - - return (0); -} - -static int -pdma_channel_request(device_t dev, struct xdma_channel *xchan, struct xdma_request *req) -{ - struct pdma_fdt_data *data; - struct pdma_channel *chan; - struct pdma_hwdesc *desc; - xdma_controller_t *xdma; - struct pdma_softc *sc; - int max_width; - uint32_t reg; - uint32_t dcm; - int i; - - sc = device_get_softc(dev); - - dprintf("%s: block_len %d block_num %d\n", - __func__, req->block_len, req->block_num); - - xdma = xchan->xdma; - data = (struct pdma_fdt_data *)xdma->data; - - chan = (struct pdma_channel *)xchan->chan; - /* Ensure we are not in operation */ - chan_stop(sc, chan); - if (req->operation == XDMA_CYCLIC) - chan->flags = CHAN_DESCR_RELINK; - chan->cur_desc = 0; - chan->req = req; - - for (i = 0; i < req->block_num; i++) { - desc = &chan->desc_ring[i]; - - if (req->direction == XDMA_MEM_TO_DEV) { - desc->dsa = req->src_addr + (i * req->block_len); - desc->dta = req->dst_addr; - desc->drt = data->tx; - desc->dcm = DCM_SAI; - } else if (req->direction == XDMA_DEV_TO_MEM) { - desc->dsa = req->src_addr; - desc->dta = req->dst_addr + (i * req->block_len); - desc->drt = data->rx; - desc->dcm = DCM_DAI; - } else if (req->direction == XDMA_MEM_TO_MEM) { - desc->dsa = req->src_addr + (i * req->block_len); - desc->dta = req->dst_addr + (i * req->block_len); - desc->drt = DRT_AUTO; - desc->dcm = DCM_SAI | DCM_DAI; - } - - if (access_width(req, &dcm, &max_width) != 0) { - device_printf(dev, - "%s: can't configure access width\n", __func__); - return (-1); - } - - desc->dcm |= dcm | DCM_TIE; - desc->dtc = (req->block_len / max_width); - - /* - * TODO: bus dma pre read/write sync here - */ - - /* - * PDMA does not provide interrupt after processing each descriptor, - * but after processing all the chain only. - * As a workaround we do unlink descriptors here, so our chain will - * consists of single descriptor only. And then we reconfigure channel - * on each interrupt again. - */ - if ((chan->flags & CHAN_DESCR_RELINK) == 0) { - if (i != (req->block_num - 1)) { - desc->dcm |= DCM_LINK; - reg = ((i + 1) * sizeof(struct pdma_hwdesc)); - desc->dtc |= (reg >> 4) << 24; - } - } - } - - return (0); -} - -static int -pdma_channel_control(device_t dev, xdma_channel_t *xchan, int cmd) -{ - struct pdma_channel *chan; - struct pdma_softc *sc; - - sc = device_get_softc(dev); - - chan = (struct pdma_channel *)xchan->chan; - - switch (cmd) { - case XDMA_CMD_BEGIN: - chan_start(sc, chan); - break; - case XDMA_CMD_TERMINATE: - chan_stop(sc, chan); - break; - case XDMA_CMD_PAUSE: - /* TODO: implement me */ - return (-1); - } - - return (0); -} - -#ifdef FDT -static int -pdma_ofw_md_data(device_t dev, pcell_t *cells, int ncells, void **ptr) -{ - struct pdma_fdt_data *data; - - if (ncells != 3) { - return (-1); - } - - data = malloc(sizeof(struct pdma_fdt_data), M_DEVBUF, (M_WAITOK | M_ZERO)); - if (data == NULL) { - device_printf(dev, "%s: Cant allocate memory\n", __func__); - return (-1); - } - - data->tx = cells[0]; - data->rx = cells[1]; - data->chan = cells[2]; - - *ptr = data; - - return (0); -} -#endif - -static device_method_t pdma_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, pdma_probe), - DEVMETHOD(device_attach, pdma_attach), - DEVMETHOD(device_detach, pdma_detach), - - /* xDMA Interface */ - DEVMETHOD(xdma_channel_alloc, pdma_channel_alloc), - DEVMETHOD(xdma_channel_free, pdma_channel_free), - DEVMETHOD(xdma_channel_request, pdma_channel_request), - DEVMETHOD(xdma_channel_control, pdma_channel_control), -#ifdef FDT - DEVMETHOD(xdma_ofw_md_data, pdma_ofw_md_data), -#endif - - DEVMETHOD_END -}; - -static driver_t pdma_driver = { - "pdma", - pdma_methods, - sizeof(struct pdma_softc), -}; - -static devclass_t pdma_devclass; - -EARLY_DRIVER_MODULE(pdma, simplebus, pdma_driver, pdma_devclass, 0, 0, - BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE); Index: sys/mips/ingenic/jz4780_pinctrl.h =================================================================== --- sys/mips/ingenic/jz4780_pinctrl.h +++ /dev/null @@ -1,33 +0,0 @@ -/*- - * Copyright 2015 Alexander Kabaev - * 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 _MIPS_INGENIC_JZ4780_PINCTRL_H -#define _MIPS_INGENIC_JZ4780_PINCTRL_H - - -#endif /* _MIPS_INGENIC_JZ4780_PINCTRL_H */ Index: sys/mips/ingenic/jz4780_pinctrl.c =================================================================== --- sys/mips/ingenic/jz4780_pinctrl.c +++ /dev/null @@ -1,260 +0,0 @@ -/*- - * Copyright 2015 Alexander Kabaev - * 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. - */ - -/* - * Ingenic JZ4780 pinctrl driver. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include - -#include - -#include "jz4780_gpio_if.h" - -struct jz4780_pinctrl_softc { - struct simplebus_softc ssc; - device_t dev; -}; - -#define CHIP_REG_STRIDE 256 -#define CHIP_REG_OFFSET(base, chip) ((base) + (chip) * CHIP_REG_STRIDE) - -static int -jz4780_pinctrl_probe(device_t dev) -{ - - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (!ofw_bus_is_compatible(dev, "ingenic,jz4780-pinctrl")) - return (ENXIO); - - device_set_desc(dev, "Ingenic JZ4780 GPIO"); - - return (BUS_PROBE_DEFAULT); -} - -static int -jz4780_pinctrl_attach(device_t dev) -{ - struct jz4780_pinctrl_softc *sc; - struct resource_list *rs; - struct resource_list_entry *re; - phandle_t dt_parent, dt_child; - int i, ret; - - sc = device_get_softc(dev); - sc->dev = dev; - - /* - * Fetch our own resource list to dole memory between children - */ - rs = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev); - if (rs == NULL) - return (ENXIO); - re = resource_list_find(rs, SYS_RES_MEMORY, 0); - if (re == NULL) - return (ENXIO); - - simplebus_init(dev, 0); - - /* Iterate over this node children, looking for pin controllers */ - dt_parent = ofw_bus_get_node(dev); - i = 0; - for (dt_child = OF_child(dt_parent); dt_child != 0; - dt_child = OF_peer(dt_child)) { - struct simplebus_devinfo *ndi; - device_t child; - bus_addr_t phys; - bus_size_t size; - - /* Add gpio controller child */ - if (!OF_hasprop(dt_child, "gpio-controller")) - continue; - child = simplebus_add_device(dev, dt_child, 0, NULL, -1, NULL); - if (child == NULL) - break; - /* Setup child resources */ - phys = CHIP_REG_OFFSET(re->start, i); - size = CHIP_REG_STRIDE; - if (phys + size - 1 <= re->end) { - ndi = device_get_ivars(child); - resource_list_add(&ndi->rl, SYS_RES_MEMORY, 0, - phys, phys + size - 1, size); - } - i++; - } - - ret = bus_generic_attach(dev); - if (ret == 0) { - fdt_pinctrl_register(dev, "ingenic,pins"); - fdt_pinctrl_configure_tree(dev); - } - return (ret); -} - -static int -jz4780_pinctrl_detach(device_t dev) -{ - - bus_generic_detach(dev); - return (0); -} - -struct jx4780_bias_prop { - const char *name; - uint32_t bias; -}; - -static struct jx4780_bias_prop jx4780_bias_table[] = { - { "bias-disable", 0 }, - { "bias-pull-up", GPIO_PIN_PULLUP }, - { "bias-pull-down", GPIO_PIN_PULLDOWN }, -}; - -static int -jz4780_pinctrl_parse_pincfg(phandle_t pincfgxref, uint32_t *bias_value) -{ - phandle_t pincfg_node; - int i; - - pincfg_node = OF_node_from_xref(pincfgxref); - for (i = 0; i < nitems(jx4780_bias_table); i++) { - if (OF_hasprop(pincfg_node, jx4780_bias_table[i].name)) { - *bias_value = jx4780_bias_table[i].bias; - return 0; - } - } - - return -1; -} - -static device_t -jz4780_pinctrl_chip_lookup(struct jz4780_pinctrl_softc *sc, phandle_t chipxref) -{ - device_t chipdev; - - chipdev = OF_device_from_xref(chipxref); - return chipdev; -} - -static int -jz4780_pinctrl_configure_pins(device_t dev, phandle_t cfgxref) -{ - struct jz4780_pinctrl_softc *sc = device_get_softc(dev); - device_t chip; - phandle_t node; - ssize_t i, len; - uint32_t *value, *pconf; - int result; - - node = OF_node_from_xref(cfgxref); - - len = OF_getencprop_alloc_multi(node, "ingenic,pins", - sizeof(uint32_t) * 4, (void **)&value); - if (len < 0) { - device_printf(dev, - "missing ingenic,pins attribute in FDT\n"); - return (ENXIO); - } - - pconf = value; - result = EINVAL; - for (i = 0; i < len; i++, pconf += 4) { - uint32_t bias; - - /* Lookup the chip that handles this configuration */ - chip = jz4780_pinctrl_chip_lookup(sc, pconf[0]); - if (chip == NULL) { - device_printf(dev, - "invalid gpio controller reference in FDT\n"); - goto done; - } - - if (jz4780_pinctrl_parse_pincfg(pconf[3], &bias) != 0) { - device_printf(dev, - "invalid pin bias for pin %u on %s in FDT\n", - pconf[1], ofw_bus_get_name(chip)); - goto done; - } - - result = JZ4780_GPIO_CONFIGURE_PIN(chip, pconf[1], pconf[2], - bias); - if (result != 0) { - device_printf(dev, - "failed to configure pin %u on %s\n", pconf[1], - ofw_bus_get_name(chip)); - goto done; - } - } - - result = 0; -done: - free(value, M_OFWPROP); - return (result); -} - - -static device_method_t jz4780_pinctrl_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, jz4780_pinctrl_probe), - DEVMETHOD(device_attach, jz4780_pinctrl_attach), - DEVMETHOD(device_detach, jz4780_pinctrl_detach), - - /* fdt_pinctrl interface */ - DEVMETHOD(fdt_pinctrl_configure, jz4780_pinctrl_configure_pins), - - DEVMETHOD_END -}; - -static devclass_t jz4780_pinctrl_devclass; -DEFINE_CLASS_1(pinctrl, jz4780_pinctrl_driver, jz4780_pinctrl_methods, - sizeof(struct jz4780_pinctrl_softc), simplebus_driver); -EARLY_DRIVER_MODULE(pinctrl, simplebus, jz4780_pinctrl_driver, - jz4780_pinctrl_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE); Index: sys/mips/ingenic/jz4780_regs.h =================================================================== --- sys/mips/ingenic/jz4780_regs.h +++ /dev/null @@ -1,787 +0,0 @@ -/* $NetBSD: ingenic_regs.h,v 1.22 2015/10/08 17:54:30 macallan Exp $ */ - -/*- - * Copyright (c) 2014 Michael Lorenz - * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef JZ4780_REGS_H -#define JZ4780_REGS_H - -/* for mips_wbflush() */ -#include - -/* UARTs, mostly 16550 compatible with 32bit spaced registers */ -#define JZ_UART0 0x10030000 -#define JZ_UART1 0x10031000 -#define JZ_UART2 0x10032000 -#define JZ_UART3 0x10033000 -#define JZ_UART4 0x10034000 - -/* LCD controller base addresses, registers are in jzfb_regs.h */ -#define JZ_LCDC0_BASE 0x13050000 -#define JZ_LCDC1_BASE 0x130a0000 - -/* TCU unit base address */ -#define JZ_TCU_BASE 0x10002000 - -/* Watchdog */ -#define JZ_WDOG_TDR 0x00000000 /* compare */ -#define JZ_WDOG_TCER 0x00000004 - #define TCER_ENABLE 0x01 /* enable counter */ -#define JZ_WDOG_TCNT 0x00000008 /* 16bit up count */ -#define JZ_WDOG_TCSR 0x0000000c - #define TCSR_PCK_EN 0x01 /* PCLK */ - #define TCSR_RTC_EN 0x02 /* RTCCLK - 32.768kHz */ - #define TCSR_EXT_EN 0x04 /* EXTCLK - 48MHz */ - #define TCSR_PRESCALE_M 0x38 - #define TCSR_DIV_1 0x00 - #define TCSR_DIV_4 0x08 - #define TCSR_DIV_16 0x10 - #define TCSR_DIV_64 0x18 - #define TCSR_DIV_256 0x20 - #define TCSR_DIV_1024 0x28 - -/* timers and PWMs */ -#define JZ_TC_TER 0x00000010 /* TC enable reg, ro */ -#define JZ_TC_TESR 0x00000014 /* TC enable set reg. */ - #define TESR_TCST0 0x0001 /* enable counter 0 */ - #define TESR_TCST1 0x0002 /* enable counter 1 */ - #define TESR_TCST2 0x0004 /* enable counter 2 */ - #define TESR_TCST3 0x0008 /* enable counter 3 */ - #define TESR_TCST4 0x0010 /* enable counter 4 */ - #define TESR_TCST5 0x0020 /* enable counter 5 */ - #define TESR_TCST6 0x0040 /* enable counter 6 */ - #define TESR_TCST7 0x0080 /* enable counter 7 */ - #define TESR_OST 0x8000 /* enable OST */ -#define JZ_TC_TECR 0x00000018 /* TC enable clear reg. */ -#define JZ_TC_TFR 0x00000020 - #define TFR_FFLAG0 0x00000001 /* channel 0 */ - #define TFR_FFLAG1 0x00000002 /* channel 1 */ - #define TFR_FFLAG2 0x00000004 /* channel 2 */ - #define TFR_FFLAG3 0x00000008 /* channel 3 */ - #define TFR_FFLAG4 0x00000010 /* channel 4 */ - #define TFR_FFLAG5 0x00000020 /* channel 5 */ - #define TFR_FFLAG6 0x00000040 /* channel 6 */ - #define TFR_FFLAG7 0x00000080 /* channel 7 */ - #define TFR_OSTFLAG 0x00008000 /* OS timer */ -#define JZ_TC_TFSR 0x00000024 /* timer flag set */ -#define JZ_TC_TFCR 0x00000028 /* timer flag clear */ -#define JZ_TC_TMR 0x00000030 /* timer flag mask */ - #define TMR_FMASK(n) (1 << (n)) - #define TMR_HMASK(n) (1 << ((n) + 16)) -#define JZ_TC_TMSR 0x00000034 /* timer flag mask set */ -#define JZ_TC_TMCR 0x00000038 /* timer flag mask clear*/ - -#define JZ_TC_TDFR(n) (0x00000040 + (n * 0x10)) /* FULL compare */ -#define JZ_TC_TDHR(n) (0x00000044 + (n * 0x10)) /* HALF compare */ -#define JZ_TC_TCNT(n) (0x00000048 + (n * 0x10)) /* count */ - -#define JZ_TC_TCSR(n) (0x0000004c + (n * 0x10)) -/* same bits as in JZ_WDOG_TCSR */ - -/* operating system timer */ -#define JZ_OST_DATA 0x000000e0 /* compare */ -#define JZ_OST_CNT_LO 0x000000e4 -#define JZ_OST_CNT_HI 0x000000e8 -#define JZ_OST_CTRL 0x000000ec - #define OSTC_PCK_EN 0x0001 /* use PCLK */ - #define OSTC_RTC_EN 0x0002 /* use RTCCLK */ - #define OSTC_EXT_EN 0x0004 /* use EXTCLK */ - #define OSTC_PRESCALE_M 0x0038 - #define OSTC_DIV_1 0x0000 - #define OSTC_DIV_4 0x0008 - #define OSTC_DIV_16 0x0010 - #define OSTC_DIV_64 0x0018 - #define OSTC_DIV_256 0x0020 - #define OSTC_DIV_1024 0x0028 - #define OSTC_SHUTDOWN 0x0200 - #define OSTC_MODE 0x8000 /* 0 - reset to 0 when = OST_DATA */ -#define JZ_OST_CNT_U32 0x000000fc /* copy of CNT_HI when reading CNT_LO */ - -static inline void -writereg(uint32_t reg, uint32_t val) -{ - *(volatile int32_t *)MIPS_PHYS_TO_KSEG1(reg) = val; - mips_wbflush(); -} - -static inline uint32_t -readreg(uint32_t reg) -{ - mips_wbflush(); - return *(volatile int32_t *)MIPS_PHYS_TO_KSEG1(reg); -} - -/* Clock management */ -#define JZ_CGU_BASE 0x10000000 - -#define JZ_CPCCR 0x00000000 /* Clock Control Register */ - #define JZ_PDIV_M 0x000f0000 /* PCLK divider mask */ - #define JZ_PDIV_S 16 /* PCLK divider shift */ - #define JZ_CDIV_M 0x0000000f /* CPU clock divider mask */ - #define JZ_CDIV_S 0 /* CPU clock divider shift */ -#define JZ_CPAPCR 0x00000010 /* APLL */ -#define JZ_CPMPCR 0x00000014 /* MPLL */ -#define JZ_CPEPCR 0x00000018 /* EPLL */ -#define JZ_CPVPCR 0x0000001C /* VPLL */ - #define JZ_PLLM_S 19 /* PLL multiplier shift */ - #define JZ_PLLM_M 0xfff80000 /* PLL multiplier mask */ - #define JZ_PLLN_S 13 /* PLL divider shift */ - #define JZ_PLLN_M 0x0007e000 /* PLL divider mask */ - #define JZ_PLLP_S 9 /* PLL postdivider shift */ - #define JZ_PLLP_M 0x00001700 /* PLL postdivider mask */ - #define JZ_PLLON 0x00000010 /* PLL is on and stable */ - #define JZ_PLLBP 0x00000002 /* PLL bypass */ - #define JZ_PLLEN 0x00000001 /* PLL enable */ -#define JZ_CLKGR0 0x00000020 /* Clock Gating Registers */ - #define CLK_NEMC (1 << 0) - #define CLK_BCH (1 << 1) - #define CLK_OTG0 (1 << 2) - #define CLK_MSC0 (1 << 3) - #define CLK_SSI0 (1 << 4) - #define CLK_SMB0 (1 << 5) - #define CLK_SMB1 (1 << 6) - #define CLK_SCC (1 << 7) - #define CLK_AIC (1 << 8) - #define CLK_TSSI0 (1 << 9) - #define CLK_OWI (1 << 10) - #define CLK_MSC1 (1 << 11) - #define CLK_MSC2 (1 << 12) - #define CLK_KBC (1 << 13) - #define CLK_SADC (1 << 14) - #define CLK_UART0 (1 << 15) - #define CLK_UART1 (1 << 16) - #define CLK_UART2 (1 << 17) - #define CLK_UART3 (1 << 18) - #define CLK_SSI1 (1 << 19) - #define CLK_SSI2 (1 << 20) - #define CLK_PDMA (1 << 21) - #define CLK_GPS (1 << 22) - #define CLK_MAC (1 << 23) - #define CLK_UHC (1 << 24) - #define CLK_SMB2 (1 << 25) - #define CLK_CIM (1 << 26) - #define CLK_TVE (1 << 27) - #define CLK_LCD (1 << 28) - #define CLK_IPU (1 << 29) - #define CLK_DDR0 (1 << 30) - #define CLK_DDR1 (1 << 31) -#define JZ_CLKGR1 0x00000028 /* Clock Gating Registers */ - #define CLK_SMB3 (1 << 0) - #define CLK_TSSI1 (1 << 1) - #define CLK_VPU (1 << 2) - #define CLK_PCM (1 << 3) - #define CLK_GPU (1 << 4) - #define CLK_COMPRESS (1 << 5) - #define CLK_AIC1 (1 << 6) - #define CLK_GPVLC (1 << 7) - #define CLK_OTG1 (1 << 8) - #define CLK_HDMI (1 << 9) - #define CLK_UART4 (1 << 10) - #define CLK_AHB_MON (1 << 11) - #define CLK_SMB4 (1 << 12) - #define CLK_DES (1 << 13) - #define CLK_X2D (1 << 14) - #define CLK_P1 (1 << 15) -#define JZ_DDCDR 0x0000002c /* DDR clock divider register */ -#define JZ_VPUCDR 0x00000030 /* VPU clock divider register */ -#define JZ_I2SCDR 0x00000060 /* I2S device clock divider register */ -#define JZ_I2S1CDR 0x000000a0 /* I2S device clock divider register */ -#define JZ_USBCDR 0x00000050 /* OTG PHY clock divider register */ -#define JZ_LP0CDR 0x00000054 /* LCD0 pix clock divider register */ -#define JZ_LP1CDR 0x00000064 /* LCD1 pix clock divider register */ -#define JZ_MSC0CDR 0x00000068 /* MSC0 clock divider register */ -#define JZ_MSC1CDR 0x000000a4 /* MSC1 clock divider register */ -#define JZ_MSC2CDR 0x000000a8 /* MSC2 clock divider register */ - #define MSCCDR_SCLK_A 0x40000000 - #define MSCCDR_MPLL 0x80000000 - #define MSCCDR_CE 0x20000000 - #define MSCCDR_BUSY 0x10000000 - #define MSCCDR_STOP 0x08000000 - #define MSCCDR_PHASE 0x00008000 /* 0 - 90deg phase, 1 - 180 */ - #define MSCCDR_DIV_M 0x000000ff /* src / ((div + 1) * 2) */ - #define UHCCDR_DIV_M 0x000000ff -#define JZ_UHCCDR 0x0000006c /* UHC 48M clock divider register */ - #define UHCCDR_SCLK_A 0x00000000 - #define UHCCDR_MPLL 0x40000000 - #define UHCCDR_EPLL 0x80000000 - #define UHCCDR_OTG_PHY 0xc0000000 - #define UHCCDR_CLK_MASK 0xc0000000 - #define UHCCDR_CE 0x20000000 - #define UHCCDR_BUSY 0x10000000 - #define UHCCDR_STOP 0x08000000 - #define UHCCDR_DIV_M 0x000000ff - #define UHCCDR_DIV(d) (d) -#define JZ_SSICDR 0x00000074 /* SSI clock divider register */ -#define JZ_CIMCDR 0x0000007c /* CIM MCLK clock divider register */ -#define JZ_PCMCDR 0x00000084 /* PCM device clock divider register */ -#define JZ_GPUCDR 0x00000088 /* GPU clock divider register */ -#define JZ_HDMICDR 0x0000008c /* HDMI clock divider register */ -#define JZ_BCHCDR 0x000000ac /* BCH clock divider register */ -#define JZ_CPM_INTR 0x000000b0 /* CPM interrupt register */ -#define JZ_CPM_INTRE 0x000000b4 /* CPM interrupt enable register */ -#define JZ_CPSPR 0x00000034 /* CPM scratch register */ -#define JZ_CPSRPR 0x00000038 /* CPM scratch protected register */ -#define JZ_USBPCR 0x0000003c /* USB parameter control register */ - #define PCR_USB_MODE 0x80000000 /* 1 - otg */ - #define PCR_AVLD_REG 0x40000000 - #define PCR_IDPULLUP_MASK 0x30000000 - #define PCR_INCR_MASK 0x08000000 - #define PCR_TCRISETUNE 0x04000000 - #define PCR_COMMONONN 0x02000000 - #define PCR_VBUSVLDEXT 0x01000000 - #define PCR_VBUSVLDEXTSEL 0x00800000 - #define PCR_POR 0x00400000 - #define PCR_SIDDQ 0x00200000 - #define PCR_OTG_DISABLE 0x00100000 - #define PCR_COMPDISTN_M 0x000e0000 - #define PCR_OTGTUNE 0x0001c000 - #define PCR_SQRXTUNE 0x00003800 - #define PCR_TXFSLSTUNE 0x00000780 - #define PCR_TXPREEMPHTUNE 0x00000040 - #define PCR_TXHSXVTUNE 0x00000030 - #define PCR_TXVREFTUNE 0x0000000f -#define JZ_USBRDT 0x00000040 /* Reset detect timer register */ - #define USBRDT_USBRDT_SHIFT 0 - #define USBRDT_USBRDT_WIDTH 23 - #define USBRDT_VBFIL_LD_EN 0x01000000 -#define JZ_USBVBFIL 0x00000044 /* USB jitter filter register */ - #define USBVBFIL_IDDIGFIL_SHIFT 16 - #define USBVBFIL_IDDIGFIL_WIDTH 16 - #define USBVBFIL_USBVBFIL_SHIFT 0 - #define USBVBFIL_USBVBFIL_WIDTH 16 -#define JZ_USBPCR1 0x00000048 /* USB parameter control register 1 */ - #define PCR_SYNOPSYS 0x10000000 /* Mentor mode otherwise */ - #define PCR_REFCLK_CORE 0x08000000 - #define PCR_REFCLK_XO25 0x04000000 - #define PCR_REFCLK_CO 0x00000000 - #define PCR_REFCLK_M 0x0c000000 - #define PCR_CLK_M 0x03000000 /* clock */ - #define PCR_CLK_192 0x03000000 /* 19.2MHz */ - #define PCR_CLK_48 0x02000000 /* 48MHz */ - #define PCR_CLK_24 0x01000000 /* 24MHz */ - #define PCR_CLK_12 0x00000000 /* 12MHz */ - #define PCR_DMPD1 0x00800000 /* pull down D- on port 1 */ - #define PCR_DPPD1 0x00400000 /* pull down D+ on port 1 */ - #define PCR_PORT0_RST 0x00200000 /* port 0 reset */ - #define PCR_PORT1_RST 0x00100000 /* port 1 reset */ - #define PCR_WORD_I_F0 0x00080000 /* 1: 16bit/30M, 8/60 otherw. */ - #define PCR_WORD_I_F1 0x00040000 /* same for port 1 */ - #define PCR_COMPDISTUNE 0x00038000 /* disconnect threshold */ - #define PCR_SQRXTUNE1 0x00007000 /* squelch threshold */ - #define PCR_TXFSLSTUNE1 0x00000f00 /* FS/LS impedance adj. */ - #define PCR_TXPREEMPH 0x00000080 /* HS transm. pre-emphasis */ - #define PCR_TXHSXVTUNE1 0x00000060 /* dp/dm voltage adj. */ - #define PCR_TXVREFTUNE1 0x00000017 /* HS DC voltage adj. */ - #define PCR_TXRISETUNE1 0x00000001 /* rise/fall wave adj. */ - -/* power manager */ -#define JZ_LPCR 0x00000004 - #define LPCR_PD_SCPU (1u << 31) /* CPU1 power down */ - #define LPCR_PD_VPU (1u << 30) /* VPU power down */ - #define LPCR_PD_GPU (1u << 29) /* GPU power down */ - #define LPCR_PD_GPS (1u << 28) /* GPS power down */ - #define LPCR_SCPUS (1u << 27) /* CPU1 power down status */ - #define LPCR_VPUS (1u << 26) /* VPU power down status */ - #define LPCR_GPUS (1u << 25) /* GPU power down status */ - #define LPCR_GPSS (1u << 24) /* GPS power down status */ - #define LPCR_GPU_IDLE (1u << 20) /* GPU idle status */ - #define LPCR_PST_SHIFT 8 /* Power stability time */ - #define LPCR_PST_MASK (0xFFFu << 8) - #define LPCR_DUTY_SHIFT 3 /* CPU clock duty */ - #define LPCR_DUTY_MASK (0x1Fu << 3) - #define LPCR_DOZE (1u << 2) /* Doze mode */ - #define LPCR_LPM_SHIFT 0 /* Low power mode */ - #define LPCR_LPM_MASK (0x03u << 0) - -#define JZ_OPCR 0x00000024 /* Oscillator Power Control Reg. */ - #define OPCR_IDLE_DIS 0x80000000 /* don't stop CPU clk on idle */ - #define OPCR_GPU_CLK_ST 0x40000000 /* stop GPU clock */ - #define OPCR_L2CM_M 0x0c000000 - #define OPCR_L2CM_ON 0x00000000 /* L2 stays on in sleep */ - #define OPCR_L2CM_RET 0x04000000 /* L2 retention mode in sleep */ - #define OPCR_L2CM_OFF 0x08000000 /* L2 powers down in sleep */ - #define OPCR_SPENDN0 0x00000080 /* 0 - OTG port forced down */ - #define OPCR_SPENDN1 0x00000040 /* 0 - UHC port forced down */ - #define OPCR_BUS_MODE 0x00000020 /* 1 - bursts */ - #define OPCR_O1SE 0x00000010 /* EXTCLK on in sleep */ - #define OPCR_PD 0x00000008 /* P0 down in sleep */ - #define OPCR_ERCS 0x00000004 /* 1 RTCCLK, 0 EXTCLK/512 */ - #define OPCR_CPU_MODE 0x00000002 /* 1 access 'accelerated' */ - #define OPCR_OSE 0x00000001 /* disable EXTCLK */ - -#define JZ_SPCR0 0x000000b8 /* SRAM Power Control Registers */ -#define JZ_SPCR1 0x000000bc -#define JZ_SRBC 0x000000c4 /* Soft Reset & Bus Control */ - #define SRBC_UHC_SR 0x00004000 /* UHC soft reset*/ - -/* - * random number generator - * - * Its function currently isn't documented by Ingenic. - * However, testing suggests that it works as expected. - */ -#define JZ_ERNG 0x000000d8 -#define JZ_RNG 0x000000dc - -/* Interrupt controller */ -#define JZ_ICBASE 0x10001000 /* IC base address */ -#define JZ_ICSR0 0x00000000 /* raw IRQ line status */ -#define JZ_ICMR0 0x00000004 /* IRQ mask, 1 masks IRQ */ -#define JZ_ICMSR0 0x00000008 /* sets bits in mask register */ -#define JZ_ICMCR0 0x0000000c /* clears bits in mask register */ -#define JZ_ICPR0 0x00000010 /* line status after masking */ - -#define JZ_ICSR1 0x00000020 /* raw IRQ line status */ -#define JZ_ICMR1 0x00000024 /* IRQ mask, 1 masks IRQ */ -#define JZ_ICMSR1 0x00000028 /* sets bits in mask register */ -#define JZ_ICMCR1 0x0000002c /* clears bits in maks register */ -#define JZ_ICPR1 0x00000030 /* line status after masking */ - -#define JZ_DSR0 0x00000034 /* source for PDMA */ -#define JZ_DMR0 0x00000038 /* mask for PDMA */ -#define JZ_DPR0 0x0000003c /* pending for PDMA */ - -#define JZ_DSR1 0x00000040 /* source for PDMA */ -#define JZ_DMR1 0x00000044 /* mask for PDMA */ -#define JZ_DPR1 0x00000048 /* pending for PDMA */ - -/* memory controller */ -#define JZ_DMMAP0 0x13010024 -#define JZ_DMMAP1 0x13010028 - #define DMMAP_BASE 0x0000ff00 /* base PADDR of memory chunk */ - #define DMMAP_MASK 0x000000ff /* mask which bits of PADDR are - * constant */ -/* USB controllers */ -#define JZ_EHCI_BASE 0x13490000 -#define JZ_EHCI_REG_UTMI_BUS 0x000000b0 - #define UTMI_BUS_WIDTH 0x00000040 -#define JZ_OHCI_BASE 0x134a0000 - -#define JZ_DWC2_BASE 0x13500000 -#define JZ_DWC2_GUSBCFG 0 - -/* Ethernet */ -#define JZ_DME_BASE 0x16000000 -#define JZ_DME_IO 0 -#define JZ_DME_DATA 2 - -/* GPIO */ -#define JZ_GPIO_A_BASE 0x10010000 -#define JZ_GPIO_B_BASE 0x10010100 -#define JZ_GPIO_C_BASE 0x10010200 -#define JZ_GPIO_D_BASE 0x10010300 -#define JZ_GPIO_E_BASE 0x10010400 -#define JZ_GPIO_F_BASE 0x10010500 - -/* GPIO registers per port */ -#define JZ_GPIO_PIN 0x00000000 /* pin level register */ -/* 0 - normal gpio, 1 - interrupt */ -#define JZ_GPIO_INT 0x00000010 /* interrupt register */ -#define JZ_GPIO_INTS 0x00000014 /* interrupt set register */ -#define JZ_GPIO_INTC 0x00000018 /* interrupt clear register */ -/* - * INT == 1: 1 disables interrupt - * INT == 0: device select, see below - */ -#define JZ_GPIO_MASK 0x00000020 /* port mask register */ -#define JZ_GPIO_MASKS 0x00000024 /* port mask set register */ -#define JZ_GPIO_MASKC 0x00000028 /* port mask clear register */ -/* - * INT == 1: 0 - level triggered, 1 - edge triggered - * INT == 0: 0 - device select, see below - */ -#define JZ_GPIO_PAT1 0x00000030 /* pattern 1 register */ -#define JZ_GPIO_PAT1S 0x00000034 /* pattern 1 set register */ -#define JZ_GPIO_PAT1C 0x00000038 /* pattern 1 clear register */ -/* - * INT == 1: - * PAT1 == 0: 0 - trigger on low, 1 - trigger on high - * PAT0 == 1: 0 - trigger on falling edge, 1 - trigger on rising edge - * INT == 0: - * MASK == 0: - * PAT1 == 0: 0 - device 0, 1 - device 1 - * PAT0 == 1: 0 - device 2, 1 - device 3 - * MASK == 1: - * PAT1 == 0: set gpio output - * PAT1 == 1: pin is input - */ -#define JZ_GPIO_PAT0 0x00000040 /* pattern 0 register */ -#define JZ_GPIO_PAT0S 0x00000044 /* pattern 0 set register */ -#define JZ_GPIO_PAT0C 0x00000048 /* pattern 0 clear register */ -/* 1 - interrupt happened */ -#define JZ_GPIO_FLAG 0x00000050 /* flag register */ -#define JZ_GPIO_FLAGC 0x00000058 /* flag clear register */ -/* 1 - disable pull up/down resistors */ -#define JZ_GPIO_DPULL 0x00000070 /* pull disable register */ -#define JZ_GPIO_DPULLS 0x00000074 /* pull disable set register */ -#define JZ_GPIO_DPULLC 0x00000078 /* pull disable clear register */ -/* the following are uncommented in the manual */ -#define JZ_GPIO_DRVL 0x00000080 /* drive low register */ -#define JZ_GPIO_DRVLS 0x00000084 /* drive low set register */ -#define JZ_GPIO_DRVLC 0x00000088 /* drive low clear register */ -#define JZ_GPIO_DIR 0x00000090 /* direction register */ -#define JZ_GPIO_DIRS 0x00000094 /* direction register */ -#define JZ_GPIO_DIRC 0x00000098 /* direction register */ -#define JZ_GPIO_DRVH 0x000000a0 /* drive high register */ -#define JZ_GPIO_DRVHS 0x000000a4 /* drive high set register */ -#define JZ_GPIO_DRVHC 0x000000a8 /* drive high clear register */ - -/* I2C / SMBus */ -#define JZ_SMB0_BASE 0x10050000 -#define JZ_SMB1_BASE 0x10051000 -#define JZ_SMB2_BASE 0x10052000 -#define JZ_SMB3_BASE 0x10053000 -#define JZ_SMB4_BASE 0x10054000 - -/* SMBus register offsets, per port */ -#define JZ_SMBCON 0x00 /* SMB control */ - #define JZ_STPHLD 0x80 /* Stop Hold Enable bit */ - #define JZ_SLVDIS 0x40 /* 1 - slave disabled */ - #define JZ_REST 0x20 /* 1 - allow RESTART */ - #define JZ_MATP 0x10 /* 1 - enable 10bit addr. for master */ - #define JZ_SATP 0x08 /* 1 - enable 10bit addr. for slave */ - #define JZ_SPD_M 0x06 /* bus speed control */ - #define JZ_SPD_100KB 0x02 /* 100kBit/s mode */ - #define JZ_SPD_400KB 0x04 /* 400kBit/s mode */ - #define JZ_MD 0x01 /* enable master */ -#define JZ_SMBTAR 0x04 /* SMB target address */ - #define JZ_SMATP 0x1000 /* enable 10bit master addr */ - #define JZ_SPECIAL 0x0800 /* 1 - special command */ - #define JZ_START 0x0400 /* 1 - send START */ - #define JZ_SMBTAR_M 0x03ff /* target address */ -#define JZ_SMBSAR 0x08 /* SMB slave address */ -#define JZ_SMBDC 0x10 /* SMB data buffer and command */ - #define JZ_CMD 0x100 /* 1 - read, 0 - write */ - #define JZ_DATA 0x0ff -#define JZ_SMBSHCNT 0x14 /* Standard speed SMB SCL high count */ -#define JZ_SMBSLCNT 0x18 /* Standard speed SMB SCL low count */ -#define JZ_SMBFHCNT 0x1C /* Fast speed SMB SCL high count */ -#define JZ_SMBFLCNT 0x20 /* Fast speed SMB SCL low count */ -#define JZ_SMBINTST 0x2C /* SMB Interrupt Status */ - #define JZ_ISTT 0x400 /* START or RESTART occured */ - #define JZ_ISTP 0x200 /* STOP occured */ - #define JZ_TXABT 0x40 /* ABORT occured */ - #define JZ_TXEMP 0x10 /* TX FIFO is low */ - #define JZ_TXOF 0x08 /* TX FIFO is high */ - #define JZ_RXFL 0x04 /* RX FIFO is at JZ_SMBRXTL*/ - #define JZ_RXOF 0x02 /* RX FIFO is high */ - #define JZ_RXUF 0x01 /* RX FIFO underflow */ -#define JZ_SMBINTM 0x30 /* SMB Interrupt Mask */ -#define JZ_SMBRXTL 0x38 /* SMB RxFIFO Threshold */ -#define JZ_SMBTXTL 0x3C /* SMB TxFIFO Threshold */ -#define JZ_SMBCINT 0x40 /* Clear Interrupts */ - #define JZ_CLEARALL 0x01 -#define JZ_SMBCRXUF 0x44 /* Clear RXUF Interrupt */ -#define JZ_SMBCRXOF 0x48 /* Clear RX_OVER Interrupt */ -#define JZ_SMBCTXOF 0x4C /* Clear TX_OVER Interrupt */ -#define JZ_SMBCRXREQ 0x50 /* Clear RDREQ Interrupt */ -#define JZ_SMBCTXABT 0x54 /* Clear TX_ABRT Interrupt */ -#define JZ_SMBCRXDN 0x58 /* Clear RX_DONE Interrupt */ -#define JZ_SMBCACT 0x5c /* Clear ACTIVITY Interrupt */ -#define JZ_SMBCSTP 0x60 /* Clear STOP Interrupt */ -#define JZ_SMBCSTT 0x64 /* Clear START Interrupt */ -#define JZ_SMBCGC 0x68 /* Clear GEN_CALL Interrupt */ -#define JZ_SMBENB 0x6C /* SMB Enable */ - #define JZ_ENABLE 0x01 -#define JZ_SMBST 0x70 /* SMB Status register */ - #define JZ_SLVACT 0x40 /* slave is active */ - #define JZ_MSTACT 0x20 /* master is active */ - #define JZ_RFF 0x10 /* RX FIFO is full */ - #define JZ_RFNE 0x08 /* RX FIFO not empty */ - #define JZ_TFE 0x04 /* TX FIFO is empty */ - #define JZ_TFNF 0x02 /* TX FIFO is not full */ - #define JZ_ACT 0x01 /* JZ_SLVACT | JZ_MSTACT */ -#define JZ_SMBABTSRC 0x80 /* SMB Transmit Abort Status Register */ -#define JZ_SMBDMACR 0x88 /* DMA Control Register */ -#define JZ_SMBDMATDL 0x8c /* DMA Transmit Data Level */ -#define JZ_SMBDMARDL 0x90 /* DMA Receive Data Level */ -#define JZ_SMBSDASU 0x94 /* SMB SDA Setup Register */ -#define JZ_SMBACKGC 0x98 /* SMB ACK General Call Register */ -#define JZ_SMBENBST 0x9C /* SMB Enable Status Register */ -#define JZ_SMBSDAHD 0xD0 /* SMB SDA HolD time Register */ - #define JZ_HDENB 0x100 /* enable hold time */ - -/* SD/MMC hosts */ -#define JZ_MSC0_BASE 0x13450000 -#define JZ_MSC1_BASE 0x13460000 -#define JZ_MSC2_BASE 0x13470000 - -#define JZ_MSC_CTRL 0x00 - #define JZ_SEND_CCSD 0x8000 - #define JZ_SEND_AS_CCSD 0x4000 - #define JZ_EXIT_MULTIPLE 0x0080 - #define JZ_EXIT_TRANSFER 0x0040 - #define JZ_START_READWAIT 0x0020 - #define JZ_STOP_READWAIT 0x0010 - #define JZ_RESET 0x0008 - #define JZ_START_OP 0x0004 - #define JZ_CLOCK_CTRL_M 0x0003 - #define JZ_CLOCK_START 0x0002 - #define JZ_CLOCK_STOP 0x0001 -#define JZ_MSC_STAT 0x04 - #define JZ_AUTO_CMD12_DONE 0x80000000 - #define JZ_AUTO_CMD23_DONE 0x40000000 - #define JZ_SVS 0x20000000 - #define JZ_PIN_LEVEL_M 0x1f000000 - #define JZ_BCE 0x00100000 /* boot CRC error */ - #define JZ_BDE 0x00080000 /* boot data end */ - #define JZ_BAE 0x00040000 /* boot acknowledge error */ - #define JZ_BAR 0x00020000 /* boot ack. received */ - #define JZ_DMAEND 0x00010000 - #define JZ_IS_RESETTING 0x00008000 - #define JZ_SDIO_INT_ACTIVE 0x00004000 - #define JZ_PRG_DONE 0x00002000 - #define JZ_DATA_TRAN_DONE 0x00001000 - #define JZ_END_CMD_RES 0x00000800 - #define JZ_DATA_FIFO_AFULL 0x00000400 - #define JZ_IS_READWAIT 0x00000200 - #define JZ_CLK_EN 0x00000100 - #define JZ_DATA_FIFO_FULL 0x00000080 - #define JZ_DATA_FIFO_EMPTY 0x00000040 - #define JZ_CRC_RES_ERR 0x00000020 - #define JZ_CRC_READ_ERR 0x00000010 - #define JZ_CRC_WRITE_ERR_M 0x0000000c - #define JZ_CRC_WRITE_OK 0x00000000 - #define JZ_CRC_CARD_ERR 0x00000004 - #define JZ_CRC_NO_STATUS 0x00000008 - #define JZ_TIME_OUT_RES 0x00000002 - #define JZ_TIME_OUT_READ 0x00000001 -#define JZ_MSC_CLKRT 0x08 - #define JZ_DEV_CLK 0x0 - #define JZ_DEV_CLK_2 0x1 /* DEV_CLK / 2 */ - #define JZ_DEV_CLK_4 0x2 /* DEV_CLK / 4 */ - #define JZ_DEV_CLK_8 0x3 /* DEV_CLK / 8 */ - #define JZ_DEV_CLK_16 0x4 /* DEV_CLK / 16 */ - #define JZ_DEV_CLK_32 0x5 /* DEV_CLK / 32 */ - #define JZ_DEV_CLK_64 0x6 /* DEV_CLK / 64 */ - #define JZ_DEV_CLK_128 0x7 /* DEV_CLK / 128 */ -#define JZ_MSC_CMDAT 0x0c - #define JZ_CCS_EXPECTED 0x80000000 - #define JZ_READ_CEATA 0x40000000 - #define JZ_DIS_BOOT 0x08000000 - #define JZ_ENA_BOOT 0x04000000 - #define JZ_EXP_BOOT_ACK 0x02000000 - #define JZ_BOOT_MODE 0x01000000 - #define JZ_AUTO_CMD23 0x00040000 - #define JZ_SDIO_PRDT 0x00020000 - #define JZ_AUTO_CMD12 0x00010000 - #define JZ_RTRG_M 0x0000c000 /* receive FIFO trigger */ - #define JZ_RTRG_16 0x00000000 /* >= 16 */ - #define JZ_RTRG_32 0x00004000 /* >= 32 */ - #define JZ_RTRG_64 0x00008000 /* >= 64 */ - #define JZ_RTRG_96 0x0000c000 /* >= 96 */ - #define JZ_TTRG_M 0x00003000 /* transmit FIFO trigger */ - #define JZ_TTRG_16 0x00000000 /* >= 16 */ - #define JZ_TTRG_32 0x00001000 /* >= 32 */ - #define JZ_TTRG_64 0x00002000 /* >= 64 */ - #define JZ_TTRG_96 0x00003000 /* >= 96 */ - #define JZ_IO_ABORT 0x00000800 - #define JZ_BUS_WIDTH_M 0x00000600 - #define JZ_BUS_1BIT 0x00000000 - #define JZ_BUS_4BIT 0x00000400 - #define JZ_BUS_8BIT 0x00000600 - #define JZ_INIT 0x00000080 /* send 80 clk init before cmd */ - #define JZ_BUSY 0x00000040 - #define JZ_STREAM 0x00000020 - #define JZ_WRITE 0x00000010 /* read otherwise */ - #define JZ_DATA_EN 0x00000008 - #define JZ_RESPONSE_M 0x00000007 /* response format */ - #define JZ_RES_NONE 0x00000000 - #define JZ_RES_R1 0x00000001 /* R1 and R1b */ - #define JZ_RES_R2 0x00000002 - #define JZ_RES_R3 0x00000003 - #define JZ_RES_R4 0x00000004 - #define JZ_RES_R5 0x00000005 - #define JZ_RES_R6 0x00000006 - #define JZ_RES_R7 0x00000007 -#define JZ_MSC_RESTO 0x10 /* 16bit response timeout in MSC_CLK */ -#define JZ_MSC_RDTO 0x14 /* 32bit read timeout in MSC_CLK */ -#define JZ_MSC_BLKLEN 0x18 /* 16bit block length */ -#define JZ_MSC_NOB 0x1c /* 16bit block counter */ -#define JZ_MSC_SNOB 0x20 /* 16bit successful block counter */ -#define JZ_MSC_IMASK 0x24 /* interrupt mask */ - #define JZ_INT_AUTO_CMD23_DONE 0x40000000 - #define JZ_INT_SVS 0x20000000 - #define JZ_INT_PIN_LEVEL_M 0x1f000000 - #define JZ_INT_BCE 0x00100000 - #define JZ_INT_BDE 0x00080000 - #define JZ_INT_BAE 0x00040000 - #define JZ_INT_BAR 0x00020000 - #define JZ_INT_DMAEND 0x00010000 - #define JZ_INT_AUTO_CMD12_DONE 0x00008000 - #define JZ_INT_DATA_FIFO_FULL 0x00004000 - #define JZ_INT_DATA_FIFO_EMPTY 0x00002000 - #define JZ_INT_CRC_RES_ERR 0x00001000 - #define JZ_INT_CRC_READ_ERR 0x00000800 - #define JZ_INT_CRC_WRITE_ERR 0x00000400 - #define JZ_INT_TIMEOUT_RES 0x00000200 - #define JZ_INT_TIMEOUT_READ 0x00000100 - #define JZ_INT_SDIO 0x00000080 - #define JZ_INT_TXFIFO_WR_REQ 0x00000040 - #define JZ_INT_RXFIFO_RD_REQ 0x00000020 - #define JZ_INT_END_CMD_RES 0x00000004 - #define JZ_INT_PRG_DONE 0x00000002 - #define JZ_INT_DATA_TRAN_DONE 0x00000001 -#define JZ_MSC_IFLG 0x28 /* interrupt flags */ -#define JZ_MSC_CMD 0x2c /* 6bit CMD index */ -#define JZ_MSC_ARG 0x30 /* 32bit argument */ -#define JZ_MSC_RES 0x34 /* 8x16bit response data FIFO */ -#define JZ_MSC_RXFIFO 0x38 -#define JZ_MSC_TXFIFO 0x3c -#define JZ_MSC_LPM 0x40 - #define JZ_DRV_SEL_M 0xc0000000 - #define JZ_FALLING_EDGE 0x00000000 - #define JZ_RISING_1NS 0x40000000 /* 1ns delay */ - #define JZ_RISING_4 0x80000000 /* 1/4 MSC_CLK delay */ - #define JZ_SMP_SEL 0x20000000 /* 1 - rising edge */ - #define JZ_LPM 0x00000001 /* low power mode */ -#define JZ_MSC_DMAC 0x44 - #define JZ_MODE_SEL 0x80 /* 1 - specify transfer length */ - #define JZ_AOFST_M 0x60 /* address offset in bytes */ - #define JZ_AOFST_S 6 /* addrress offset shift */ - #define JZ_ALIGNEN 0x10 /* allow non-32bit-aligned transfers */ - #define JZ_INCR_M 0x0c /* burst type */ - #define JZ_INCR_16 0x00 - #define JZ_INCR_32 0x04 - #define JZ_INCR_64 0x08 - #define JZ_DMASEL 0x02 /* 1 - SoC DMAC, 0 - MSC built-in */ - #define JZ_DMAEN 0x01 /* enable DMA */ -#define JZ_MSC_DMANDA 0x48 /* next descriptor paddr */ -#define JZ_MSC_DMADA 0x4c /* current descriptor */ -#define JZ_MSC_DMALEN 0x50 /* transfer tength */ -#define JZ_MSC_DMACMD 0x54 - #define JZ_DMA_IDI_M 0xff000000 - #define JZ_DMA_ID_M 0x00ff0000 - #define JZ_DMA_AOFST_M 0x00000600 - #define JZ_DMA_ALIGN 0x00000100 - #define JZ_DMA_ENDI 0x00000002 - #define JZ_DMA_LINK 0x00000001 -#define JZ_MSC_CTRL2 0x58 - #define JZ_PIP 0x1f000000 /* 1 - intr trigger on high */ - #define JZ_RST_EN 0x00800000 - #define JZ_STPRM 0x00000010 - #define JZ_SVC 0x00000008 - #define JZ_SMS_M 0x00000007 - #define JZ_SMS_DEF 0x00000000 /* default speed */ - #define JZ_SMS_HIGH 0x00000001 /* high speed */ - #define JZ_SMS_SDR12 0x00000002 - #define JZ_SMS_SDR25 0x00000003 - #define JZ_SMS_SDR50 0x00000004 -#define JZ_MSC_RTCNT 0x5c /* RT FIFO count */ - -/* EFUSE Slave Interface */ -#define JZ_EFUSE 0x134100D0 -#define JZ_EFUCTRL 0x00 - #define JZ_EFUSE_BANK 0x40000000 /* select upper 4KBit */ - #define JZ_EFUSE_ADDR_M 0x3fe00000 /* in bytes */ - #define JZ_EFUSE_ADDR_SHIFT 21 - #define JZ_EFUSE_SIZE_M 0x001f0000 /* in bytes */ - #define JZ_EFUSE_SIZE_SHIFT 16 - #define JZ_EFUSE_PROG 0x00008000 /* enable programming */ - #define JZ_EFUSE_WRITE 0x00000002 /* write enable */ - #define JZ_EFUSE_READ 0x00000001 /* read enable */ -#define JZ_EFUCFG 0x04 - #define JZ_EFUSE_INT_E 0x80000000 /* which IRQ? */ - #define JZ_EFUSE_RD_ADJ_M 0x00f00000 - #define JZ_EFUSE_RD_STROBE 0x000f0000 - #define JZ_EFUSE_WR_ADJUST 0x0000f000 - #define JZ_EFUSE_WR_STROBE 0x00000fff -#define JZ_EFUSTATE 0x08 - #define JZ_EFUSE_GLOBAL_P 0x00008000 /* wr protect bits */ - #define JZ_EFUSE_CHIPID_P 0x00004000 - #define JZ_EFUSE_CUSTID_P 0x00002000 - #define JZ_EFUSE_SECWR_EN 0x00001000 - #define JZ_EFUSE_PC_P 0x00000800 - #define JZ_EFUSE_HDMIKEY_P 0x00000400 - #define JZ_EFUSE_SECKEY_P 0x00000200 - #define JZ_EFUSE_SECBOOT_EN 0x00000100 - #define JZ_EFUSE_HDMI_BUSY 0x00000004 - #define JZ_EFUSE_WR_DONE 0x00000002 - #define JZ_EFUSE_RD_DONE 0x00000001 -#define JZ_EFUDATA0 0x0C -#define JZ_EFUDATA1 0x10 -#define JZ_EFUDATA2 0x14 -#define JZ_EFUDATA3 0x18 -#define JZ_EFUDATA4 0x1C -#define JZ_EFUDATA5 0x20 -#define JZ_EFUDATA6 0x24 -#define JZ_EFUDATA7 0x28 - -/* NEMC */ -#define JZ_NEMC_BASE 0x13410000 -#define JZ_NEMC_SMCR(n) (0x10 + (n) * 4) - -# define JZ_NEMC_SMCR_SMT_SHIFT 0 -# define JZ_NEMC_SMCR_SMT_WIDTH 1 -# define JZ_NEMC_SMCR_SMT_MASK (((1 << JZ_NEMC_SMCR_SMT_WIDTH) - 1) << JZ_NEMC_SMCR_SMT_SHIFT) -# define JZ_NEMC_SMCR_SMT_NORMAL (0 << JZ_NEMC_SMCR_SMT_SHIFT) -# define JZ_NEMC_SMCR_SMT_BROM (1 << JZ_NEMC_SMCR_SMT_SHIFT) - -# define JZ_NEMC_SMCR_BL_SHIFT 1 -# define JZ_NEMC_SMCR_BL_WIDTH 2 -# define JZ_NEMC_SMCR_BL_MASK (((1 << JZ_NEMC_SMCR_BL_WIDTH) - 1) << JZ_NEMC_SMCR_BL_SHIFT) -# define JZ_NEMC_SMCR_BL(n) (((n) << JZ_NEMC_SMCR_BL_SHIFT) - -# define JZ_NEMC_SMCR_BW_SHIFT 6 -# define JZ_NEMC_SMCR_BW_WIDTH 2 -# define JZ_NEMC_SMCR_BW_MASK (((1 << JZ_NEMC_SMCR_BW_WIDTH) - 1) << JZ_NEMC_SMCR_BW_SHIFT) -# define JZ_NEMC_SMCR_BW_8 (0 << JZ_NEMC_SMCR_BW_SHIFT) - -# define JZ_NEMC_SMCR_TAS_SHIFT 8 -# define JZ_NEMC_SMCR_TAS_WIDTH 4 -# define JZ_NEMC_SMCR_TAS_MASK (((1 << JZ_NEMC_SMCR_TAS_WIDTH) - 1) << JZ_NEMC_SMCR_TAS_SHIFT) - -# define JZ_NEMC_SMCR_TAH_SHIFT 12 -# define JZ_NEMC_SMCR_TAH_WIDTH 4 -# define JZ_NEMC_SMCR_TAH_MASK (((1 << JZ_NEMC_SMCR_TAH_WIDTH) - 1) << JZ_NEMC_SMCR_TAH_SHIFT) - -# define JZ_NEMC_SMCR_TBP_SHIFT 16 -# define JZ_NEMC_SMCR_TBP_WIDTH 4 -# define JZ_NEMC_SMCR_TBP_MASK (((1 << JZ_NEMC_SMCR_TBP_WIDTH) - 1) << JZ_NEMC_SMCR_TBP_SHIFT) - -# define JZ_NEMC_SMCR_TAW_SHIFT 20 -# define JZ_NEMC_SMCR_TAW_WIDTH 4 -# define JZ_NEMC_SMCR_TAW_MASK (((1 << JZ_NEMC_SMCR_TAW_WIDTH) - 1) << JZ_NEMC_SMCR_TAW_SHIFT) - -# define JZ_NEMC_SMCR_STRV_SHIFT 24 -# define JZ_NEMC_SMCR_STRV_WIDTH 4 -# define JZ_NEMC_SMCR_STRV_MASK (((1 << JZ_NEMC_SMCR_STRV_WIDTH) - 1) << JZ_NEMC_SMCR_STRV_SHIFT) - -#define JZ_NEMC_SACR(n) (0x30 + (n) * 4) - -# define JZ_NEMC_SACR_MASK_SHIFT 0 -# define JZ_NEMC_SACR_MASK_WIDTH 8 -# define JZ_NEMC_SACR_MASK_MASK (((1 << JZ_NEMC_SACR_MASK_WIDTH) - 1) << JZ_NEMC_SACR_MASK_SHIFT) - -# define JZ_NEMC_SACR_ADDR_SHIFT 0 -# define JZ_NEMC_SACR_ADDR_WIDTH 8 -# define JZ_NEMC_SACR_ADDR_MASK (((1 << JZ_NEMC_SACR_ADDR_WIDTH) - 1) << JZ_NEMC_SACR_ADDR_SHIFT) - -#define JC_NEMC_NFSCR 0x50 - -#endif /* JZ4780_REGS_H */ Index: sys/mips/ingenic/jz4780_rtc.c =================================================================== --- sys/mips/ingenic/jz4780_rtc.c +++ /dev/null @@ -1,234 +0,0 @@ -/*- - * Copyright 2016 Alexander Kabaev - * 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. - */ - -/* - * Ingenic JZ4780 RTC driver - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "clock_if.h" - -#define JZ_RTC_TIMEOUT 5000 - -#define JZ_RTCCR 0x00 -# define JZ_RTCCR_WRDY (1u << 7) -#define JZ_RTSR 0x04 -#define JZ_HSPR 0x34 -#define JZ_WENR 0x3C -# define JZ_WENR_PAT 0xa55a -# define JZ_WENR_WEN (1u <<31) - -struct jz4780_rtc_softc { - device_t dev; - struct resource *res[2]; -}; - -static struct resource_spec jz4780_rtc_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE }, - { SYS_RES_IRQ, 0, RF_ACTIVE }, - { -1, 0 } -}; - -#define CSR_READ(sc, reg) bus_read_4((sc)->res[0], (reg)) -#define CSR_WRITE(sc, reg, val) bus_write_4((sc)->res[0], (reg), (val)) - -static int jz4780_rtc_probe(device_t dev); -static int jz4780_rtc_attach(device_t dev); -static int jz4780_rtc_detach(device_t dev); - -static int -jz4780_rtc_probe(device_t dev) -{ - - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (!ofw_bus_is_compatible(dev, "ingenic,jz4780-rtc")) - return (ENXIO); - - device_set_desc(dev, "JZ4780 RTC"); - - return (BUS_PROBE_DEFAULT); -} - -/* Poll control register until RTC is ready to accept register writes */ -static int -jz4780_rtc_wait(struct jz4780_rtc_softc *sc) -{ - int timeout; - - timeout = JZ_RTC_TIMEOUT; - while (timeout-- > 0) { - if (CSR_READ(sc, JZ_RTCCR) & JZ_RTCCR_WRDY) - return (0); - } - return (EIO); -} - -/* - * Write RTC register. It appears that RTC goes into read-only mode at random, - * which suggests something is up with how it is powered up, so do the pattern - * writing dance every time just in case. - */ -static int -jz4780_rtc_write(struct jz4780_rtc_softc *sc, uint32_t reg, uint32_t val) -{ - int ret, timeout; - - ret = jz4780_rtc_wait(sc); - if (ret != 0) - return (ret); - - CSR_WRITE(sc, JZ_WENR, JZ_WENR_PAT); - - ret = jz4780_rtc_wait(sc); - if (ret) - return ret; - - timeout = JZ_RTC_TIMEOUT; - while (timeout-- > 0) { - if (CSR_READ(sc, JZ_WENR) & JZ_WENR_WEN) - break; - } - if (timeout < 0) - return (EIO); - - CSR_WRITE(sc, reg, val); - return 0; -} - -static int -jz4780_rtc_attach(device_t dev) -{ - struct jz4780_rtc_softc *sc = device_get_softc(dev); - uint32_t scratch; - int ret; - - sc->dev = dev; - - if (bus_alloc_resources(dev, jz4780_rtc_spec, sc->res)) { - device_printf(dev, "could not allocate resources for device\n"); - return (ENXIO); - } - - scratch = CSR_READ(sc, JZ_HSPR); - if (scratch != 0x12345678) { - ret = jz4780_rtc_write(sc, JZ_HSPR, 0x12345678); - if (ret == 0) - ret = jz4780_rtc_write(sc, JZ_RTSR, 0); - if (ret) { - device_printf(dev, "Unable to write RTC registers\n"); - jz4780_rtc_detach(dev); - return (ret); - } - } - clock_register(dev, 1000000); /* Register 1 HZ clock */ - return (0); -} - -static int -jz4780_rtc_detach(device_t dev) -{ - struct jz4780_rtc_softc *sc; - - sc = device_get_softc(dev); - bus_release_resources(dev, jz4780_rtc_spec, sc->res); - return (0); -} - -static int -jz4780_rtc_gettime(device_t dev, struct timespec *ts) -{ - struct jz4780_rtc_softc *sc; - uint32_t val1, val2; - int timeout; - - sc = device_get_softc(dev); - - timeout = JZ_RTC_TIMEOUT; - val2 = CSR_READ(sc, JZ_RTSR); - do { - val1 = val2; - val2 = CSR_READ(sc, JZ_RTSR); - } while (val1 != val2 && timeout-- >= 0); - - if (timeout < 0) - return (EIO); - - /* Convert secs to timespec directly */ - ts->tv_sec = val1; - ts->tv_nsec = 0; - return 0; -} - -static int -jz4780_rtc_settime(device_t dev, struct timespec *ts) -{ - struct jz4780_rtc_softc *sc; - - sc = device_get_softc(dev); - return jz4780_rtc_write(sc, JZ_RTSR, ts->tv_sec); -} - -static device_method_t jz4780_rtc_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, jz4780_rtc_probe), - DEVMETHOD(device_attach, jz4780_rtc_attach), - DEVMETHOD(device_detach, jz4780_rtc_detach), - - DEVMETHOD(clock_gettime, jz4780_rtc_gettime), - DEVMETHOD(clock_settime, jz4780_rtc_settime), - - DEVMETHOD_END -}; - -static driver_t jz4780_rtc_driver = { - "jz4780_rtc", - jz4780_rtc_methods, - sizeof(struct jz4780_rtc_softc), -}; - -static devclass_t jz4780_rtc_devclass; - -EARLY_DRIVER_MODULE(jz4780_rtc, simplebus, jz4780_rtc_driver, - jz4780_rtc_devclass, 0, 0, BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE); Index: sys/mips/ingenic/jz4780_smb.h =================================================================== --- sys/mips/ingenic/jz4780_smb.h +++ /dev/null @@ -1,98 +0,0 @@ -/*- - * Copyright (c) 2016 Jared McNeill - * 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. - * - * $FreeBSD$ - */ - -/* - * Ingenic JZ4780 SMB Controller - */ - -#ifndef __JZ4780_SMB_H__ -#define __JZ4780_SMB_H__ - -#define SMBCON 0x00 -#define SMBCON_STPHLD (1 << 7) -#define SMBCON_SLVDIS (1 << 6) -#define SMBCON_REST (1 << 5) -#define SMBCON_MATP (1 << 4) -#define SMBCON_SATP (1 << 3) -#define SMBCON_SPD (3 << 1) -#define SMBCON_SPD_STANDARD (1 << 1) -#define SMBCON_SPD_FAST (2 << 1) -#define SMBCON_MD (1 << 0) -#define SMBTAR 0x04 -#define SMBTAR_MATP (1 << 12) -#define SMBTAR_SPECIAL (1 << 11) -#define SMBTAR_GC_OR_START (1 << 10) -#define SMBTAR_SMBTAR (0x3ff << 0) -#define SMBSAR 0x08 -#define SMBDC 0x10 -#define SMBDC_CMD (1 << 8) -#define SMBDC_DAT (0xff << 0) -#define SMBSHCNT 0x14 -#define SMBSLCNT 0x18 -#define SMBFHCNT 0x1c -#define SMBFLCNT 0x20 -#define SMBINTST 0x2c -#define SMBINTM 0x30 -#define SMBRXTL 0x38 -#define SMBTXTL 0x3c -#define SMBCINT 0x40 -#define SMBCRXUF 0x44 -#define SMBCRXOF 0x48 -#define SMBCTXOF 0x4c -#define SMBCRXREQ 0x50 -#define SMBCTXABT 0x54 -#define SMBCRXDN 0x58 -#define SMBCACT 0x5c -#define SMBCSTP 0x60 -#define SMBCSTT 0x64 -#define SMBCGC 0x68 -#define SMBENB 0x6c -#define SMBENB_SMBENB (1 << 0) -#define SMBST 0x70 -#define SMBST_SLVACT (1 << 6) -#define SMBST_MSTACT (1 << 5) -#define SMBST_RFF (1 << 4) -#define SMBST_RFNE (1 << 3) -#define SMBST_TFE (1 << 2) -#define SMBST_TFNF (1 << 1) -#define SMBST_ACT (1 << 0) -#define SMBABTSRC 0x80 -#define SMBDMACR 0x88 -#define SMBDMATDLR 0x8c -#define SMBDMARDLR 0x90 -#define SMBSDASU 0x94 -#define SMBACKGC 0x98 -#define SMBENBST 0x9c -#define SMBENBST_SLVRDLST (1 << 2) -#define SMBENBST_SLVDISB (1 << 1) -#define SMBENBST_SMBEN (1 << 0) -#define SMBSDAHD 0xd0 -#define SMBSDAHD_HDENB (1 << 8) -#define SMBSDAHD_SDAHD (0xff << 0) - -#endif /* !__JZ4780_SMB_H__ */ Index: sys/mips/ingenic/jz4780_smb.c =================================================================== --- sys/mips/ingenic/jz4780_smb.c +++ /dev/null @@ -1,480 +0,0 @@ -/*- - * Copyright (c) 2016 Jared McNeill - * 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. - * - * $FreeBSD$ - */ - -/* - * Ingenic JZ4780 SMB Controller - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include - -#include - -#include "iicbus_if.h" - -#define JZSMB_TIMEOUT ((300UL * hz) / 1000) - -#define JZSMB_SPEED_STANDARD 100000 -#define JZSMB_SETUP_TIME_STANDARD 300 -#define JZSMB_HOLD_TIME_STANDARD 400 -#define JZSMB_PERIOD_MIN_STANDARD 4000 -#define JZSMB_PERIOD_MAX_STANDARD 4700 - -#define JZSMB_SPEED_FAST 400000 -#define JZSMB_SETUP_TIME_FAST 450 -#define JZSMB_HOLD_TIME_FAST 450 -#define JZSMB_PERIOD_MIN_FAST 600 -#define JZSMB_PERIOD_MAX_FAST 1300 - -#define JZSMB_HCNT_BASE 8 -#define JZSMB_HCNT_MIN 6 -#define JZSMB_LCNT_BASE 1 -#define JZSMB_LCNT_MIN 8 - -static inline int -tstohz(const struct timespec *tsp) -{ - struct timeval tv; - - TIMESPEC_TO_TIMEVAL(&tv, tsp); - return (tvtohz(&tv)); -} - -static struct ofw_compat_data compat_data[] = { - { "ingenic,jz4780-i2c", 1 }, - { NULL, 0 } -}; - -static struct resource_spec jzsmb_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE }, - { -1, 0 } -}; - -struct jzsmb_softc { - struct resource *res; - struct mtx mtx; - clk_t clk; - device_t iicbus; - int busy; - uint32_t i2c_freq; - uint64_t bus_freq; - uint32_t status; - - struct iic_msg *msg; -}; - -#define SMB_LOCK(sc) mtx_lock(&(sc)->mtx) -#define SMB_UNLOCK(sc) mtx_unlock(&(sc)->mtx) -#define SMB_ASSERT_LOCKED(sc) mtx_assert(&(sc)->mtx, MA_OWNED) -#define SMB_READ(sc, reg) bus_read_2((sc)->res, (reg)) -#define SMB_WRITE(sc, reg, val) bus_write_2((sc)->res, (reg), (val)) - -static phandle_t -jzsmb_get_node(device_t bus, device_t dev) -{ - return (ofw_bus_get_node(bus)); -} - -static int -jzsmb_enable(struct jzsmb_softc *sc, int enable) -{ - SMB_ASSERT_LOCKED(sc); - - if (enable) { - SMB_WRITE(sc, SMBENB, SMBENB_SMBENB); - while ((SMB_READ(sc, SMBENBST) & SMBENBST_SMBEN) == 0) - ; - } else { - SMB_WRITE(sc, SMBENB, 0); - while ((SMB_READ(sc, SMBENBST) & SMBENBST_SMBEN) != 0) - ; - } - - return (0); -} - -static int -jzsmb_reset_locked(device_t dev, u_char addr) -{ - struct jzsmb_softc *sc; - uint16_t con; - uint32_t period; - int hcnt, lcnt, setup_time, hold_time; - - sc = device_get_softc(dev); - - SMB_ASSERT_LOCKED(sc); - - /* Setup master mode operation */ - - /* Disable SMB */ - jzsmb_enable(sc, 0); - - /* Disable interrupts */ - SMB_WRITE(sc, SMBINTM, 0); - - /* Set supported speed mode and expected SCL frequency */ - period = sc->bus_freq / sc->i2c_freq; - con = SMBCON_REST | SMBCON_SLVDIS | SMBCON_MD; - switch (sc->i2c_freq) { - case JZSMB_SPEED_STANDARD: - con |= SMBCON_SPD_STANDARD; - setup_time = JZSMB_SETUP_TIME_STANDARD; - hold_time = JZSMB_HOLD_TIME_STANDARD; - hcnt = (period * JZSMB_PERIOD_MIN_STANDARD) / - (JZSMB_PERIOD_MAX_STANDARD + JZSMB_PERIOD_MIN_STANDARD); - lcnt = period - hcnt; - hcnt = MAX(hcnt - JZSMB_HCNT_BASE, JZSMB_HCNT_MIN); - lcnt = MAX(lcnt - JZSMB_LCNT_BASE, JZSMB_LCNT_MIN); - SMB_WRITE(sc, SMBCON, con); - SMB_WRITE(sc, SMBSHCNT, hcnt); - SMB_WRITE(sc, SMBSLCNT, lcnt); - break; - case JZSMB_SPEED_FAST: - con |= SMBCON_SPD_FAST; - setup_time = JZSMB_SETUP_TIME_FAST; - hold_time = JZSMB_HOLD_TIME_FAST; - hcnt = (period * JZSMB_PERIOD_MIN_FAST) / - (JZSMB_PERIOD_MAX_FAST + JZSMB_PERIOD_MIN_FAST); - lcnt = period - hcnt; - hcnt = MAX(hcnt - JZSMB_HCNT_BASE, JZSMB_HCNT_MIN); - lcnt = MAX(lcnt - JZSMB_LCNT_BASE, JZSMB_LCNT_MIN); - SMB_WRITE(sc, SMBCON, con); - SMB_WRITE(sc, SMBFHCNT, hcnt); - SMB_WRITE(sc, SMBFLCNT, lcnt); - break; - default: - return (EINVAL); - } - - setup_time = ((setup_time * sc->bus_freq / 1000) / 1000000) + 1; - setup_time = MIN(1, MAX(255, setup_time)); - SMB_WRITE(sc, SMBSDASU, setup_time); - - hold_time = ((hold_time * sc->bus_freq / 1000) / 1000000) - 1; - hold_time = MAX(255, hold_time); - if (hold_time >= 0) - SMB_WRITE(sc, SMBSDAHD, hold_time | SMBSDAHD_HDENB); - else - SMB_WRITE(sc, SMBSDAHD, 0); - - SMB_WRITE(sc, SMBTAR, addr >> 1); - - if (addr != 0) { - /* Enable SMB */ - jzsmb_enable(sc, 1); - } - - return (0); -} - -static int -jzsmb_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) -{ - struct jzsmb_softc *sc; - int error; - - sc = device_get_softc(dev); - - SMB_LOCK(sc); - error = jzsmb_reset_locked(dev, addr); - SMB_UNLOCK(sc); - - return (error); -} - -static int -jzsmb_transfer_read(device_t dev, struct iic_msg *msg) -{ - struct jzsmb_softc *sc; - struct timespec start, diff; - uint16_t con, resid; - int timeo; - - sc = device_get_softc(dev); - timeo = JZSMB_TIMEOUT * msg->len; - - SMB_ASSERT_LOCKED(sc); - - con = SMB_READ(sc, SMBCON); - con |= SMBCON_STPHLD; - SMB_WRITE(sc, SMBCON, con); - - getnanouptime(&start); - for (resid = msg->len; resid > 0; resid--) { - for (int i = 0; i < min(resid, 8); i++) - SMB_WRITE(sc, SMBDC, SMBDC_CMD); - for (;;) { - getnanouptime(&diff); - timespecsub(&diff, &start, &diff); - if ((SMB_READ(sc, SMBST) & SMBST_RFNE) != 0) { - msg->buf[msg->len - resid] = - SMB_READ(sc, SMBDC) & SMBDC_DAT; - break; - } else - DELAY(1000); - - if (tstohz(&diff) >= timeo) { - device_printf(dev, - "read timeout (status=0x%02x)\n", - SMB_READ(sc, SMBST)); - return (EIO); - } - } - } - - con = SMB_READ(sc, SMBCON); - con &= ~SMBCON_STPHLD; - SMB_WRITE(sc, SMBCON, con); - - return (0); -} - -static int -jzsmb_transfer_write(device_t dev, struct iic_msg *msg, int stop_hold) -{ - struct jzsmb_softc *sc; - struct timespec start, diff; - uint16_t con, resid; - int timeo; - - sc = device_get_softc(dev); - timeo = JZSMB_TIMEOUT * msg->len; - - SMB_ASSERT_LOCKED(sc); - - con = SMB_READ(sc, SMBCON); - con |= SMBCON_STPHLD; - SMB_WRITE(sc, SMBCON, con); - - getnanouptime(&start); - for (resid = msg->len; resid > 0; resid--) { - for (;;) { - getnanouptime(&diff); - timespecsub(&diff, &start, &diff); - if ((SMB_READ(sc, SMBST) & SMBST_TFNF) != 0) { - SMB_WRITE(sc, SMBDC, - msg->buf[msg->len - resid]); - break; - } else - DELAY((1000 * hz) / JZSMB_TIMEOUT); - - if (tstohz(&diff) >= timeo) { - device_printf(dev, - "write timeout (status=0x%02x)\n", - SMB_READ(sc, SMBST)); - return (EIO); - } - } - } - - if (!stop_hold) { - con = SMB_READ(sc, SMBCON); - con &= ~SMBCON_STPHLD; - SMB_WRITE(sc, SMBCON, con); - } - - return (0); -} - -static int -jzsmb_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) -{ - struct jzsmb_softc *sc; - uint32_t n; - uint16_t con; - int error; - - sc = device_get_softc(dev); - - SMB_LOCK(sc); - while (sc->busy) - mtx_sleep(sc, &sc->mtx, 0, "i2cbuswait", 0); - sc->busy = 1; - sc->status = 0; - - for (n = 0; n < nmsgs; n++) { - /* Set target address */ - if (n == 0 || msgs[n].slave != msgs[n - 1].slave) - jzsmb_reset_locked(dev, msgs[n].slave); - - /* Set read or write */ - if ((msgs[n].flags & IIC_M_RD) != 0) - error = jzsmb_transfer_read(dev, &msgs[n]); - else - error = jzsmb_transfer_write(dev, &msgs[n], - n < nmsgs - 1); - - if (error != 0) - goto done; - } - -done: - /* Send stop if necessary */ - con = SMB_READ(sc, SMBCON); - con &= ~SMBCON_STPHLD; - SMB_WRITE(sc, SMBCON, con); - - /* Disable SMB */ - jzsmb_enable(sc, 0); - - sc->msg = NULL; - sc->busy = 0; - wakeup(sc); - SMB_UNLOCK(sc); - - return (error); -} - -static int -jzsmb_probe(device_t dev) -{ - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) - return (ENXIO); - - device_set_desc(dev, "Ingenic JZ4780 SMB Controller"); - - return (BUS_PROBE_DEFAULT); -} - -static int -jzsmb_attach(device_t dev) -{ - struct jzsmb_softc *sc; - phandle_t node; - int error; - - sc = device_get_softc(dev); - node = ofw_bus_get_node(dev); - mtx_init(&sc->mtx, device_get_nameunit(dev), "jzsmb", MTX_DEF); - - error = clk_get_by_ofw_index(dev, 0, 0, &sc->clk); - if (error != 0) { - device_printf(dev, "cannot get clock\n"); - goto fail; - } - error = clk_enable(sc->clk); - if (error != 0) { - device_printf(dev, "cannot enable clock\n"); - goto fail; - } - error = clk_get_freq(sc->clk, &sc->bus_freq); - if (error != 0 || sc->bus_freq == 0) { - device_printf(dev, "cannot get bus frequency\n"); - return (error); - } - - if (bus_alloc_resources(dev, jzsmb_spec, &sc->res) != 0) { - device_printf(dev, "cannot allocate resources for device\n"); - error = ENXIO; - goto fail; - } - - if (OF_getencprop(node, "clock-frequency", &sc->i2c_freq, - sizeof(sc->i2c_freq)) != 0 || sc->i2c_freq == 0) - sc->i2c_freq = 100000; /* Default to standard mode */ - - sc->iicbus = device_add_child(dev, "iicbus", -1); - if (sc->iicbus == NULL) { - device_printf(dev, "cannot add iicbus child device\n"); - error = ENXIO; - goto fail; - } - - bus_generic_attach(dev); - - return (0); - -fail: - bus_release_resources(dev, jzsmb_spec, &sc->res); - if (sc->clk != NULL) - clk_release(sc->clk); - mtx_destroy(&sc->mtx); - return (error); -} - -static device_method_t jzsmb_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, jzsmb_probe), - DEVMETHOD(device_attach, jzsmb_attach), - - /* Bus interface */ - DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), - DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), - DEVMETHOD(bus_alloc_resource, bus_generic_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_set_resource, bus_generic_rl_set_resource), - DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), - - /* OFW methods */ - DEVMETHOD(ofw_bus_get_node, jzsmb_get_node), - - /* iicbus interface */ - DEVMETHOD(iicbus_callback, iicbus_null_callback), - DEVMETHOD(iicbus_reset, jzsmb_reset), - DEVMETHOD(iicbus_transfer, jzsmb_transfer), - - DEVMETHOD_END -}; - -static driver_t jzsmb_driver = { - "iichb", - jzsmb_methods, - sizeof(struct jzsmb_softc), -}; - -static devclass_t jzsmb_devclass; - -EARLY_DRIVER_MODULE(iicbus, jzsmb, iicbus_driver, iicbus_devclass, 0, 0, - BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE); -EARLY_DRIVER_MODULE(jzsmb, simplebus, jzsmb_driver, jzsmb_devclass, 0, 0, - BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE); -MODULE_VERSION(jzsmb, 1); Index: sys/mips/ingenic/jz4780_timer.c =================================================================== --- sys/mips/ingenic/jz4780_timer.c +++ /dev/null @@ -1,339 +0,0 @@ -/*- - * Copyright 2013-2015 Alexander Kabaev - * Copyright 2013-2015 John Wehle - * 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 - -struct jz4780_timer_softc { - device_t dev; - struct resource * res[4]; - void * ih_cookie; - struct eventtimer et; - struct timecounter tc; -}; - -static struct resource_spec jz4780_timer_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE }, - { SYS_RES_IRQ, 0, RF_ACTIVE }, /* OST */ - { SYS_RES_IRQ, 1, RF_ACTIVE }, /* TC5 */ - { SYS_RES_IRQ, 2, RF_ACTIVE }, /* TC0-4,6 */ - { -1, 0 } -}; - -/* - * devclass_get_device / device_get_softc could be used - * to dynamically locate this, however the timers are a - * required device which can't be unloaded so there's - * no need for the overhead. - */ -static struct jz4780_timer_softc *jz4780_timer_sc = NULL; - -#define CSR_WRITE_4(sc, reg, val) bus_write_4((sc)->res[0], reg, (val)) -#define CSR_READ_4(sc, reg) bus_read_4((sc)->res[0], reg) - -static unsigned -jz4780_get_timecount(struct timecounter *tc) -{ - struct jz4780_timer_softc *sc = - (struct jz4780_timer_softc *)tc->tc_priv; - - return CSR_READ_4(sc, JZ_OST_CNT_LO); -} - -static int -jz4780_hardclock(void *arg) -{ - struct jz4780_timer_softc *sc = (struct jz4780_timer_softc *)arg; - - CSR_WRITE_4(sc, JZ_TC_TFCR, TFR_FFLAG5); - CSR_WRITE_4(sc, JZ_TC_TECR, TESR_TCST5); - - if (sc->et.et_active) - sc->et.et_event_cb(&sc->et, sc->et.et_arg); - - return (FILTER_HANDLED); -} - -static int -jz4780_timer_start(struct eventtimer *et, sbintime_t first, sbintime_t period) -{ - struct jz4780_timer_softc *sc = - (struct jz4780_timer_softc *)et->et_priv; - uint32_t ticks; - - ticks = (first * et->et_frequency) / SBT_1S; - if (ticks == 0) - return (EINVAL); - - CSR_WRITE_4(sc, JZ_TC_TDFR(5), ticks); - CSR_WRITE_4(sc, JZ_TC_TCNT(5), 0); - CSR_WRITE_4(sc, JZ_TC_TESR, TESR_TCST5); - - return (0); -} - -static int -jz4780_timer_stop(struct eventtimer *et) -{ - struct jz4780_timer_softc *sc = - (struct jz4780_timer_softc *)et->et_priv; - - CSR_WRITE_4(sc, JZ_TC_TECR, TESR_TCST5); - return (0); -} - -static int -jz4780_timer_probe(device_t dev) -{ - - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (!ofw_bus_is_compatible(dev, "ingenic,jz4780-tcu")) - return (ENXIO); - - device_set_desc(dev, "Ingenic JZ4780 timer"); - - return (BUS_PROBE_DEFAULT); -} - -static int -jz4780_timer_attach(device_t dev) -{ - struct jz4780_timer_softc *sc = device_get_softc(dev); - pcell_t counter_freq; - clk_t clk; - - /* There should be exactly one instance. */ - if (jz4780_timer_sc != NULL) - return (ENXIO); - - sc->dev = dev; - - if (bus_alloc_resources(dev, jz4780_timer_spec, sc->res)) { - device_printf(dev, "can not allocate resources for device\n"); - return (ENXIO); - } - - counter_freq = 0; - if (clk_get_by_name(dev, "ext", &clk) == 0) { - uint64_t clk_freq; - - if (clk_get_freq(clk, &clk_freq) == 0) - counter_freq = (uint32_t)clk_freq / 16; - clk_release(clk); - } - if (counter_freq == 0) { - device_printf(dev, "unable to determine ext clock frequency\n"); - /* Hardcode value we 'know' is correct */ - counter_freq = 48000000 / 16; - } - - /* - * Disable the timers, select the input for each timer, - * clear and then start OST. - */ - - /* Stop OST, if it happens to be running */ - CSR_WRITE_4(sc, JZ_TC_TECR, TESR_OST); - /* Stop all other channels as well */ - CSR_WRITE_4(sc, JZ_TC_TECR, TESR_TCST0 | TESR_TCST1 | TESR_TCST2 | - TESR_TCST3 | TESR_TCST4 | TESR_TCST5 | TESR_TCST6 | TESR_TCST3); - /* Clear detect mask flags */ - CSR_WRITE_4(sc, JZ_TC_TFCR, 0xFFFFFFFF); - /* Mask all interrupts */ - CSR_WRITE_4(sc, JZ_TC_TMSR, 0xFFFFFFFF); - - /* Init counter with known data */ - CSR_WRITE_4(sc, JZ_OST_CTRL, 0); - CSR_WRITE_4(sc, JZ_OST_CNT_LO, 0); - CSR_WRITE_4(sc, JZ_OST_CNT_HI, 0); - CSR_WRITE_4(sc, JZ_OST_DATA, 0xffffffff); - - /* Configure counter for external clock */ - CSR_WRITE_4(sc, JZ_OST_CTRL, OSTC_EXT_EN | OSTC_MODE | OSTC_DIV_16); - - /* Start the counter again */ - CSR_WRITE_4(sc, JZ_TC_TESR, TESR_OST); - - /* Configure TCU channel 5 similarly to OST and leave it disabled */ - CSR_WRITE_4(sc, JZ_TC_TCSR(5), TCSR_EXT_EN | TCSR_DIV_16); - CSR_WRITE_4(sc, JZ_TC_TMCR, TMR_FMASK(5)); - - if (bus_setup_intr(dev, sc->res[2], INTR_TYPE_CLK, - jz4780_hardclock, NULL, sc, &sc->ih_cookie)) { - device_printf(dev, "could not setup interrupt handler\n"); - bus_release_resources(dev, jz4780_timer_spec, sc->res); - return (ENXIO); - } - - sc->et.et_name = "JZ4780 TCU5"; - sc->et.et_flags = ET_FLAGS_ONESHOT; - sc->et.et_frequency = counter_freq; - sc->et.et_quality = 1000; - sc->et.et_min_period = (0x00000002LLU * SBT_1S) / sc->et.et_frequency; - sc->et.et_max_period = (0x0000fffeLLU * SBT_1S) / sc->et.et_frequency; - sc->et.et_start = jz4780_timer_start; - sc->et.et_stop = jz4780_timer_stop; - sc->et.et_priv = sc; - - et_register(&sc->et); - - sc->tc.tc_get_timecount = jz4780_get_timecount; - sc->tc.tc_name = "JZ4780 OST"; - sc->tc.tc_frequency = counter_freq; - sc->tc.tc_counter_mask = ~0u; - sc->tc.tc_quality = 1000; - sc->tc.tc_priv = sc; - - tc_init(&sc->tc); - - /* Now when tc is initialized, allow DELAY to find it */ - jz4780_timer_sc = sc; - - return (0); -} - -static int -jz4780_timer_detach(device_t dev) -{ - - return (EBUSY); -} - -static device_method_t jz4780_timer_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, jz4780_timer_probe), - DEVMETHOD(device_attach, jz4780_timer_attach), - DEVMETHOD(device_detach, jz4780_timer_detach), - - DEVMETHOD_END -}; - -static driver_t jz4780_timer_driver = { - "timer", - jz4780_timer_methods, - sizeof(struct jz4780_timer_softc), -}; - -static devclass_t jz4780_timer_devclass; - -EARLY_DRIVER_MODULE(timer, simplebus, jz4780_timer_driver, - jz4780_timer_devclass, 0, 0, BUS_PASS_TIMER); - -void -DELAY(int usec) -{ - uint32_t counter; - uint32_t delta, now, previous, remaining; - - /* Timer has not yet been initialized */ - if (jz4780_timer_sc == NULL) { - for (; usec > 0; usec--) - for (counter = 200; counter > 0; counter--) { - /* Prevent gcc from optimizing out the loop */ - mips_rd_cause(); - } - return; - } - TSENTER(); - - /* - * Some of the other timers in the source tree do this calculation as: - * - * usec * ((sc->tc.tc_frequency / 1000000) + 1) - * - * which gives a fairly pessimistic result when tc_frequency is an exact - * multiple of 1000000. Given the data type and typical values for - * tc_frequency adding 999999 shouldn't overflow. - */ - remaining = usec * ((jz4780_timer_sc->tc.tc_frequency + 999999) / - 1000000); - - /* - * We add one since the first iteration may catch the counter just - * as it is changing. - */ - remaining += 1; - - previous = jz4780_get_timecount(&jz4780_timer_sc->tc); - - for ( ; ; ) { - now = jz4780_get_timecount(&jz4780_timer_sc->tc); - - /* - * If the timer has rolled over, then we have the case: - * - * if (previous > now) { - * delta = (0 - previous) + now - * } - * - * which is really no different then the normal case. - * Both cases are simply: - * - * delta = now - previous. - */ - delta = now - previous; - - if (delta >= remaining) - break; - - previous = now; - remaining -= delta; - } - TSEXIT(); -} - -void -platform_initclocks(void) -{ - -} - Index: sys/mips/ingenic/jz4780_uart.c =================================================================== --- sys/mips/ingenic/jz4780_uart.c +++ /dev/null @@ -1,220 +0,0 @@ -/*- - * 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 ``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 "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 "uart_if.h" - -/* - * High-level UART interface. - */ -struct jz4780_uart_softc { - struct ns8250_softc ns8250_base; - clk_t clk_mod; - clk_t clk_baud; -}; - -static int -jz4780_bus_attach(struct uart_softc *sc) -{ - struct ns8250_softc *ns8250; - struct uart_bas *bas; - int rv; - - ns8250 = (struct ns8250_softc *)sc; - bas = &sc->sc_bas; - - rv = ns8250_bus_attach(sc); - if (rv != 0) - return (0); - - /* Configure uart to use extra IER_RXTMOUT bit */ - ns8250->ier_rxbits = IER_RXTMOUT | IER_EMSC | IER_ERLS | IER_ERXRDY; - ns8250->ier_mask = ~(ns8250->ier_rxbits); - ns8250->ier = uart_getreg(bas, REG_IER) & ns8250->ier_mask; - ns8250->ier |= ns8250->ier_rxbits; - uart_setreg(bas, REG_IER, ns8250->ier); - uart_barrier(bas); - return (0); -} - -static kobj_method_t jz4780_uart_methods[] = { - KOBJMETHOD(uart_probe, ns8250_bus_probe), - KOBJMETHOD(uart_attach, jz4780_bus_attach), - KOBJMETHOD(uart_detach, ns8250_bus_detach), - KOBJMETHOD(uart_flush, ns8250_bus_flush), - KOBJMETHOD(uart_getsig, ns8250_bus_getsig), - KOBJMETHOD(uart_ioctl, ns8250_bus_ioctl), - KOBJMETHOD(uart_ipend, ns8250_bus_ipend), - KOBJMETHOD(uart_param, ns8250_bus_param), - KOBJMETHOD(uart_receive, ns8250_bus_receive), - KOBJMETHOD(uart_setsig, ns8250_bus_setsig), - KOBJMETHOD(uart_transmit, ns8250_bus_transmit), - KOBJMETHOD(uart_grab, ns8250_bus_grab), - KOBJMETHOD(uart_ungrab, ns8250_bus_ungrab), - KOBJMETHOD_END -}; - -static struct uart_class jz4780_uart_class = { - "jz4780_uart_class", - jz4780_uart_methods, - sizeof(struct jz4780_uart_softc), - .uc_ops = &uart_ns8250_ops, - .uc_range = 8, - .uc_rclk = 0, -}; - -/* Compatible devices. */ -static struct ofw_compat_data compat_data[] = { - {"ingenic,jz4780-uart", (uintptr_t)&jz4780_uart_class}, - {NULL, (uintptr_t)NULL}, -}; - -UART_FDT_CLASS(compat_data); - -/* - * UART Driver interface. - */ -static int -jz4780_uart_get_shift(device_t dev) -{ - phandle_t node; - pcell_t shift; - - node = ofw_bus_get_node(dev); - if ((OF_getencprop(node, "reg-shift", &shift, sizeof(shift))) <= 0) - shift = 2; - return ((int)shift); -} - -static int -jz4780_uart_probe(device_t dev) -{ - struct jz4780_uart_softc *sc; - uint64_t freq; - int shift; - int rv; - const struct ofw_compat_data *cd; - - sc = device_get_softc(dev); - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - cd = ofw_bus_search_compatible(dev, compat_data); - if (cd->ocd_data == 0) - return (ENXIO); - - /* Figure out clock setup */ - rv = clk_get_by_ofw_name(dev, 0, "module", &sc->clk_mod); - if (rv != 0) { - device_printf(dev, "Cannot get UART clock: %d\n", rv); - return (ENXIO); - } - rv = clk_enable(sc->clk_mod); - if (rv != 0) { - device_printf(dev, "Cannot enable UART clock: %d\n", rv); - return (ENXIO); - } - rv = clk_get_by_ofw_name(dev, 0, "baud", &sc->clk_baud); - if (rv != 0) { - device_printf(dev, "Cannot get UART clock: %d\n", rv); - return (ENXIO); - } - rv = clk_enable(sc->clk_baud); - if (rv != 0) { - device_printf(dev, "Cannot enable UART clock: %d\n", rv); - return (ENXIO); - } - rv = clk_get_freq(sc->clk_baud, &freq); - if (rv != 0) { - device_printf(dev, "Cannot determine UART clock frequency: %d\n", rv); - return (ENXIO); - } - - if (bootverbose) - device_printf(dev, "got UART clock: %lld\n", freq); - sc->ns8250_base.base.sc_class = (struct uart_class *)cd->ocd_data; - shift = jz4780_uart_get_shift(dev); - return (uart_bus_probe(dev, shift, 0, (int)freq, 0, 0, 0)); -} - -static int -jz4780_uart_detach(device_t dev) -{ - struct jz4780_uart_softc *sc; - int rv; - - rv = uart_bus_detach(dev); - if (rv != 0) - return (rv); - - sc = device_get_softc(dev); - if (sc->clk_mod != NULL) { - clk_release(sc->clk_mod); - } - if (sc->clk_baud != NULL) { - clk_release(sc->clk_baud); - } - return (0); -} - -static device_method_t jz4780_uart_bus_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, jz4780_uart_probe), - DEVMETHOD(device_attach, uart_bus_attach), - DEVMETHOD(device_detach, jz4780_uart_detach), - { 0, 0 } -}; - -static driver_t jz4780_uart_driver = { - uart_driver_name, - jz4780_uart_bus_methods, - sizeof(struct jz4780_uart_softc), -}; - -DRIVER_MODULE(jz4780_uart, simplebus, jz4780_uart_driver, uart_devclass, - 0, 0); Index: sys/mips/mediatek/std.rt2880 =================================================================== --- sys/mips/mediatek/std.rt2880 +++ /dev/null @@ -1,89 +0,0 @@ -# -# std.rt2880 -- Base kernel configuration file for FreeBSD/MIPS RT2800 SoC -# -# This includes all the required drivers for the SoCs. -# -# $FreeBSD$ -# - -# Include the standard file list for Mediatek SoCs. -files "../mediatek/files.mediatek" - -# Building a mips/mipsel kernel -machine mips mipsel - -# Little-endian machine -makeoptions MIPS_LITTLE_ENDIAN=defined - -# Default kernel load address -makeoptions KERNLOADADDR=0x88001000 - -# Mediatek/Ralink SoC support depends on FDT (with static DTB for the moment) -options FDT -options FDT_DTB_STATIC - -# We rely on INTRNG code -options INTRNG -options MIPS_NIRQ=256 - -# We rely on NEW_PCIB code -options NEW_PCIB - -# Build kernel with gdb(1) debug symbols -makeoptions DEBUG=-g - -# Support for DDB and KDB -options DDB -options KDB - -# Debugging for use in -current -options INVARIANTS -options INVARIANT_SUPPORT -options WITNESS -options WITNESS_SKIPSPIN -options DEBUG_REDZONE -options DEBUG_MEMGUARD - -# For small memory footprints -options VM_KMEM_SIZE_SCALE=1 - -# General options, including scheduler, etc. -options SCHED_ULE # ULE scheduler -options INET # InterNETworking -#options INET6 # IPv6 -options PSEUDOFS # Pseude-filesystem framework -options FFS # Berkeley Fast Filesystem -#options SOFTUPDATES # Enable FFS soft updates support -#options UFS_ACL # Support for access control lists -#options UFS_DIRHASH # Improve big directory performance -#options MSDOSFS # Enable support for MSDOS filesystems -options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time ext. - -# -# Standard drivers section -# -# The drivers in the following section are required in order to successfully -# compile the kernel. -# - -# FDT clock and pinctrl framework -device fdt_clock -device fdt_pinctrl - -# UART support -device uart - -# random support -device random - -# loop device support -device loop - -# ether device support -device ether - -# ether switch support -#device etherswitch -#device miibus -#device ip17x -#device mdio Index: sys/mips/mips/bus_space_generic.c =================================================================== --- sys/mips/mips/bus_space_generic.c +++ sys/mips/mips/bus_space_generic.c @@ -202,14 +202,6 @@ #define wr16(a, v) cvmx_write64_uint16(a, v) #define wr32(a, v) cvmx_write64_uint32(a, v) #define wr64(a, v) cvmx_write64_uint64(a, v) -#elif defined(CPU_SB1) && _BYTE_ORDER == _BIG_ENDIAN -#include -#define rd8(a) sb_big_endian_read8(a) -#define rd16(a) sb_big_endian_read16(a) -#define rd32(a) sb_big_endian_read32(a) -#define wr8(a, v) sb_big_endian_write8(a, v) -#define wr16(a, v) sb_big_endian_write16(a, v) -#define wr32(a, v) sb_big_endian_write32(a, v) #else #define rd8(a) readb(a) #define rd16(a) readw(a) Index: sys/mips/sibyte/ata_zbbus.c =================================================================== --- sys/mips/sibyte/ata_zbbus.c +++ /dev/null @@ -1,172 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2009 Neelkanth Natu - * 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 - -__FBSDID("$FreeBSD$"); - -static int -ata_zbbus_probe(device_t dev) -{ - - return (ata_probe(dev)); -} - -static int -ata_zbbus_attach(device_t dev) -{ - int i, rid, regshift, regoffset; - struct ata_channel *ch; - struct resource *io; - - ch = device_get_softc(dev); - - if (ch->attached) - return (0); - ch->attached = 1; - - rid = 0; - io = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); - if (io == NULL) - return (ENXIO); - - /* - * SWARM needs an address shift of 5 when accessing ATA registers. - * - * For e.g. an access to register 4 actually needs an address - * of (4 << 5) to be output on the generic bus. - */ - regshift = 5; - resource_int_value(device_get_name(dev), device_get_unit(dev), - "regshift", ®shift); - if (regshift && bootverbose) - device_printf(dev, "using a register shift of %d\n", regshift); - - regoffset = 0x1F0; - resource_int_value(device_get_name(dev), device_get_unit(dev), - "regoffset", ®offset); - if (regoffset && bootverbose) { - device_printf(dev, "using a register offset of 0x%0x\n", - regoffset); - } - - /* setup the ata register addresses */ - for (i = ATA_DATA; i <= ATA_COMMAND; ++i) { - ch->r_io[i].res = io; - ch->r_io[i].offset = (regoffset + i) << regshift; - } - - ch->r_io[ATA_CONTROL].res = io; - ch->r_io[ATA_CONTROL].offset = (regoffset + ATA_CTLOFFSET) << regshift; - ch->r_io[ATA_IDX_ADDR].res = io; /* XXX what is this used for */ - ata_default_registers(dev); - - /* initialize softc for this channel */ - ch->unit = 0; - ch->flags |= ATA_USE_16BIT; - ata_generic_hw(dev); - - return (ata_attach(dev)); -} - -static int -ata_zbbus_detach(device_t dev) -{ - int error; - struct ata_channel *ch = device_get_softc(dev); - - if (!ch->attached) - return (0); - ch->attached = 0; - - error = ata_detach(dev); - - bus_release_resource(dev, SYS_RES_MEMORY, 0, - ch->r_io[ATA_IDX_ADDR].res); - - return (error); -} - -static int -ata_zbbus_suspend(device_t dev) -{ - struct ata_channel *ch = device_get_softc(dev); - - if (!ch->attached) - return (0); - - return (ata_suspend(dev)); -} - -static int -ata_zbbus_resume(device_t dev) -{ - struct ata_channel *ch = device_get_softc(dev); - - if (!ch->attached) - return (0); - - return (ata_resume(dev)); -} - -static device_method_t ata_zbbus_methods[] = { - /* device interface */ - DEVMETHOD(device_probe, ata_zbbus_probe), - DEVMETHOD(device_attach, ata_zbbus_attach), - DEVMETHOD(device_detach, ata_zbbus_detach), - DEVMETHOD(device_suspend, ata_zbbus_suspend), - DEVMETHOD(device_resume, ata_zbbus_resume), - - { 0, 0 } -}; - -static driver_t ata_zbbus_driver = { - "ata", - ata_zbbus_methods, - sizeof(struct ata_channel) -}; - -DRIVER_MODULE(ata, zbbus, ata_zbbus_driver, ata_devclass, 0, 0); Index: sys/mips/sibyte/files.sibyte =================================================================== --- sys/mips/sibyte/files.sibyte +++ /dev/null @@ -1,10 +0,0 @@ -# $FreeBSD$ - -mips/sibyte/sb_machdep.c standard -mips/sibyte/sb_zbbus.c standard -mips/sibyte/sb_zbpci.c standard -mips/sibyte/sb_scd.c standard -mips/sibyte/ata_zbbus.c standard -mips/mips/intr_machdep.c standard -mips/sibyte/sb_asm.S standard -mips/mips/tick.c standard Index: sys/mips/sibyte/sb_asm.S =================================================================== --- sys/mips/sibyte/sb_asm.S +++ /dev/null @@ -1,51 +0,0 @@ -/*- - * Copyright (c) 2009 Neelkanth Natu - * 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$ - */ - -#include -#include - -.set mips64 -.set noat -.set noreorder - -#ifdef SMP -/* - * This function must be implemented in assembly because it is called early - * in AP boot without a valid stack. - * - * This cpu number is available in bits 25 to 27 of the coprocessor 0 PRID - * register. This is not documented in the BCM1250 user manual but can be - * gleaned from the CFE source code - see sb1250_altcpu.S - */ -LEAF(platform_processor_id) - mfc0 v0, MIPS_COP_0_PRID - srl v0, v0, 25 - jr ra - and v0, v0, 7 -END(platform_processor_id) -#endif /* SMP */ Index: sys/mips/sibyte/sb_bus_space.h =================================================================== --- sys/mips/sibyte/sb_bus_space.h +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010 Neelkanth Natu - * 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 _SB_BUS_SPACE_H_ -#define _SB_BUS_SPACE_H_ - -#include - -#if _BYTE_ORDER == _BIG_ENDIAN -uint8_t sb_big_endian_read8(bus_addr_t addr); -uint16_t sb_big_endian_read16(bus_addr_t addr); -uint32_t sb_big_endian_read32(bus_addr_t addr); -void sb_big_endian_write8(bus_addr_t addr, uint8_t val); -void sb_big_endian_write16(bus_addr_t addr, uint16_t val); -void sb_big_endian_write32(bus_addr_t addr, uint32_t val); -#endif - -#endif Index: sys/mips/sibyte/sb_machdep.c =================================================================== --- sys/mips/sibyte/sb_machdep.c +++ /dev/null @@ -1,441 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2007 Bruce M. Simpson. - * 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 "opt_ddb.h" -#include "opt_kdb.h" - -#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 - -#ifdef SMP -#include -#include -#endif - -#ifdef CFE -#include -#endif - -#include "sb_scd.h" - -#ifdef DDB -#ifndef KDB -#error KDB must be enabled in order for DDB to work! -#endif -#endif - -#ifdef CFE_ENV -extern void cfe_env_init(void); -#endif - -extern int *edata; -extern int *end; - -extern char MipsTLBMiss[], MipsTLBMissEnd[]; - -void -platform_cpu_init() -{ - /* Nothing special */ -} - -static void -sb_intr_init(int cpuid) -{ - int intrnum, intsrc; - - /* - * Disable all sources to the interrupt mapper and setup the mapping - * between an interrupt source and the mips hard interrupt number. - */ - for (intsrc = 0; intsrc < NUM_INTSRC; ++intsrc) { - intrnum = sb_route_intsrc(intsrc); - sb_disable_intsrc(cpuid, intsrc); - sb_write_intmap(cpuid, intsrc, intrnum); -#ifdef SMP - /* - * Set up the mailbox interrupt mapping. - * - * The mailbox interrupt is "special" in that it is not shared - * with any other interrupt source. - */ - if (intsrc == INTSRC_MAILBOX3) { - intrnum = platform_ipi_hardintr_num(); - sb_write_intmap(cpuid, INTSRC_MAILBOX3, intrnum); - sb_enable_intsrc(cpuid, INTSRC_MAILBOX3); - } -#endif - } -} - -static void -mips_init(void) -{ - int i, j, cfe_mem_idx, tmp; - uint64_t maxmem; - -#ifdef CFE_ENV - cfe_env_init(); -#endif - - TUNABLE_INT_FETCH("boothowto", &boothowto); - - if (boothowto & RB_VERBOSE) - bootverbose++; - -#ifdef MAXMEM - tmp = MAXMEM; -#else - tmp = 0; -#endif - TUNABLE_INT_FETCH("hw.physmem", &tmp); - maxmem = (uint64_t)tmp * 1024; - - /* - * XXX - * If we used vm_paddr_t consistently in pmap, etc., we could - * use 64-bit page numbers on !n64 systems, too, like i386 - * does with PAE. - */ -#if !defined(__mips_n64) - if (maxmem == 0 || maxmem > 0xffffffff) - maxmem = 0xffffffff; -#endif - -#ifdef CFE - /* - * Query DRAM memory map from CFE. - */ - physmem = 0; - cfe_mem_idx = 0; - for (i = 0; i < 10; i += 2) { - int result; - uint64_t addr, len, type; - - result = cfe_enummem(cfe_mem_idx++, 0, &addr, &len, &type); - if (result < 0) { - phys_avail[i] = phys_avail[i + 1] = 0; - break; - } - - KASSERT(type == CFE_MI_AVAILABLE, - ("CFE DRAM region is not available?")); - - if (bootverbose) - printf("cfe_enummem: 0x%016jx/%ju.\n", addr, len); - - if (maxmem != 0) { - if (addr >= maxmem) { - printf("Ignoring %ju bytes of memory at 0x%jx " - "that is above maxmem %dMB\n", - len, addr, - (int)(maxmem / (1024 * 1024))); - continue; - } - - if (addr + len > maxmem) { - printf("Ignoring %ju bytes of memory " - "that is above maxmem %dMB\n", - (addr + len) - maxmem, - (int)(maxmem / (1024 * 1024))); - len = maxmem - addr; - } - } - - phys_avail[i] = addr; - if (i == 0 && addr == 0) { - /* - * If this is the first physical memory segment probed - * from CFE, omit the region at the start of physical - * memory where the kernel has been loaded. - */ - phys_avail[i] += MIPS_KSEG0_TO_PHYS(kernel_kseg0_end); - } - phys_avail[i + 1] = addr + len; - physmem += len; - } - - realmem = btoc(physmem); -#endif - - for (j = 0; j < i; j++) - dump_avail[j] = phys_avail[j]; - - physmem = realmem; - - init_param1(); - init_param2(physmem); - mips_cpu_init(); - - /* - * Sibyte has a L1 data cache coherent with DMA. This includes - * on-chip network interfaces as well as PCI/HyperTransport bus - * masters. - */ - cpuinfo.cache_coherent_dma = TRUE; - - /* - * XXX - * The kernel is running in 32-bit mode but the CFE is running in - * 64-bit mode. So the SR_KX bit in the status register is turned - * on by the CFE every time we call into it - for e.g. CFE_CONSOLE. - * - * This means that if get a TLB miss for any address above 0xc0000000 - * and the SR_KX bit is set then we will end up in the XTLB exception - * vector. - * - * For now work around this by copying the TLB exception handling - * code to the XTLB exception vector. - */ - { - bcopy(MipsTLBMiss, (void *)MIPS_XTLB_MISS_EXC_VEC, - MipsTLBMissEnd - MipsTLBMiss); - - mips_icache_sync_all(); - mips_dcache_wbinv_all(); - } - - pmap_bootstrap(); - mips_proc0_init(); - mutex_init(); - - kdb_init(); -#ifdef KDB - if (boothowto & RB_KDB) - kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); -#endif -} - -void -platform_reset(void) -{ - - /* - * XXX SMP - * XXX flush data caches - */ - sb_system_reset(); -} - -static void -kseg0_map_coherent(void) -{ - uint32_t config; - const int CFG_K0_COHERENT = 5; - - config = mips_rd_config(); - config &= ~MIPS_CONFIG_K0_MASK; - config |= CFG_K0_COHERENT; - mips_wr_config(config); -} - -#ifdef SMP -void -platform_ipi_send(int cpuid) -{ - KASSERT(cpuid == 0 || cpuid == 1, - ("platform_ipi_send: invalid cpuid %d", cpuid)); - - sb_set_mailbox(cpuid, 1ULL); -} - -void -platform_ipi_clear(void) -{ - int cpuid; - - cpuid = PCPU_GET(cpuid); - sb_clear_mailbox(cpuid, 1ULL); -} - -int -platform_ipi_hardintr_num(void) -{ - - return (4); -} - -int -platform_ipi_softintr_num(void) -{ - - return (-1); -} - -struct cpu_group * -platform_smp_topo(void) -{ - - return (smp_topo_none()); -} - -void -platform_init_ap(int cpuid) -{ - int ipi_int_mask, clock_int_mask; - - KASSERT(cpuid == 1, ("AP has an invalid cpu id %d", cpuid)); - - /* - * Make sure that kseg0 is mapped cacheable-coherent - */ - kseg0_map_coherent(); - - sb_intr_init(cpuid); - - /* - * Unmask the clock and ipi interrupts. - */ - clock_int_mask = hard_int_mask(5); - ipi_int_mask = hard_int_mask(platform_ipi_hardintr_num()); - set_intr_mask(ipi_int_mask | clock_int_mask); -} - -int -platform_start_ap(int cpuid) -{ -#ifdef CFE - int error; - - if ((error = cfe_cpu_start(cpuid, mpentry, 0, 0, 0))) { - printf("cfe_cpu_start error: %d\n", error); - return (-1); - } else { - return (0); - } -#else - return (-1); -#endif /* CFE */ -} -#endif /* SMP */ - -static u_int -sb_get_timecount(struct timecounter *tc) -{ - - return ((u_int)sb_zbbus_cycle_count()); -} - -static void -sb_timecounter_init(void) -{ - static struct timecounter sb_timecounter = { - sb_get_timecount, - NULL, - ~0u, - 0, - "sibyte_zbbus_counter", - 2000 - }; - - /* - * The ZBbus cycle counter runs at half the cpu frequency. - */ - sb_timecounter.tc_frequency = sb_cpu_speed() / 2; - platform_timecounter = &sb_timecounter; -} - -void -platform_start(__register_t a0, __register_t a1, __register_t a2, - __register_t a3) -{ - /* - * Make sure that kseg0 is mapped cacheable-coherent - */ - kseg0_map_coherent(); - - /* clear the BSS and SBSS segments */ - memset(&edata, 0, (vm_offset_t)&end - (vm_offset_t)&edata); - mips_postboot_fixup(); - - sb_intr_init(0); - sb_timecounter_init(); - - /* Initialize pcpu stuff */ - mips_pcpu0_init(); - -#ifdef CFE - /* - * Initialize CFE firmware trampolines before - * we initialize the low-level console. - * - * CFE passes the following values in registers: - * a0: firmware handle - * a2: firmware entry point - * a3: entry point seal - */ - if (a3 == CFE_EPTSEAL) - cfe_init(a0, a2); -#endif - cninit(); - - mips_init(); - - mips_timer_init_params(sb_cpu_speed(), 0); -} Index: sys/mips/sibyte/sb_scd.h =================================================================== --- sys/mips/sibyte/sb_scd.h +++ /dev/null @@ -1,54 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2009 Neelkanth Natu - * 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 _SB_SCD_H_ -#define _SB_SCD_H_ - -#define NUM_INTSRC 64 /* total number of interrupt sources */ - -uint64_t sb_zbbus_cycle_count(void); -uint64_t sb_cpu_speed(void); -void sb_system_reset(void); - -int sb_route_intsrc(int src); -void sb_enable_intsrc(int cpu, int src); -void sb_disable_intsrc(int cpu, int src); -uint64_t sb_read_intsrc_mask(int cpu); -void sb_write_intsrc_mask(int cpu, uint64_t mask); -void sb_write_intmap(int cpu, int intsrc, int intrnum); -int sb_read_intmap(int cpu, int intsrc); - -#ifdef SMP -#define INTSRC_MAILBOX3 29 -void sb_set_mailbox(int cpuid, uint64_t val); -void sb_clear_mailbox(int cpuid, uint64_t val); -#endif - -#endif /* _SB_SCD_H_ */ Index: sys/mips/sibyte/sb_scd.c =================================================================== --- sys/mips/sibyte/sb_scd.c +++ /dev/null @@ -1,308 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2009 Neelkanth Natu - * 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 "sb_scd.h" - -/* - * We compile a 32-bit kernel to run on the SB-1 processor which is a 64-bit - * processor. It has some registers that must be accessed using 64-bit load - * and store instructions. - * - * We use the mips_ld() and mips_sd() functions to do this for us. - */ -#define sb_store64(addr, val) mips3_sd((uint64_t *)(uintptr_t)(addr), (val)) -#define sb_load64(addr) mips3_ld((uint64_t *)(uintptr_t)(addr)) - -/* - * System Control and Debug (SCD) unit on the Sibyte ZBbus. - */ - -/* - * Extract the value starting at bit position 'b' for 'n' bits from 'x'. - */ -#define GET_VAL_64(x, b, n) (((x) >> (b)) & ((1ULL << (n)) - 1)) - -#define SYSREV_ADDR MIPS_PHYS_TO_KSEG1(0x10020000) -#define SYSREV_NUM_PROCESSORS(x) GET_VAL_64((x), 24, 4) - -#define SYSCFG_ADDR MIPS_PHYS_TO_KSEG1(0x10020008) -#define SYSCFG_PLLDIV(x) GET_VAL_64((x), 7, 5) - -#define ZBBUS_CYCLE_COUNT_ADDR MIPS_PHYS_TO_KSEG1(0x10030000) - -#define INTSRC_MASK_ADDR(cpu) \ - (MIPS_PHYS_TO_KSEG1(0x10020028) | ((cpu) << 13)) - -#define INTSRC_MAP_ADDR(cpu, intsrc) \ - (MIPS_PHYS_TO_KSEG1(0x10020200) | ((cpu) << 13)) + (intsrc * 8) - -#define MAILBOX_SET_ADDR(cpu) \ - (MIPS_PHYS_TO_KSEG1(0x100200C8) | ((cpu) << 13)) - -#define MAILBOX_CLEAR_ADDR(cpu) \ - (MIPS_PHYS_TO_KSEG1(0x100200D0) | ((cpu) << 13)) - -static uint64_t -sb_read_syscfg(void) -{ - - return (sb_load64(SYSCFG_ADDR)); -} - -static void -sb_write_syscfg(uint64_t val) -{ - - sb_store64(SYSCFG_ADDR, val); -} - -uint64_t -sb_zbbus_cycle_count(void) -{ - - return (sb_load64(ZBBUS_CYCLE_COUNT_ADDR)); -} - -uint64_t -sb_cpu_speed(void) -{ - int plldiv; - const uint64_t MHZ = 1000000; - - plldiv = SYSCFG_PLLDIV(sb_read_syscfg()); - if (plldiv == 0) { - printf("PLL_DIV is 0 - assuming 6 (300MHz).\n"); - plldiv = 6; - } - - return (plldiv * 50 * MHZ); -} - -void -sb_system_reset(void) -{ - uint64_t syscfg; - - const uint64_t SYSTEM_RESET = 1ULL << 60; - const uint64_t EXT_RESET = 1ULL << 59; - const uint64_t SOFT_RESET = 1ULL << 58; - - syscfg = sb_read_syscfg(); - syscfg &= ~SOFT_RESET; - syscfg |= SYSTEM_RESET | EXT_RESET; - sb_write_syscfg(syscfg); -} - -void -sb_disable_intsrc(int cpu, int src) -{ - int regaddr; - uint64_t val; - - regaddr = INTSRC_MASK_ADDR(cpu); - - val = sb_load64(regaddr); - val |= 1ULL << src; - sb_store64(regaddr, val); -} - -void -sb_enable_intsrc(int cpu, int src) -{ - int regaddr; - uint64_t val; - - regaddr = INTSRC_MASK_ADDR(cpu); - - val = sb_load64(regaddr); - val &= ~(1ULL << src); - sb_store64(regaddr, val); -} - -void -sb_write_intsrc_mask(int cpu, uint64_t val) -{ - int regaddr; - - regaddr = INTSRC_MASK_ADDR(cpu); - sb_store64(regaddr, val); -} - -uint64_t -sb_read_intsrc_mask(int cpu) -{ - int regaddr; - uint64_t val; - - regaddr = INTSRC_MASK_ADDR(cpu); - val = sb_load64(regaddr); - - return (val); -} - -void -sb_write_intmap(int cpu, int intsrc, int intrnum) -{ - int regaddr; - - regaddr = INTSRC_MAP_ADDR(cpu, intsrc); - sb_store64(regaddr, intrnum); -} - -int -sb_read_intmap(int cpu, int intsrc) -{ - int regaddr; - - regaddr = INTSRC_MAP_ADDR(cpu, intsrc); - return (sb_load64(regaddr) & 0x7); -} - -int -sb_route_intsrc(int intsrc) -{ - int intrnum; - - KASSERT(intsrc >= 0 && intsrc < NUM_INTSRC, - ("Invalid interrupt source number (%d)", intsrc)); - - /* - * Interrupt 5 is used by sources internal to the CPU (e.g. timer). - * Use a deterministic mapping for the remaining sources. - */ -#ifdef SMP - KASSERT(platform_ipi_hardintr_num() == 4, - ("Unexpected interrupt number used for IPI")); - intrnum = intsrc % 4; -#else - intrnum = intsrc % 5; -#endif - - return (intrnum); -} - -#ifdef SMP -static uint64_t -sb_read_sysrev(void) -{ - - return (sb_load64(SYSREV_ADDR)); -} - -void -sb_set_mailbox(int cpu, uint64_t val) -{ - int regaddr; - - regaddr = MAILBOX_SET_ADDR(cpu); - sb_store64(regaddr, val); -} - -void -sb_clear_mailbox(int cpu, uint64_t val) -{ - int regaddr; - - regaddr = MAILBOX_CLEAR_ADDR(cpu); - sb_store64(regaddr, val); -} - -void -platform_cpu_mask(cpuset_t *mask) -{ - int i, s; - - CPU_ZERO(mask); - s = SYSREV_NUM_PROCESSORS(sb_read_sysrev()); - for (i = 0; i < s; i++) - CPU_SET(i, mask); -} -#endif /* SMP */ - -#define SCD_PHYSADDR 0x10000000 -#define SCD_SIZE 0x00060000 - -static int -scd_probe(device_t dev) -{ - - device_set_desc(dev, "Broadcom/Sibyte System Control and Debug"); - return (0); -} - -static int -scd_attach(device_t dev) -{ - int rid; - struct resource *res; - - if (bootverbose) - device_printf(dev, "attached.\n"); - - rid = 0; - res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, SCD_PHYSADDR, - SCD_PHYSADDR + SCD_SIZE - 1, SCD_SIZE, 0); - if (res == NULL) - panic("Cannot allocate resource for system control and debug."); - - return (0); -} - -static device_method_t scd_methods[] ={ - /* Device interface */ - DEVMETHOD(device_probe, scd_probe), - DEVMETHOD(device_attach, scd_attach), - DEVMETHOD(device_detach, bus_generic_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - - { 0, 0 } -}; - -static driver_t scd_driver = { - "scd", - scd_methods -}; - -static devclass_t scd_devclass; - -DRIVER_MODULE(scd, zbbus, scd_driver, scd_devclass, 0, 0); Index: sys/mips/sibyte/sb_zbbus.c =================================================================== --- sys/mips/sibyte/sb_zbbus.c +++ /dev/null @@ -1,464 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2009 Neelkanth Natu - * 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 "sb_scd.h" - -static MALLOC_DEFINE(M_INTMAP, "sb1250 intmap", "Sibyte 1250 Interrupt Mapper"); - -static struct mtx zbbus_intr_mtx; -MTX_SYSINIT(zbbus_intr_mtx, &zbbus_intr_mtx, "zbbus_intr_mask/unmask lock", - MTX_SPIN); - -/* - * This array holds the mapping between a MIPS hard interrupt and the - * interrupt sources that feed into that it. - */ -static uint64_t hardint_to_intsrc_mask[NHARD_IRQS]; - -struct sb_intmap { - int intsrc; /* interrupt mapper register number (0 - 63) */ - int hardint; /* cpu interrupt from 0 to NHARD_IRQS - 1 */ - - /* - * The device that the interrupt belongs to. Note that multiple - * devices may share an interrupt. For e.g. PCI_INT_x lines. - * - * The device 'dev' in combination with the 'rid' uniquely - * identify this interrupt source. - */ - device_t dev; - int rid; - - SLIST_ENTRY(sb_intmap) next; -}; - -static SLIST_HEAD(, sb_intmap) sb_intmap_head; - -static struct sb_intmap * -sb_intmap_lookup(int intrnum, device_t dev, int rid) -{ - struct sb_intmap *map; - - SLIST_FOREACH(map, &sb_intmap_head, next) { - if (dev == map->dev && rid == map->rid && - intrnum == map->hardint) - break; - } - return (map); -} - -/* - * Keep track of which (dev,rid,hardint) tuple is using the interrupt source. - * - * We don't actually unmask the interrupt source until the device calls - * a bus_setup_intr() on the resource. - */ -static void -sb_intmap_add(int intrnum, device_t dev, int rid, int intsrc) -{ - struct sb_intmap *map; - - KASSERT(intrnum >= 0 && intrnum < NHARD_IRQS, - ("intrnum is out of range: %d", intrnum)); - - map = sb_intmap_lookup(intrnum, dev, rid); - if (map) { - KASSERT(intsrc == map->intsrc, - ("%s%d allocating SYS_RES_IRQ resource with rid %d " - "with a different intsrc (%d versus %d)", - device_get_name(dev), device_get_unit(dev), rid, - intsrc, map->intsrc)); - return; - } - - map = malloc(sizeof(*map), M_INTMAP, M_WAITOK | M_ZERO); - map->intsrc = intsrc; - map->hardint = intrnum; - map->dev = dev; - map->rid = rid; - - SLIST_INSERT_HEAD(&sb_intmap_head, map, next); -} - -static void -sb_intmap_activate(int intrnum, device_t dev, int rid) -{ - struct sb_intmap *map; - - KASSERT(intrnum >= 0 && intrnum < NHARD_IRQS, - ("intrnum is out of range: %d", intrnum)); - - map = sb_intmap_lookup(intrnum, dev, rid); - if (map) { - /* - * Deliver all interrupts to CPU0. - */ - mtx_lock_spin(&zbbus_intr_mtx); - hardint_to_intsrc_mask[intrnum] |= 1ULL << map->intsrc; - sb_enable_intsrc(0, map->intsrc); - mtx_unlock_spin(&zbbus_intr_mtx); - } else { - /* - * In zbbus_setup_intr() we blindly call sb_intmap_activate() - * for every interrupt activation that comes our way. - * - * We might end up here if we did not "hijack" the SYS_RES_IRQ - * resource in zbbus_alloc_resource(). - */ - printf("sb_intmap_activate: unable to activate interrupt %d " - "for device %s%d rid %d.\n", intrnum, - device_get_name(dev), device_get_unit(dev), rid); - } -} - -/* - * Replace the default interrupt mask and unmask routines in intr_machdep.c - * with routines that are SMP-friendly. In contrast to the default mask/unmask - * routines in intr_machdep.c these routines do not change the SR.int_mask bits. - * - * Instead they use the interrupt mapper to either mask or unmask all - * interrupt sources feeding into a particular interrupt line of the processor. - * - * This means that these routines have an identical effect irrespective of - * which cpu is executing them. This is important because the ithread may - * be scheduled to run on either of the cpus. - */ -static void -zbbus_intr_mask(void *arg) -{ - uint64_t mask; - int irq; - - irq = (uintptr_t)arg; - - mtx_lock_spin(&zbbus_intr_mtx); - - mask = sb_read_intsrc_mask(0); - mask |= hardint_to_intsrc_mask[irq]; - sb_write_intsrc_mask(0, mask); - - mtx_unlock_spin(&zbbus_intr_mtx); -} - -static void -zbbus_intr_unmask(void *arg) -{ - uint64_t mask; - int irq; - - irq = (uintptr_t)arg; - - mtx_lock_spin(&zbbus_intr_mtx); - - mask = sb_read_intsrc_mask(0); - mask &= ~hardint_to_intsrc_mask[irq]; - sb_write_intsrc_mask(0, mask); - - mtx_unlock_spin(&zbbus_intr_mtx); -} - -struct zbbus_devinfo { - struct resource_list resources; -}; - -static MALLOC_DEFINE(M_ZBBUSDEV, "zbbusdev", "zbbusdev"); - -static int -zbbus_probe(device_t dev) -{ - - device_set_desc(dev, "Broadcom/Sibyte ZBbus"); - return (BUS_PROBE_NOWILDCARD); -} - -static int -zbbus_attach(device_t dev) -{ - - if (bootverbose) { - device_printf(dev, "attached.\n"); - } - - cpu_set_hardintr_mask_func(zbbus_intr_mask); - cpu_set_hardintr_unmask_func(zbbus_intr_unmask); - - bus_generic_probe(dev); - bus_enumerate_hinted_children(dev); - bus_generic_attach(dev); - - return (0); -} - -static void -zbbus_hinted_child(device_t bus, const char *dname, int dunit) -{ - device_t child; - long maddr, msize; - int err, irq; - - if (resource_disabled(dname, dunit)) - return; - - child = BUS_ADD_CHILD(bus, 0, dname, dunit); - if (child == NULL) { - panic("zbbus: could not add child %s unit %d\n", dname, dunit); - } - - if (bootverbose) - device_printf(bus, "Adding hinted child %s%d\n", dname, dunit); - - /* - * Assign any pre-defined resources to the child. - */ - if (resource_long_value(dname, dunit, "msize", &msize) == 0 && - resource_long_value(dname, dunit, "maddr", &maddr) == 0) { - if (bootverbose) { - device_printf(bus, "Assigning memory resource " - "0x%0lx/%ld to child %s%d\n", - maddr, msize, dname, dunit); - } - err = bus_set_resource(child, SYS_RES_MEMORY, 0, maddr, msize); - if (err) { - device_printf(bus, "Unable to set memory resource " - "0x%0lx/%ld for child %s%d: %d\n", - maddr, msize, dname, dunit, err); - } - } - - if (resource_int_value(dname, dunit, "irq", &irq) == 0) { - if (bootverbose) { - device_printf(bus, "Assigning irq resource %d to " - "child %s%d\n", irq, dname, dunit); - } - err = bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1); - if (err) { - device_printf(bus, "Unable to set irq resource %d" - "for child %s%d: %d\n", - irq, dname, dunit, err); - } - } -} - -static struct resource * -zbbus_alloc_resource(device_t bus, device_t child, int type, int *rid, - rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) -{ - struct resource *res; - int intrnum, intsrc, isdefault; - struct resource_list *rl; - struct resource_list_entry *rle; - struct zbbus_devinfo *dinfo; - - isdefault = (RMAN_IS_DEFAULT_RANGE(start, end) && count == 1); - - /* - * Our direct child is asking for a default resource allocation. - */ - if (device_get_parent(child) == bus) { - dinfo = device_get_ivars(child); - rl = &dinfo->resources; - rle = resource_list_find(rl, type, *rid); - if (rle) { - if (rle->res) - panic("zbbus_alloc_resource: resource is busy"); - if (isdefault) { - start = rle->start; - count = ulmax(count, rle->count); - end = ulmax(rle->end, start + count - 1); - } - } else { - if (isdefault) { - /* - * Our child is requesting a default - * resource allocation but we don't have the - * 'type/rid' tuple in the resource list. - * - * We have to fail the resource allocation. - */ - return (NULL); - } else { - /* - * The child is requesting a non-default - * resource. We just pass the request up - * to our parent. If the resource allocation - * succeeds we will create a resource list - * entry corresponding to that resource. - */ - } - } - } else { - rl = NULL; - rle = NULL; - } - - /* - * nexus doesn't know about the interrupt mapper and only wants to - * see the hard irq numbers [0-6]. We translate from the interrupt - * source presented to the mapper to the interrupt number presented - * to the cpu. - */ - if ((count == 1) && (type == SYS_RES_IRQ)) { - intsrc = start; - intrnum = sb_route_intsrc(intsrc); - start = end = intrnum; - } else { - intsrc = -1; /* satisfy gcc */ - intrnum = -1; - } - - res = bus_generic_alloc_resource(bus, child, type, rid, - start, end, count, flags); - - /* - * Keep track of the input into the interrupt mapper that maps - * to the resource allocated by 'child' with resource id 'rid'. - * - * If we don't record the mapping here then we won't be able to - * locate the interrupt source when bus_setup_intr(child,rid) is - * called. - */ - if (res != NULL && intrnum != -1) - sb_intmap_add(intrnum, child, rman_get_rid(res), intsrc); - - /* - * If a non-default resource allocation by our child was successful - * then keep track of the resource in the resource list associated - * with the child. - */ - if (res != NULL && rle == NULL && device_get_parent(child) == bus) { - resource_list_add(rl, type, *rid, start, end, count); - rle = resource_list_find(rl, type, *rid); - if (rle == NULL) - panic("zbbus_alloc_resource: cannot find resource"); - } - - if (rle != NULL) { - KASSERT(device_get_parent(child) == bus, - ("rle should be NULL for passthru device")); - rle->res = res; - if (rle->res) { - rle->start = rman_get_start(rle->res); - rle->end = rman_get_end(rle->res); - rle->count = count; - } - } - - return (res); -} - -static int -zbbus_setup_intr(device_t dev, device_t child, struct resource *irq, int flags, - driver_filter_t *filter, driver_intr_t *intr, void *arg, - void **cookiep) -{ - int error; - - error = bus_generic_setup_intr(dev, child, irq, flags, - filter, intr, arg, cookiep); - if (error == 0) - sb_intmap_activate(rman_get_start(irq), child, - rman_get_rid(irq)); - - return (error); -} - -static device_t -zbbus_add_child(device_t bus, u_int order, const char *name, int unit) -{ - device_t child; - struct zbbus_devinfo *dinfo; - - child = device_add_child_ordered(bus, order, name, unit); - if (child != NULL) { - dinfo = malloc(sizeof(struct zbbus_devinfo), M_ZBBUSDEV, - M_WAITOK | M_ZERO); - resource_list_init(&dinfo->resources); - device_set_ivars(child, dinfo); - } - - return (child); -} - -static struct resource_list * -zbbus_get_resource_list(device_t dev, device_t child) -{ - struct zbbus_devinfo *dinfo = device_get_ivars(child); - - return (&dinfo->resources); -} - -static device_method_t zbbus_methods[] ={ - /* Device interface */ - DEVMETHOD(device_probe, zbbus_probe), - DEVMETHOD(device_attach, zbbus_attach), - DEVMETHOD(device_detach, bus_generic_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - - /* Bus interface */ - DEVMETHOD(bus_alloc_resource, zbbus_alloc_resource), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), - DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), - DEVMETHOD(bus_release_resource, bus_generic_release_resource), - DEVMETHOD(bus_get_resource_list,zbbus_get_resource_list), - DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), - DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), - DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource), - DEVMETHOD(bus_setup_intr, zbbus_setup_intr), - DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), - DEVMETHOD(bus_add_child, zbbus_add_child), - DEVMETHOD(bus_hinted_child, zbbus_hinted_child), - - { 0, 0 } -}; - -static driver_t zbbus_driver = { - "zbbus", - zbbus_methods -}; - -static devclass_t zbbus_devclass; - -DRIVER_MODULE(zbbus, nexus, zbbus_driver, zbbus_devclass, 0, 0); Index: sys/mips/sibyte/sb_zbpci.c =================================================================== --- sys/mips/sibyte/sb_zbpci.c +++ /dev/null @@ -1,545 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2009 Neelkanth Natu - * 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 "pcib_if.h" - -#include "sb_bus_space.h" -#include "sb_scd.h" - -__FBSDID("$FreeBSD$"); - -static struct { - vm_offset_t vaddr; - vm_paddr_t paddr; -} zbpci_config_space[MAXCPU]; - -static const vm_paddr_t CFG_PADDR_BASE = 0xFE000000; -static const u_long PCI_IOSPACE_ADDR = 0xFC000000; -static const u_long PCI_IOSPACE_SIZE = 0x02000000; - -#define PCI_MATCH_BYTE_LANES_START 0x40000000 -#define PCI_MATCH_BYTE_LANES_END 0x5FFFFFFF -#define PCI_MATCH_BYTE_LANES_SIZE 0x20000000 - -#define PCI_MATCH_BIT_LANES_MASK (1 << 29) -#define PCI_MATCH_BIT_LANES_START 0x60000000 -#define PCI_MATCH_BIT_LANES_END 0x7FFFFFFF -#define PCI_MATCH_BIT_LANES_SIZE 0x20000000 - -static struct rman port_rman; - -static int -zbpci_probe(device_t dev) -{ - - device_set_desc(dev, "Broadcom/Sibyte PCI I/O Bridge"); - return (0); -} - -static int -zbpci_attach(device_t dev) -{ - int n, rid, size; - vm_offset_t va; - struct resource *res; - - /* - * Reserve the physical memory window used to map PCI I/O space. - */ - rid = 0; - res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, - PCI_IOSPACE_ADDR, - PCI_IOSPACE_ADDR + PCI_IOSPACE_SIZE - 1, - PCI_IOSPACE_SIZE, 0); - if (res == NULL) - panic("Cannot allocate resource for PCI I/O space mapping."); - - port_rman.rm_start = 0; - port_rman.rm_end = PCI_IOSPACE_SIZE - 1; - port_rman.rm_type = RMAN_ARRAY; - port_rman.rm_descr = "PCI I/O ports"; - if (rman_init(&port_rman) != 0 || - rman_manage_region(&port_rman, 0, PCI_IOSPACE_SIZE - 1) != 0) - panic("%s: port_rman", __func__); - - /* - * Reserve the physical memory that is used to read/write to the - * pci config space but don't activate it. We are using a page worth - * of KVA as a window over this region. - */ - rid = 1; - size = (PCI_BUSMAX + 1) * (PCI_SLOTMAX + 1) * (PCI_FUNCMAX + 1) * 256; - res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, CFG_PADDR_BASE, - CFG_PADDR_BASE + size - 1, size, 0); - if (res == NULL) - panic("Cannot allocate resource for config space accesses."); - - /* - * Allocate the entire "match bit lanes" address space. - */ -#if _BYTE_ORDER == _BIG_ENDIAN - rid = 2; - res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, - PCI_MATCH_BIT_LANES_START, - PCI_MATCH_BIT_LANES_END, - PCI_MATCH_BIT_LANES_SIZE, 0); - if (res == NULL) - panic("Cannot allocate resource for pci match bit lanes."); -#endif /* _BYTE_ORDER ==_BIG_ENDIAN */ - - /* - * Allocate KVA for accessing PCI config space. - */ - va = kva_alloc(PAGE_SIZE * mp_ncpus); - if (va == 0) { - device_printf(dev, "Cannot allocate virtual addresses for " - "config space access.\n"); - return (ENOMEM); - } - - for (n = 0; n < mp_ncpus; ++n) - zbpci_config_space[n].vaddr = va + n * PAGE_SIZE; - - /* - * Sibyte has the PCI bus hierarchy rooted at bus 0 and HT-PCI - * hierarchy rooted at bus 1. - */ - if (device_add_child(dev, "pci", 0) == NULL) - panic("zbpci_attach: could not add pci bus 0.\n"); - - if (device_add_child(dev, "pci", 1) == NULL) - panic("zbpci_attach: could not add pci bus 1.\n"); - - if (bootverbose) - device_printf(dev, "attached.\n"); - - return (bus_generic_attach(dev)); -} - -static struct resource * -zbpci_alloc_resource(device_t bus, device_t child, int type, int *rid, - rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) -{ - struct resource *res; - - /* - * Handle PCI I/O port resources here and pass everything else to nexus. - */ - if (type != SYS_RES_IOPORT) { - res = bus_generic_alloc_resource(bus, child, type, rid, - start, end, count, flags); - return (res); - } - - res = rman_reserve_resource(&port_rman, start, end, count, - flags, child); - if (res == NULL) - return (NULL); - - rman_set_rid(res, *rid); - - /* Activate the resource is requested */ - if (flags & RF_ACTIVE) { - if (bus_activate_resource(child, type, *rid, res) != 0) { - rman_release_resource(res); - return (NULL); - } - } - - return (res); -} - -static int -zbpci_activate_resource(device_t bus, device_t child, int type, int rid, - struct resource *res) -{ - int error; - void *vaddr; - u_long orig_paddr, paddr, psize; - - paddr = rman_get_start(res); - psize = rman_get_size(res); - orig_paddr = paddr; - -#if _BYTE_ORDER == _BIG_ENDIAN - /* - * The CFE allocates PCI memory resources that map to the - * "match byte lanes" address space. This address space works - * best for DMA transfers because it does not do any automatic - * byte swaps when data crosses the pci-cpu interface. - * - * This also makes it sub-optimal for accesses to PCI device - * registers because it exposes the little-endian nature of - * the PCI bus to the big-endian CPU. The Sibyte has another - * address window called the "match bit lanes" window which - * automatically swaps bytes when data crosses the pci-cpu - * interface. - * - * We "assume" that any bus_space memory accesses done by the - * CPU to a PCI device are register/configuration accesses and - * are done through the "match bit lanes" window. Any DMA - * transfers will continue to be through the "match byte lanes" - * window because the PCI BAR registers will not be changed. - */ - if (type == SYS_RES_MEMORY) { - if (paddr >= PCI_MATCH_BYTE_LANES_START && - paddr + psize - 1 <= PCI_MATCH_BYTE_LANES_END) { - paddr |= PCI_MATCH_BIT_LANES_MASK; - rman_set_start(res, paddr); - rman_set_end(res, paddr + psize - 1); - } - } -#endif - - if (type != SYS_RES_IOPORT) { - error = bus_generic_activate_resource(bus, child, type, - rid, res); -#if _BYTE_ORDER == _BIG_ENDIAN - if (type == SYS_RES_MEMORY) { - rman_set_start(res, orig_paddr); - rman_set_end(res, orig_paddr + psize - 1); - } -#endif - return (error); - } - - /* - * Map the I/O space resource through the memory window starting - * at PCI_IOSPACE_ADDR. - */ - vaddr = pmap_mapdev(paddr + PCI_IOSPACE_ADDR, psize); - - rman_set_virtual(res, vaddr); - rman_set_bustag(res, mips_bus_space_generic); - rman_set_bushandle(res, (bus_space_handle_t)vaddr); - - return (rman_activate_resource(res)); -} - -static int -zbpci_release_resource(device_t bus, device_t child, int type, int rid, - struct resource *r) -{ - int error; - - if (type != SYS_RES_IOPORT) - return (bus_generic_release_resource(bus, child, type, rid, r)); - - if (rman_get_flags(r) & RF_ACTIVE) { - error = bus_deactivate_resource(child, type, rid, r); - if (error) - return (error); - } - - return (rman_release_resource(r)); -} - -static int -zbpci_deactivate_resource(device_t bus, device_t child, int type, int rid, - struct resource *r) -{ - vm_offset_t va; - - if (type != SYS_RES_IOPORT) { - return (bus_generic_deactivate_resource(bus, child, type, - rid, r)); - } - - va = (vm_offset_t)rman_get_virtual(r); - pmap_unmapdev(va, rman_get_size(r)); - - return (rman_deactivate_resource(r)); -} - -static int -zbpci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) -{ - - switch (which) { - case PCIB_IVAR_DOMAIN: - *result = 0; /* single PCI domain */ - return (0); - case PCIB_IVAR_BUS: - *result = device_get_unit(child); /* PCI bus 0 or 1 */ - return (0); - default: - return (ENOENT); - } -} - -/* - * We rely on the CFE to have configured the intline correctly to point to - * one of PCI-A/PCI-B/PCI-C/PCI-D in the interupt mapper. - */ -static int -zbpci_route_interrupt(device_t pcib, device_t dev, int pin) -{ - - return (PCI_INVALID_IRQ); -} - -/* - * This function is expected to be called in a critical section since it - * changes the per-cpu pci config space va-to-pa mappings. - */ -static vm_offset_t -zbpci_config_space_va(int bus, int slot, int func, int reg, int bytes) -{ - int cpu; - vm_offset_t va_page; - vm_paddr_t pa, pa_page; - - if (bus <= PCI_BUSMAX && slot <= PCI_SLOTMAX && func <= PCI_FUNCMAX && - reg <= PCI_REGMAX && (bytes == 1 || bytes == 2 || bytes == 4) && - ((reg & (bytes - 1)) == 0)) { - cpu = PCPU_GET(cpuid); - va_page = zbpci_config_space[cpu].vaddr; - pa = CFG_PADDR_BASE | - (bus << 16) | (slot << 11) | (func << 8) | reg; -#if _BYTE_ORDER == _BIG_ENDIAN - pa = pa ^ (4 - bytes); -#endif - pa_page = rounddown2(pa, PAGE_SIZE); - if (zbpci_config_space[cpu].paddr != pa_page) { - pmap_kremove(va_page); - pmap_kenter_attr(va_page, pa_page, PTE_C_UNCACHED); - zbpci_config_space[cpu].paddr = pa_page; - } - return (va_page + (pa - pa_page)); - } else { - return (0); - } -} - -static uint32_t -zbpci_read_config(device_t dev, u_int b, u_int s, u_int f, u_int r, int w) -{ - uint32_t data; - vm_offset_t va; - - critical_enter(); - - va = zbpci_config_space_va(b, s, f, r, w); - if (va == 0) { - panic("zbpci_read_config: invalid %d/%d/%d[%d] %d\n", - b, s, f, r, w); - } - - switch (w) { - case 4: - data = *(uint32_t *)va; - break; - case 2: - data = *(uint16_t *)va; - break; - case 1: - data = *(uint8_t *)va; - break; - default: - panic("zbpci_read_config: invalid width %d\n", w); - } - - critical_exit(); - - return (data); -} - -static void -zbpci_write_config(device_t d, u_int b, u_int s, u_int f, u_int r, - uint32_t data, int w) -{ - vm_offset_t va; - - critical_enter(); - - va = zbpci_config_space_va(b, s, f, r, w); - if (va == 0) { - panic("zbpci_write_config: invalid %d/%d/%d[%d] %d/%d\n", - b, s, f, r, data, w); - } - - switch (w) { - case 4: - *(uint32_t *)va = data; - break; - case 2: - *(uint16_t *)va = data; - break; - case 1: - *(uint8_t *)va = data; - break; - default: - panic("zbpci_write_config: invalid width %d\n", w); - } - - critical_exit(); -} - -static device_method_t zbpci_methods[] ={ - /* Device interface */ - DEVMETHOD(device_probe, zbpci_probe), - DEVMETHOD(device_attach, zbpci_attach), - DEVMETHOD(device_detach, bus_generic_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - - /* Bus interface */ - DEVMETHOD(bus_read_ivar, zbpci_read_ivar), - DEVMETHOD(bus_write_ivar, bus_generic_write_ivar), - DEVMETHOD(bus_alloc_resource, zbpci_alloc_resource), - DEVMETHOD(bus_activate_resource, zbpci_activate_resource), - DEVMETHOD(bus_deactivate_resource, zbpci_deactivate_resource), - DEVMETHOD(bus_release_resource, zbpci_release_resource), - DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), - DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), - DEVMETHOD(bus_add_child, bus_generic_add_child), - - /* pcib interface */ - DEVMETHOD(pcib_maxslots, pcib_maxslots), - DEVMETHOD(pcib_read_config, zbpci_read_config), - DEVMETHOD(pcib_write_config, zbpci_write_config), - DEVMETHOD(pcib_route_interrupt, zbpci_route_interrupt), - DEVMETHOD(pcib_request_feature, pcib_request_feature_allow), - - { 0, 0 } -}; - -/* - * The "zbpci" class inherits from the "pcib" base class. Therefore in - * addition to drivers that belong to the "zbpci" class we will also - * consider drivers belonging to the "pcib" when probing children of - * "zbpci". - */ -DEFINE_CLASS_1(zbpci, zbpci_driver, zbpci_methods, 0, pcib_driver); - -static devclass_t zbpci_devclass; - -DRIVER_MODULE(zbpci, zbbus, zbpci_driver, zbpci_devclass, 0, 0); - -/* - * Big endian bus space routines - */ -#if _BYTE_ORDER == _BIG_ENDIAN - -/* - * The CPU correctly deals with the big-endian to little-endian swap if - * we are accessing 4 bytes at a time. However if we want to read 1 or 2 - * bytes then we need to fudge the address generated by the CPU such that - * it generates the right byte enables on the PCI bus. - */ -static bus_addr_t -sb_match_bit_lane_addr(bus_addr_t addr, int bytes) -{ - vm_offset_t pa; - - pa = vtophys(addr); - - if (pa >= PCI_MATCH_BIT_LANES_START && pa <= PCI_MATCH_BIT_LANES_END) - return (addr ^ (4 - bytes)); - else - return (addr); -} - -uint8_t -sb_big_endian_read8(bus_addr_t addr) -{ - bus_addr_t addr2; - - addr2 = sb_match_bit_lane_addr(addr, 1); - return (readb(addr2)); -} - -uint16_t -sb_big_endian_read16(bus_addr_t addr) -{ - bus_addr_t addr2; - - addr2 = sb_match_bit_lane_addr(addr, 2); - return (readw(addr2)); -} - -uint32_t -sb_big_endian_read32(bus_addr_t addr) -{ - bus_addr_t addr2; - - addr2 = sb_match_bit_lane_addr(addr, 4); - return (readl(addr2)); -} - -void -sb_big_endian_write8(bus_addr_t addr, uint8_t val) -{ - bus_addr_t addr2; - - addr2 = sb_match_bit_lane_addr(addr, 1); - writeb(addr2, val); -} - -void -sb_big_endian_write16(bus_addr_t addr, uint16_t val) -{ - bus_addr_t addr2; - - addr2 = sb_match_bit_lane_addr(addr, 2); - writew(addr2, val); -} - -void -sb_big_endian_write32(bus_addr_t addr, uint32_t val) -{ - bus_addr_t addr2; - - addr2 = sb_match_bit_lane_addr(addr, 4); - writel(addr2, val); -} -#endif /* _BIG_ENDIAN */ Index: sys/mips/sibyte/std.sibyte =================================================================== --- sys/mips/sibyte/std.sibyte +++ /dev/null @@ -1,3 +0,0 @@ -# $FreeBSD$ - -files "../sibyte/files.sibyte"