[ar531x] add initial port for the AR231x/531x series of SoCs.
These are older MIPS4kc parts from Atheros. They typically ran at sub-200MHz and have 11bg, 11a, or 11abg wifi MAC/PHYs integrated. This port is the initial non-wifi pieces required to bring up the chip. I'll commit the redboot and other pieces later, and then hopefully(!) wifi support will follow. Submitted by: Mori Hiroki <yamori813@yahoo.co.jp> Differential Revision: https://reviews.freebsd.org/D7237
This commit is contained in:
parent
5420f76b59
commit
7c12b677f5
756
sys/mips/atheros/ar531x/apb.c
Normal file
756
sys/mips/atheros/ar531x/apb.c
Normal file
@ -0,0 +1,756 @@
|
||||
/*-
|
||||
* Copyright (c) 2016, Hiroki Mori
|
||||
* Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/interrupt.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/pcpu.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/pmc.h>
|
||||
#include <sys/pmckern.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#ifdef INTRNG
|
||||
#include <machine/intr.h>
|
||||
#else
|
||||
#include <machine/intr_machdep.h>
|
||||
#endif
|
||||
|
||||
#ifdef INTRNG
|
||||
#include "pic_if.h"
|
||||
|
||||
#define PIC_INTR_ISRC(sc, irq) (&(sc)->pic_irqs[(irq)].isrc)
|
||||
#endif
|
||||
|
||||
#include <mips/atheros/ar531x/apbvar.h>
|
||||
#include <mips/atheros/ar531x/ar5315reg.h>
|
||||
#include <mips/atheros/ar531x/ar5312reg.h>
|
||||
#include <mips/atheros/ar531x/ar5315_setup.h>
|
||||
|
||||
#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 == 0) {
|
||||
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 || TAILQ_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);
|
63
sys/mips/atheros/ar531x/apbvar.h
Normal file
63
sys/mips/atheros/ar531x/apbvar.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*-
|
||||
* Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice 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_ */
|
209
sys/mips/atheros/ar531x/ar5312_chip.c
Normal file
209
sys/mips/atheros/ar531x/ar5312_chip.c
Normal file
@ -0,0 +1,209 @@
|
||||
/*-
|
||||
* 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/cons.h>
|
||||
#include <sys/kdb.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_page.h>
|
||||
|
||||
#include <net/ethernet.h>
|
||||
|
||||
#include <machine/clock.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpuregs.h>
|
||||
#include <machine/hwfunc.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/trap.h>
|
||||
#include <machine/vmparam.h>
|
||||
|
||||
#include <mips/atheros/ar531x/ar5312reg.h>
|
||||
#include <mips/atheros/ar531x/ar5315reg.h>
|
||||
#include <mips/atheros/ar531x/ar5315_cpudef.h>
|
||||
#include <mips/atheros/ar531x/ar5315_setup.h>
|
||||
|
||||
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,
|
||||
};
|
34
sys/mips/atheros/ar531x/ar5312_chip.h
Normal file
34
sys/mips/atheros/ar531x/ar5312_chip.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*-
|
||||
* 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
|
239
sys/mips/atheros/ar531x/ar5312reg.h
Normal file
239
sys/mips/atheros/ar531x/ar5312reg.h
Normal file
@ -0,0 +1,239 @@
|
||||
/* $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 <dev/ath/ath_hal/ah_soc.h> /* 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_ */
|
256
sys/mips/atheros/ar531x/ar5315_chip.c
Normal file
256
sys/mips/atheros/ar531x/ar5315_chip.c
Normal file
@ -0,0 +1,256 @@
|
||||
/*-
|
||||
* 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/cons.h>
|
||||
#include <sys/kdb.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_page.h>
|
||||
|
||||
#include <net/ethernet.h>
|
||||
|
||||
#include <machine/clock.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpuregs.h>
|
||||
#include <machine/hwfunc.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/trap.h>
|
||||
#include <machine/vmparam.h>
|
||||
|
||||
#include <mips/atheros/ar531x/ar5315reg.h>
|
||||
#include <mips/atheros/ar531x/ar5315_chip.h>
|
||||
#include <mips/atheros/ar531x/ar5315_cpudef.h>
|
||||
|
||||
/* 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,
|
||||
};
|
34
sys/mips/atheros/ar531x/ar5315_chip.h
Normal file
34
sys/mips/atheros/ar531x/ar5315_chip.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*-
|
||||
* 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
|
139
sys/mips/atheros/ar531x/ar5315_cpudef.h
Normal file
139
sys/mips/atheros/ar531x/ar5315_cpudef.h
Normal file
@ -0,0 +1,139 @@
|
||||
/*-
|
||||
* 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
|
534
sys/mips/atheros/ar531x/ar5315_gpio.c
Normal file
534
sys/mips/atheros/ar531x/ar5315_gpio.c
Normal file
@ -0,0 +1,534 @@
|
||||
/*-
|
||||
* Copyright (c) 2016, Hiroki Mori
|
||||
* Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org>
|
||||
* 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/gpio.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <mips/atheros/ar531x/ar5315reg.h>
|
||||
#include <mips/atheros/ar531x/ar5315_cpudef.h>
|
||||
#include <mips/atheros/ar531x/ar5315_gpiovar.h>
|
||||
#include <dev/gpio/gpiobusvar.h>
|
||||
|
||||
#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.<pin>.gpiofunc=<func value>
|
||||
* hint.gpio.X.func.<pin>.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);
|
75
sys/mips/atheros/ar531x/ar5315_gpiovar.h
Normal file
75
sys/mips/atheros/ar531x/ar5315_gpiovar.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*-
|
||||
* Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org>
|
||||
* 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 <sys/timepps.h>
|
||||
|
||||
#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__ */
|
351
sys/mips/atheros/ar531x/ar5315_machdep.c
Normal file
351
sys/mips/atheros/ar531x/ar5315_machdep.c
Normal file
@ -0,0 +1,351 @@
|
||||
/*-
|
||||
* 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_ar531x.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/cons.h>
|
||||
#include <sys/kdb.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_page.h>
|
||||
|
||||
#include <net/ethernet.h>
|
||||
|
||||
#include <machine/clock.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpuregs.h>
|
||||
#include <machine/hwfunc.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/trap.h>
|
||||
#include <machine/vmparam.h>
|
||||
|
||||
#include <mips/atheros/ar531x/ar5315reg.h>
|
||||
|
||||
#include <mips/atheros/ar531x/ar5315_setup.h>
|
||||
#include <mips/atheros/ar531x/ar5315_cpudef.h>
|
||||
|
||||
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];
|
||||
|
||||
/*
|
||||
* We get a string in from Redboot with the all the arguments together,
|
||||
* "foo=bar bar=baz". Split them up and save in kenv.
|
||||
*/
|
||||
static void
|
||||
parse_argv(char *str)
|
||||
{
|
||||
char *n, *v;
|
||||
|
||||
while ((v = strsep(&str, " ")) != NULL) {
|
||||
if (*v == '\0')
|
||||
continue;
|
||||
if (*v == '-') {
|
||||
while (*v != '\0') {
|
||||
v++;
|
||||
switch (*v) {
|
||||
case 'a': boothowto |= RB_ASKNAME; break;
|
||||
case 'd': boothowto |= RB_KDB; break;
|
||||
case 'g': boothowto |= RB_GDB; break;
|
||||
case 's': boothowto |= RB_SINGLE; break;
|
||||
case 'v': boothowto |= RB_VERBOSE; break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
n = strsep(&v, "=");
|
||||
if (v == NULL)
|
||||
kern_setenv(n, "1");
|
||||
else
|
||||
kern_setenv(n, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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]);
|
||||
parse_argv(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
|
||||
|
||||
}
|
161
sys/mips/atheros/ar531x/ar5315_setup.c
Normal file
161
sys/mips/atheros/ar531x/ar5315_setup.c
Normal file
@ -0,0 +1,161 @@
|
||||
/*-
|
||||
* 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_ar531x.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/cons.h>
|
||||
#include <sys/kdb.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_page.h>
|
||||
|
||||
#include <net/ethernet.h>
|
||||
|
||||
#include <machine/clock.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpuregs.h>
|
||||
#include <machine/hwfunc.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/trap.h>
|
||||
#include <machine/vmparam.h>
|
||||
|
||||
#include <mips/atheros/ar531x/ar5315reg.h>
|
||||
#include <mips/atheros/ar531x/ar5312reg.h>
|
||||
#include <mips/atheros/ar531x/ar5315_setup.h>
|
||||
|
||||
#include <mips/atheros/ar531x/ar5315_cpudef.h>
|
||||
|
||||
#include <mips/atheros/ar531x/ar5315_chip.h>
|
||||
#include <mips/atheros/ar531x/ar5312_chip.h>
|
||||
#include <mips/atheros/ar724x_chip.h>
|
||||
#include <mips/atheros/ar91xx_chip.h>
|
||||
|
||||
#include <dev/ath/ath_hal/ah_soc.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
51
sys/mips/atheros/ar531x/ar5315_setup.h
Normal file
51
sys/mips/atheros/ar531x/ar5315_setup.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*-
|
||||
* 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
|
287
sys/mips/atheros/ar531x/ar5315_spi.c
Normal file
287
sys/mips/atheros/ar531x/ar5315_spi.c
Normal file
@ -0,0 +1,287 @@
|
||||
/*-
|
||||
* Copyright (c) 2016, Hiroki Mori
|
||||
* Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <sys/bus.h>
|
||||
#include <sys/interrupt.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <vm/vm_extern.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/pmap.h>
|
||||
|
||||
#include <dev/spibus/spi.h>
|
||||
#include <dev/spibus/spibusvar.h>
|
||||
#include "spibus_if.h"
|
||||
|
||||
#include <mips/atheros/ar531x/arspireg.h>
|
||||
#include <mips/atheros/ar531x/ar5315reg.h>
|
||||
|
||||
#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", 0);
|
||||
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;
|
||||
struct spibus_ivar *devi = SPIBUS_IVAR(child);
|
||||
int lin, lout;
|
||||
uint32_t ctl, cnt, op, rdat;
|
||||
int i, j;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
if (sc->sc_debug & 0x8000)
|
||||
printf("ar5315_spi_transfer: CMD ");
|
||||
|
||||
/* Open SPI controller interface */
|
||||
ar5315_spi_chip_activate(sc, devi->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, devi->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);
|
150
sys/mips/atheros/ar531x/ar5315_wdog.c
Normal file
150
sys/mips/atheros/ar531x/ar5315_wdog.c
Normal file
@ -0,0 +1,150 @@
|
||||
/*-
|
||||
* Copyright (c) 2016, Hiroki Mori
|
||||
* Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/watchdog.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <mips/atheros/ar531x/ar5315reg.h>
|
||||
#include <mips/atheros/ar531x/ar5315_cpudef.h>
|
||||
|
||||
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);
|
244
sys/mips/atheros/ar531x/ar5315reg.h
Normal file
244
sys/mips/atheros/ar531x/ar5315reg.h
Normal file
@ -0,0 +1,244 @@
|
||||
/* $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_ */
|
62
sys/mips/atheros/ar531x/arspireg.h
Normal file
62
sys/mips/atheros/ar531x/arspireg.h
Normal file
@ -0,0 +1,62 @@
|
||||
/* $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 */
|
30
sys/mips/atheros/ar531x/files.ar5315
Normal file
30
sys/mips/atheros/ar531x/files.ar5315
Normal file
@ -0,0 +1,30 @@
|
||||
# $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/intr_machdep.c standard
|
||||
mips/mips/tick.c standard
|
||||
|
||||
dev/etherswitch/e6000sw/e6060sw.c optional etherswitch
|
||||
dev/etherswitch/realtek/rtl830x.c optional etherswitch
|
||||
|
||||
# Hack to reuse ARM intrng code
|
||||
kern/subr_intr.c standard
|
||||
kern/msi_if.m standard
|
||||
kern/pic_if.m standard
|
||||
|
||||
# Intrng compatible MIPS32 interrupt controller
|
||||
mips/mips/mips_pic.c standard
|
||||
|
1685
sys/mips/atheros/ar531x/if_are.c
Normal file
1685
sys/mips/atheros/ar531x/if_are.c
Normal file
File diff suppressed because it is too large
Load Diff
401
sys/mips/atheros/ar531x/if_arereg.h
Normal file
401
sys/mips/atheros/ar531x/if_arereg.h
Normal file
@ -0,0 +1,401 @@
|
||||
/*-
|
||||
* Copyright (C) 2007
|
||||
* Oleksandr Tymoshenko <gonzo@freebsd.org>. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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_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;
|
||||
};
|
||||
|
||||
#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__ */
|
89
sys/mips/atheros/ar531x/uart_bus_ar5315.c
Normal file
89
sys/mips/atheros/ar531x/uart_bus_ar5315.c
Normal file
@ -0,0 +1,89 @@
|
||||
/*-
|
||||
* Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
*/
|
||||
#include "opt_uart.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/uart/uart.h>
|
||||
#include <dev/uart/uart_cpu.h>
|
||||
#include <dev/uart/uart_bus.h>
|
||||
|
||||
#include <mips/atheros/ar531x/ar5315reg.h>
|
||||
#include <mips/atheros/ar531x/ar5315_cpudef.h>
|
||||
|
||||
#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, freq, 0, 0));
|
||||
}
|
||||
|
||||
DRIVER_MODULE(uart, apb, uart_ar5315_driver, uart_devclass, 0, 0);
|
76
sys/mips/atheros/ar531x/uart_cpu_ar5315.c
Normal file
76
sys/mips/atheros/ar531x/uart_cpu_ar5315.c
Normal file
@ -0,0 +1,76 @@
|
||||
/*-
|
||||
* 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/uart/uart.h>
|
||||
#include <dev/uart/uart_cpu.h>
|
||||
|
||||
#include <mips/atheros/ar531x/ar5315reg.h>
|
||||
#include <mips/atheros/ar531x/ar5315_cpudef.h>
|
||||
#include <mips/atheros/ar71xx_bus_space_reversed.h>
|
||||
|
||||
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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user