Changeset View
Changeset View
Standalone View
Standalone View
sys/mips/broadcom/bcm_mipscore.c
Show All 40 Lines | |||||
#include <machine/bus.h> | #include <machine/bus.h> | ||||
#include <machine/resource.h> | #include <machine/resource.h> | ||||
#include <dev/bhnd/bhnd.h> | #include <dev/bhnd/bhnd.h> | ||||
#include <dev/bhnd/bhndvar.h> | #include <dev/bhnd/bhndvar.h> | ||||
#include <dev/bhnd/bhnd_ids.h> | #include <dev/bhnd/bhnd_ids.h> | ||||
#include <dev/bhnd/bcma/bcma_dmp.h> | |||||
#include "bcm_mipscore.h" | #include "bcm_mipscore.h" | ||||
static const struct resource_spec mipscore_rspec[MIPSCORE_MAX_RSPEC] = { | static const struct resource_spec mipscore_rspec[MIPSCORE_MAX_RSPEC] = { | ||||
{ SYS_RES_MEMORY, 0, RF_ACTIVE }, | { SYS_RES_MEMORY, 0, RF_ACTIVE }, | ||||
{ -1, -1, 0 } | { -1, -1, 0 } | ||||
}; | }; | ||||
#define MIPSCORE_DEV(_vendor, _core) \ | #define MIPSCORE_DEV(_vendor, _core) \ | ||||
BHND_DEVICE(_vendor, _core, NULL, NULL, BHND_DF_SOC) | BHND_DEVICE(_vendor, _core, NULL, NULL, BHND_DF_SOC) | ||||
#define BHND_MIPS74K_IRQN 5 | |||||
#define BHND_MIPS74K_IRQBASE 2 | |||||
struct bhnd_device mipscore_match[] = { | struct bhnd_device mipscore_match[] = { | ||||
MIPSCORE_DEV(BCM, MIPS), | MIPSCORE_DEV(BCM, MIPS), | ||||
MIPSCORE_DEV(BCM, MIPS33), | MIPSCORE_DEV(BCM, MIPS33), | ||||
MIPSCORE_DEV(MIPS, MIPS74K), | MIPSCORE_DEV(MIPS, MIPS74K), | ||||
BHND_DEVICE_END | BHND_DEVICE_END | ||||
}; | }; | ||||
static int | static int | ||||
Show All 9 Lines | mipscore_probe(device_t dev) | ||||
return (BUS_PROBE_DEFAULT); | return (BUS_PROBE_DEFAULT); | ||||
} | } | ||||
static int | static int | ||||
mipscore_attach(device_t dev) | mipscore_attach(device_t dev) | ||||
{ | { | ||||
struct mipscore_softc *sc; | struct mipscore_softc *sc; | ||||
struct resource *res; | struct resource *res; | ||||
uint32_t intmask; | device_t *children; | ||||
uint32_t tmp; | |||||
uint32_t intmasks[BHND_MIPS74K_IRQN]; | |||||
uint16_t devid; | uint16_t devid; | ||||
int error; | int error; | ||||
int offset, count; | |||||
int i, j; | |||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
devid = bhnd_get_device(dev); | devid = bhnd_get_device(dev); | ||||
sc->devid = devid; | sc->devid = devid; | ||||
sc->dev = dev; | sc->dev = dev; | ||||
/* Allocate bus resources */ | /* Allocate bus resources */ | ||||
memcpy(sc->rspec, mipscore_rspec, sizeof(sc->rspec)); | memcpy(sc->rspec, mipscore_rspec, sizeof(sc->rspec)); | ||||
error = bhnd_alloc_resources(dev, sc->rspec, sc->res); | error = bhnd_alloc_resources(dev, sc->rspec, sc->res); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
res = sc->res[0]->res; | res = sc->res[0]->res; | ||||
if (res == NULL) | if (res == NULL) | ||||
return (ENXIO); | return (ENXIO); | ||||
if (devid == BHND_COREID_MIPS74K) { | if (devid == BHND_COREID_MIPS74K) { | ||||
intmask = (1 << 31); | tmp = (1 << 31); | ||||
offset = offsetof(struct mipscore_regs, intmask[5]); | |||||
/* Use intmask5 register to route the timer interrupt */ | /* Use intmask5 register to route the timer interrupt */ | ||||
bus_write_4(res, offsetof(struct mipscore_regs, intmask[5]), | bus_write_4(res, offset, tmp); | ||||
intmask); | /* Use intmask0-4 to identify mapping IRQ to cores */ | ||||
offset = offsetof(struct mipscore_regs, intmask[0]); | |||||
/* scan IRQ masks of lines */ | |||||
for (i = 0; i < BHND_MIPS74K_IRQN; i++) { | |||||
intmasks[i] = bus_read_4(res, offset); | |||||
offset += sizeof(uint32_t); | |||||
} | |||||
error = device_get_children(device_get_parent(dev), &children, | |||||
&count); | |||||
if (error) { | |||||
BHND_ERROR_DEV(dev, "can't get list of BHND devices: %d", | |||||
error); | |||||
return (error); | |||||
} | |||||
for (i = 0; i < count; i++) { | |||||
tmp = bhnd_read_config(children[i], | |||||
BCMA_DMP_OOBSELOUTA30, sizeof(uint32_t)); | |||||
if (tmp == 0) | |||||
continue; | |||||
/* filter bits by LINE mask */ | |||||
tmp &= 0x1f; | |||||
/* calculate bitmask according to line number */ | |||||
tmp = (1 << tmp); | |||||
/* try find line in IRQ bit masks */ | |||||
for (j = 0; j < BHND_MIPS74K_IRQN; j++) { | |||||
if ((intmasks[j] & tmp) == 0) | |||||
continue; | |||||
BHND_INFO_DEV(dev, "%s: IRQ %d as rid 0", | |||||
bhnd_get_device_name(children[i]), | |||||
BHND_MIPS74K_IRQBASE + j); | |||||
bus_set_resource(children[i], SYS_RES_IRQ, 0, | |||||
BHND_MIPS74K_IRQBASE + j, 1); | |||||
break; | |||||
} | |||||
} | |||||
free(children, M_TEMP); | |||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
static device_method_t mipscore_methods[] = { | static device_method_t mipscore_methods[] = { | ||||
DEVMETHOD(device_probe, mipscore_probe), | DEVMETHOD(device_probe, mipscore_probe), | ||||
DEVMETHOD(device_attach, mipscore_attach), | DEVMETHOD(device_attach, mipscore_attach), | ||||
Show All 10 Lines |