void
omapmputmr_attach(device_t parent, device_t self, void *aux)
{
	struct omapmputmr_softc *sc = device_private(self);
	struct tipb_attach_args *tipb = aux;
	int ints_per_sec;

	sc->sc_iot = tipb->tipb_iot;
	sc->sc_intr = tipb->tipb_intr;

	if (bus_space_map(tipb->tipb_iot, tipb->tipb_addr, tipb->tipb_size, 0,
			 &sc->sc_ioh))
		panic("%s: Cannot map registers", device_xname(self));

	switch (device_unit(self)) {
	case 0:
		clock_sc = sc;
		ints_per_sec = hz;
		break;
	case 1:
		stat_sc = sc;
		ints_per_sec = profhz = stathz = STATHZ;
		break;
	case 2:
		ref_sc = sc;
		ints_per_sec = hz;	/* Same rate as clock */
		break;
	default:
		ints_per_sec = hz;	/* Better value? */
		break;
	}

	aprint_normal(": OMAP MPU Timer\n");
	aprint_naive("\n");

	/* Stop the timer from counting, but keep the timer module working. */
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, MPU_CNTL_TIMER,
			  MPU_CLOCK_ENABLE);

	timer_factors tf;
	calc_timer_factors(ints_per_sec, &tf);

	switch (device_unit(self)) {
	case 0:
		counts_per_hz = tf.reload + 1;
		counts_per_usec = tf.counts_per_usec;
		break;
	case 2:

		/*
		 * The microtime reference clock for all practical purposes
		 * just wraps around as an unsigned int.
		 */

		tf.reload = 0xffffffff;
		break;

	default:
		break;
	}

	/* Set the reload value. */
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, MPU_LOAD_TIMER, tf.reload);
	/* Set the PTV and the other required bits and pieces. */
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, MPU_CNTL_TIMER,
			  ( MPU_CLOCK_ENABLE
			    | (tf.ptv << MPU_PTV_SHIFT)
			    | MPU_AR
			    | MPU_ST));
	/* The clock is now running, but is not generating interrupts. */
}
Ejemplo n.º 2
0
void    
platform_mp_start_ap(void)
{
	bus_space_handle_t scu;
	bus_space_handle_t src;

	uint32_t val;
	int i;

	if (bus_space_map(fdtbus_bs_tag, SCU_PHYSBASE, SCU_SIZE, 0, &scu) != 0)
		panic("Couldn't map the SCU\n");
	if (bus_space_map(fdtbus_bs_tag, SRC_PHYSBASE, SRC_SIZE, 0, &src) != 0)
		panic("Couldn't map the system reset controller (SRC)\n");

	/*
	 * Invalidate SCU cache tags.  The 0x0000ffff constant invalidates all
	 * ways on all cores 0-3.  Per the ARM docs, it's harmless to write to
	 * the bits for cores that are not present.
	 */
	bus_space_write_4(fdtbus_bs_tag, scu, SCU_INV_TAGS_REG, 0x0000ffff);

	/*
	 * Erratum ARM/MP: 764369 (problems with cache maintenance).
	 * Setting the "disable-migratory bit" in the undocumented SCU
	 * Diagnostic Control Register helps work around the problem.
	 */
	val = bus_space_read_4(fdtbus_bs_tag, scu, SCU_DIAG_CONTROL);
	bus_space_write_4(fdtbus_bs_tag, scu, SCU_DIAG_CONTROL, 
	    val | SCU_DIAG_DISABLE_MIGBIT);

	/*
	 * Enable the SCU, then clean the cache on this core.  After these two
	 * operations the cache tag ram in the SCU is coherent with the contents
	 * of the cache on this core.  The other cores aren't running yet so
	 * their caches can't contain valid data yet, but we've initialized
	 * their SCU tag ram above, so they will be coherent from startup.
	 */
	val = bus_space_read_4(fdtbus_bs_tag, scu, SCU_CONTROL_REG);
	bus_space_write_4(fdtbus_bs_tag, scu, SCU_CONTROL_REG, 
	    val | SCU_CONTROL_ENABLE);
	cpu_idcache_wbinv_all();

	/*
	 * For each AP core, set the entry point address and argument registers,
	 * and set the core-enable and core-reset bits in the control register.
	 */
	val = bus_space_read_4(fdtbus_bs_tag, src, SRC_CONTROL_REG);
	for (i=1; i < mp_ncpus; i++) {
		bus_space_write_4(fdtbus_bs_tag, src, SRC_GPR0_C1FUNC + 8*i,
		    pmap_kextract((vm_offset_t)mpentry));
		bus_space_write_4(fdtbus_bs_tag, src, SRC_GPR1_C1ARG  + 8*i, 0);

		val |= ((1 << (SRC_CONTROL_C1ENA_SHIFT - 1 + i )) |
		    ( 1 << (SRC_CONTROL_C1RST_SHIFT - 1 + i)));

	}
	bus_space_write_4(fdtbus_bs_tag, src, 0, val);

	armv7_sev();

	bus_space_unmap(fdtbus_bs_tag, scu, SCU_SIZE);
	bus_space_unmap(fdtbus_bs_tag, src, SRC_SIZE);
}
Ejemplo n.º 3
0
static __inline void
WR4(struct ixpwdog_softc *sc, bus_size_t off, uint32_t val)
{
	bus_space_write_4(&ixp425_bs_tag, IXP425_TIMER_VBASE, off, val);
}
Ejemplo n.º 4
0
void
be_mcreset(struct be_softc *sc)
{
	struct ethercom *ec = &sc->sc_ethercom;
	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
	bus_space_tag_t t = sc->sc_bustag;
	bus_space_handle_t br = sc->sc_br;
	uint32_t v;
	uint32_t crc;
	uint16_t hash[4];
	struct ether_multi *enm;
	struct ether_multistep step;

	if (ifp->if_flags & IFF_PROMISC) {
		v = bus_space_read_4(t, br, BE_BRI_RXCFG);
		v |= BE_BR_RXCFG_PMISC;
		bus_space_write_4(t, br, BE_BRI_RXCFG, v);
		return;
	}

	if (ifp->if_flags & IFF_ALLMULTI) {
		hash[3] = hash[2] = hash[1] = hash[0] = 0xffff;
		goto chipit;
	}

	hash[3] = hash[2] = hash[1] = hash[0] = 0;

	ETHER_FIRST_MULTI(step, ec, enm);
	while (enm != NULL) {
		if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
			/*
			 * We must listen to a range of multicast
			 * addresses.  For now, just accept all
			 * multicasts, rather than trying to set only
			 * those filter bits needed to match the range.
			 * (At this time, the only use of address
			 * ranges is for IP multicast routing, for
			 * which the range is big enough to require
			 * all bits set.)
			 */
			hash[3] = hash[2] = hash[1] = hash[0] = 0xffff;
			ifp->if_flags |= IFF_ALLMULTI;
			goto chipit;
		}

		crc = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN);
		/* Just want the 6 most significant bits. */
		crc >>= 26;

		hash[crc >> 4] |= 1 << (crc & 0xf);
		ETHER_NEXT_MULTI(step, enm);
	}

	ifp->if_flags &= ~IFF_ALLMULTI;

chipit:
	/* Enable the hash filter */
	bus_space_write_4(t, br, BE_BRI_HASHTAB0, hash[0]);
	bus_space_write_4(t, br, BE_BRI_HASHTAB1, hash[1]);
	bus_space_write_4(t, br, BE_BRI_HASHTAB2, hash[2]);
	bus_space_write_4(t, br, BE_BRI_HASHTAB3, hash[3]);

	v = bus_space_read_4(t, br, BE_BRI_RXCFG);
	v &= ~BE_BR_RXCFG_PMISC;
	v |= BE_BR_RXCFG_HENABLE;
	bus_space_write_4(t, br, BE_BRI_RXCFG, v);
}
Ejemplo n.º 5
0
static void 
giopci_attach(struct device *parent, struct device *self, void *aux)
{
	struct giopci_softc *sc = (void *)self;
	pci_chipset_tag_t pc = &sc->sc_pc;
	struct gio_attach_args *ga = aux;
	uint32_t pci_off, pci_len, arb;
	struct pcibus_attach_args pba;
	u_long m_start, m_end;
#ifdef PCI_NETBSD_CONFIGURE
	extern int pci_conf_debug;

	pci_conf_debug = giopci_debug;
#endif

	sc->sc_iot	= ga->ga_iot;
	sc->sc_slot	= ga->ga_slot;
	sc->sc_gprid	= GIO_PRODUCT_PRODUCTID(ga->ga_product);

	if (mach_type == MACH_SGI_IP22 &&
	    mach_subtype == MACH_SGI_IP22_FULLHOUSE)
		arb = GIO_ARB_RT | GIO_ARB_MST | GIO_ARB_PIPE;
	else
		arb = GIO_ARB_RT | GIO_ARB_MST;

	if (gio_arb_config(ga->ga_slot, arb)) {
		printf(": failed to configure GIO bus arbiter\n");
		return;
	}

#if (NIMC > 0)
	imc_disable_sysad_parity();
#endif

	switch (sc->sc_gprid) {
	case PHOBOS_G100:
	case PHOBOS_G130:
	case PHOBOS_G160:
		pci_off = PHOBOS_PCI_OFFSET;
		pci_len = PHOBOS_PCI_LENGTH;
		m_start = MIPS_KSEG1_TO_PHYS(ga->ga_addr + PHOBOS_TULIP_START);
		m_end = MIPS_KSEG1_TO_PHYS(ga->ga_addr + PHOBOS_TULIP_END);
		break;

	case SETENG_GFE:
		/*
		 * NB: The SetEng board does not allow the ThunderLAN's DMA
		 *     engine to properly transfer segments that span page
		 *     boundaries. See sgimips/autoconf.c where we catch a
		 *     tl(4) device attachment and create an appropriate
		 *     proplib entry to enable the workaround.
		 */
		pci_off = SETENG_PCI_OFFSET;
		pci_len = SETENG_PCI_LENGTH;
		m_start = MIPS_KSEG1_TO_PHYS(ga->ga_addr + SETENG_TLAN_START);
		m_end = MIPS_KSEG1_TO_PHYS(ga->ga_addr + SETENG_TLAN_END);
		bus_space_write_4(ga->ga_iot, ga->ga_ioh,
		    SETENG_MAGIC_OFFSET, SETENG_MAGIC_VALUE);
		break;

	default:
		panic("giopci_attach: unsupported GIO product id 0x%02x",
		    sc->sc_gprid);
	}

	if (bus_space_subregion(ga->ga_iot, ga->ga_ioh, pci_off, pci_len,
	    &sc->sc_ioh)) {
		printf("%s: unable to map PCI registers\n",sc->sc_dev.dv_xname);
		return;
	}
	sc->sc_pci_len = pci_len;

	pc->pc_bus_maxdevs	= giopci_bus_maxdevs;
	pc->pc_conf_read	= giopci_conf_read;
	pc->pc_conf_write	= giopci_conf_write;
	pc->pc_conf_hook	= giopci_conf_hook;
	pc->pc_intr_map		= giopci_intr_map;
	pc->pc_intr_string	= giopci_intr_string;
	pc->intr_establish	= giopci_intr_establish;
	pc->intr_disestablish	= giopci_intr_disestablish;
	pc->iot			= ga->ga_iot;
	pc->ioh			= ga->ga_ioh;
	pc->cookie		= sc;

	printf(": %s\n", gio_product_string(sc->sc_gprid));

#ifdef PCI_NETBSD_CONFIGURE
	pc->pc_memext = extent_create("giopcimem", m_start, m_end,
	    M_DEVBUF, NULL, 0, EX_NOWAIT);
	pci_configure_bus(pc, NULL, pc->pc_memext, NULL, 0, mips_dcache_align);
#endif

	memset(&pba, 0, sizeof(pba));
	pba.pba_memt	= SGIMIPS_BUS_SPACE_MEM;
	pba.pba_dmat	= ga->ga_dmat;
	pba.pba_pc	= pc;
	pba.pba_flags	= PCI_FLAGS_MEM_ENABLED;
	/* NB: do not set PCI_FLAGS_{MRL,MRM,MWI}_OKAY  -- true ?! */

	config_found_ia(self, "pcibus", &pba, pcibusprint);
}
Ejemplo n.º 6
0
static int
fimd_attach(device_t dev)
{
	struct panel_info panel;
	struct fimd_softc *sc;
	device_t gpio_dev;
	int reg;

	sc = device_get_softc(dev);
	sc->dev = dev;

	if (bus_alloc_resources(dev, fimd_spec, sc->res)) {
		device_printf(dev, "could not allocate resources\n");
		return (ENXIO);
	}

	/* Memory interface */
	sc->bst = rman_get_bustag(sc->res[0]);
	sc->bsh = rman_get_bushandle(sc->res[0]);
	sc->bst_disp = rman_get_bustag(sc->res[1]);
	sc->bsh_disp = rman_get_bushandle(sc->res[1]);
	sc->bst_sysreg = rman_get_bustag(sc->res[2]);
	sc->bsh_sysreg = rman_get_bushandle(sc->res[2]);

	if (get_panel_info(sc, &panel)) {
		device_printf(dev, "Can't get panel info\n");
		return (ENXIO);
	}

	panel.fixvclk = 0;
	panel.ivclk = 0;
	panel.clkval_f = 2;

	sc->panel = &panel;

	/* Get the GPIO device, we need this to give power to USB */
	gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
	if (gpio_dev == NULL) {
		/* TODO */
	}

	reg = bus_space_read_4(sc->bst_sysreg, sc->bsh_sysreg, 0x214);
	reg |= FIMDBYPASS_DISP1;
	bus_space_write_4(sc->bst_sysreg, sc->bsh_sysreg, 0x214, reg);

	sc->sc_info.fb_width = panel.width;
	sc->sc_info.fb_height = panel.height;
	sc->sc_info.fb_stride = sc->sc_info.fb_width * 2;
	sc->sc_info.fb_bpp = sc->sc_info.fb_depth = 16;
	sc->sc_info.fb_size = sc->sc_info.fb_height * sc->sc_info.fb_stride;
	sc->sc_info.fb_vbase = (intptr_t)kmem_alloc_contig(kernel_arena,
	    sc->sc_info.fb_size, M_ZERO, 0, ~0, PAGE_SIZE, 0, VM_MEMATTR_UNCACHEABLE);
	sc->sc_info.fb_pbase = (intptr_t)vtophys(sc->sc_info.fb_vbase);

#if 0
	printf("%dx%d [%d]\n", sc->sc_info.fb_width, sc->sc_info.fb_height,
	    sc->sc_info.fb_stride);
	printf("pbase == 0x%08x\n", sc->sc_info.fb_pbase);
#endif

	memset((int8_t *)sc->sc_info.fb_vbase, 0x0, sc->sc_info.fb_size);

	fimd_init(sc);

	sc->sc_info.fb_name = device_get_nameunit(dev);

	/* Ask newbus to attach framebuffer device to me. */
	sc->sc_fbd = device_add_child(dev, "fbd", device_get_unit(dev));
	if (sc->sc_fbd == NULL)
		device_printf(dev, "Can't attach fbd device\n");

	if (device_probe_and_attach(sc->sc_fbd) != 0) {
		device_printf(sc->dev, "Failed to attach fbd device\n");
	}

	return (0);
}
Ejemplo n.º 7
0
int
amptimer_intr(void *frame)
{
	struct amptimer_softc	*sc = amptimer_cd.cd_devs[0];
	struct amptimer_pcpu_softc *pc = &sc->sc_pstat[CPU_INFO_UNIT(curcpu())];
	uint64_t		 now;
	uint64_t		 nextevent;
	uint32_t		 r, reg;
#if defined(USE_GTIMER_CMP)
	int			 skip = 1;
#else
	int64_t			 delay;
#endif
	int			 rc = 0;

	/*
	 * DSR - I know that the tick timer is 64 bits, but the following
	 * code deals with rollover, so there is no point in dealing
	 * with the 64 bit math, just let the 32 bit rollover
	 * do the right thing
	 */

	now = amptimer_readcnt64(sc);

	while (pc->pc_nexttickevent <= now) {
		pc->pc_nexttickevent += sc->sc_ticks_per_intr;
		pc->pc_ticks_err_sum += sc->sc_ticks_err_cnt;

		/* looping a few times is faster than divide */
		while (pc->pc_ticks_err_sum > hz) {
			pc->pc_nexttickevent += 1;
			pc->pc_ticks_err_sum -= hz;
		}

#ifdef AMPTIMER_DEBUG
		sc->sc_clk_count.ec_count++;
#endif
		rc = 1;
		hardclock(frame);
	}
	while (pc->pc_nextstatevent <= now) {
		do {
			r = random() & (sc->sc_statvar -1);
		} while (r == 0); /* random == 0 not allowed */
		pc->pc_nextstatevent += sc->sc_statmin + r;

		/* XXX - correct nextstatevent? */
#ifdef AMPTIMER_DEBUG
		sc->sc_stat_count.ec_count++;
#endif
		rc = 1;
		statclock(frame);
	}

	if (pc->pc_nexttickevent < pc->pc_nextstatevent)
		nextevent = pc->pc_nexttickevent;
	else
		nextevent = pc->pc_nextstatevent;

#if defined(USE_GTIMER_CMP)
again:
	reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GTIMER_CTRL);
	reg &= ~GTIMER_CTRL_COMP;
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTIMER_CTRL, reg);
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTIMER_CMP_LOW,
	    nextevent & 0xffffffff);
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTIMER_CMP_HIGH,
	    nextevent >> 32);
	reg |= GTIMER_CTRL_COMP;
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTIMER_CTRL, reg);

	now = amptimer_readcnt64(sc);
	if (now >= nextevent) {
		nextevent = now + skip;
		skip += 1;
		goto again;
	}
#else
	/* clear old status */
	bus_space_write_4(sc->sc_iot, sc->sc_pioh, PTIMER_STATUS,
	    PTIMER_STATUS_EVENT);

	delay = nextevent - now;
	if (delay < 0)
		delay = 1;

	reg = bus_space_read_4(sc->sc_iot, sc->sc_pioh, PTIMER_CTRL);
	if ((reg & (PTIMER_CTRL_ENABLE | PTIMER_CTRL_IRQEN)) !=
	    (PTIMER_CTRL_ENABLE | PTIMER_CTRL_IRQEN))
		bus_space_write_4(sc->sc_iot, sc->sc_pioh, PTIMER_CTRL,
		    (PTIMER_CTRL_ENABLE | PTIMER_CTRL_IRQEN));

	bus_space_write_4(sc->sc_iot, sc->sc_pioh, PTIMER_LOAD, delay);
#endif

	return (rc);
}
Ejemplo n.º 8
0
static int
lbc_banks_enable(struct lbc_softc *sc)
{
	uint32_t size;
	uint32_t regval;
	int error, i;

	for (i = 0; i < LBC_DEV_MAX; i++) {
		size = sc->sc_banks[i].size;
		if (size == 0)
			continue;

		/*
		 * Compute and program BR value.
		 */
		regval = sc->sc_banks[i].addr;
		switch (sc->sc_banks[i].width) {
		case 8:
			regval |= (1 << 11);
			break;
		case 16:
			regval |= (2 << 11);
			break;
		case 32:
			regval |= (3 << 11);
			break;
		default:
			error = EINVAL;
			goto fail;
		}
		regval |= (sc->sc_banks[i].decc << 9);
		regval |= (sc->sc_banks[i].wp << 8);
		regval |= (sc->sc_banks[i].msel << 5);
		regval |= (sc->sc_banks[i].atom << 2);
		regval |= 1;
		bus_space_write_4(sc->sc_bst, sc->sc_bsh,
		    LBC85XX_BR(i), regval);

		/*
		 * Compute and program OR value.
		 */
		regval = lbc_address_mask(size);
		switch (sc->sc_banks[i].msel) {
		case LBCRES_MSEL_GPCM:
			/* TODO Add flag support for option registers */
			regval |= 0x0ff7;
			break;
		case LBCRES_MSEL_FCM:
			/* TODO Add flag support for options register */
			regval |= 0x0796;
			break;
		case LBCRES_MSEL_UPMA:
		case LBCRES_MSEL_UPMB:
		case LBCRES_MSEL_UPMC:
			printf("UPM mode not supported yet!");
			error = ENOSYS;
			goto fail;
		}
		bus_space_write_4(sc->sc_bst, sc->sc_bsh,
		    LBC85XX_OR(i), regval);
	}

	return (0);

fail:
	lbc_banks_unmap(sc);
	return (error);
}
Ejemplo n.º 9
0
static int
lbc_attach(device_t dev)
{
	struct lbc_softc *sc;
	struct lbc_devinfo *di;
	struct rman *rm;
	uintmax_t offset, size;
	vm_paddr_t start;
	device_t cdev;
	phandle_t node, child;
	pcell_t *ranges, *rangesptr;
	int tuple_size, tuples;
	int par_addr_cells;
	int bank, error, i, j;

	sc = device_get_softc(dev);
	sc->sc_dev = dev;

	sc->sc_mrid = 0;
	sc->sc_mres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_mrid,
	    RF_ACTIVE);
	if (sc->sc_mres == NULL)
		return (ENXIO);

	sc->sc_bst = rman_get_bustag(sc->sc_mres);
	sc->sc_bsh = rman_get_bushandle(sc->sc_mres);

	for (bank = 0; bank < LBC_DEV_MAX; bank++) {
		bus_space_write_4(sc->sc_bst, sc->sc_bsh, LBC85XX_BR(bank), 0);
		bus_space_write_4(sc->sc_bst, sc->sc_bsh, LBC85XX_OR(bank), 0);
	}

	/*
	 * Initialize configuration register:
	 * - enable Local Bus
	 * - set data buffer control signal function
	 * - disable parity byte select
	 * - set ECC parity type
	 * - set bus monitor timing and timer prescale
	 */
	bus_space_write_4(sc->sc_bst, sc->sc_bsh, LBC85XX_LBCR, 0);

	/*
	 * Initialize clock ratio register:
	 * - disable PLL bypass mode
	 * - configure LCLK delay cycles for the assertion of LALE
	 * - set system clock divider
	 */
	bus_space_write_4(sc->sc_bst, sc->sc_bsh, LBC85XX_LCRR, 0x00030008);

	bus_space_write_4(sc->sc_bst, sc->sc_bsh, LBC85XX_LTEDR, 0);
	bus_space_write_4(sc->sc_bst, sc->sc_bsh, LBC85XX_LTESR, ~0);
	bus_space_write_4(sc->sc_bst, sc->sc_bsh, LBC85XX_LTEIR, 0x64080001);

	sc->sc_irid = 0;
	sc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irid,
	    RF_ACTIVE | RF_SHAREABLE);
	if (sc->sc_ires != NULL) {
		error = bus_setup_intr(dev, sc->sc_ires,
		    INTR_TYPE_MISC | INTR_MPSAFE, NULL, lbc_intr, sc,
		    &sc->sc_icookie);
		if (error) {
			device_printf(dev, "could not activate interrupt\n");
			bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid,
			    sc->sc_ires);
			sc->sc_ires = NULL;
		}
	}

	sc->sc_ltesr = ~0;

	rangesptr = NULL;

	rm = &sc->sc_rman;
	rm->rm_type = RMAN_ARRAY;
	rm->rm_descr = "Local Bus Space";
	error = rman_init(rm);
	if (error)
		goto fail;

	error = rman_manage_region(rm, rm->rm_start, rm->rm_end);
	if (error) {
		rman_fini(rm);
		goto fail;
	}

	/*
	 * Process 'ranges' property.
	 */
	node = ofw_bus_get_node(dev);
	if ((fdt_addrsize_cells(node, &sc->sc_addr_cells,
	    &sc->sc_size_cells)) != 0) {
		error = ENXIO;
		goto fail;
	}

	par_addr_cells = fdt_parent_addr_cells(node);
	if (par_addr_cells > 2) {
		device_printf(dev, "unsupported parent #addr-cells\n");
		error = ERANGE;
		goto fail;
	}
	tuple_size = sizeof(pcell_t) * (sc->sc_addr_cells + par_addr_cells +
	    sc->sc_size_cells);

	tuples = OF_getencprop_alloc_multi(node, "ranges", tuple_size,
	    (void **)&ranges);
	if (tuples < 0) {
		device_printf(dev, "could not retrieve 'ranges' property\n");
		error = ENXIO;
		goto fail;
	}
	rangesptr = ranges;

	debugf("par addr_cells = %d, addr_cells = %d, size_cells = %d, "
	    "tuple_size = %d, tuples = %d\n", par_addr_cells,
	    sc->sc_addr_cells, sc->sc_size_cells, tuple_size, tuples);

	start = 0;
	size = 0;
	for (i = 0; i < tuples; i++) {

		/* The first cell is the bank (chip select) number. */
		bank = fdt_data_get(ranges, 1);
		if (bank < 0 || bank > LBC_DEV_MAX) {
			device_printf(dev, "bank out of range: %d\n", bank);
			error = ERANGE;
			goto fail;
		}
		ranges += 1;

		/*
		 * Remaining cells of the child address define offset into
		 * this CS.
		 */
		offset = 0;
		for (j = 0; j < sc->sc_addr_cells - 1; j++) {
			offset <<= sizeof(pcell_t) * 8;
			offset |= *ranges;
			ranges++;
		}

		/* Parent bus start address of this bank. */
		start = 0;
		for (j = 0; j < par_addr_cells; j++) {
			start <<= sizeof(pcell_t) * 8;
			start |= *ranges;
			ranges++;
		}

		size = fdt_data_get((void *)ranges, sc->sc_size_cells);
		ranges += sc->sc_size_cells;
		debugf("bank = %d, start = %jx, size = %jx\n", bank,
		    (uintmax_t)start, size);

		sc->sc_banks[bank].addr = start + offset;
		sc->sc_banks[bank].size = size;

		/*
		 * Attributes for the bank.
		 *
		 * XXX Note there are no DT bindings defined for them at the
		 * moment, so we need to provide some defaults.
		 */
		sc->sc_banks[bank].width = 16;
		sc->sc_banks[bank].msel = LBCRES_MSEL_GPCM;
		sc->sc_banks[bank].decc = LBCRES_DECC_DISABLED;
		sc->sc_banks[bank].atom = LBCRES_ATOM_DISABLED;
		sc->sc_banks[bank].wp = 0;
	}

	/*
	 * Initialize mem-mappings for the LBC banks (i.e. chip selects).
	 */
	error = lbc_banks_map(sc);
	if (error)
		goto fail;

	/*
	 * Walk the localbus and add direct subordinates as our children.
	 */
	for (child = OF_child(node); child != 0; child = OF_peer(child)) {

		di = malloc(sizeof(*di), M_LBC, M_WAITOK | M_ZERO);

		if (ofw_bus_gen_setup_devinfo(&di->di_ofw, child) != 0) {
			free(di, M_LBC);
			device_printf(dev, "could not set up devinfo\n");
			continue;
		}

		resource_list_init(&di->di_res);

		if (fdt_lbc_reg_decode(child, sc, di)) {
			device_printf(dev, "could not process 'reg' "
			    "property\n");
			ofw_bus_gen_destroy_devinfo(&di->di_ofw);
			free(di, M_LBC);
			continue;
		}

		fdt_lbc_fixup(child, sc, di);

		/* Add newbus device for this FDT node */
		cdev = device_add_child(dev, NULL, -1);
		if (cdev == NULL) {
			device_printf(dev, "could not add child: %s\n",
			    di->di_ofw.obd_name);
			resource_list_free(&di->di_res);
			ofw_bus_gen_destroy_devinfo(&di->di_ofw);
			free(di, M_LBC);
			continue;
		}
		debugf("added child name='%s', node=%x\n", di->di_ofw.obd_name,
		    child);
		device_set_ivars(cdev, di);
	}

	/*
	 * Enable the LBC.
	 */
	lbc_banks_enable(sc);

	OF_prop_free(rangesptr);
	return (bus_generic_attach(dev));

fail:
	OF_prop_free(rangesptr);
	bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_mrid, sc->sc_mres);
	return (error);
}
Ejemplo n.º 10
0
static void
igma_reg_write(const struct igma_chip *cd, int r, u_int32_t v)
{
	bus_space_write_4(cd->mmiot, cd->mmioh, r, v);
}
Ejemplo n.º 11
0
void
imxahci_attach(struct device *parent, struct device *self, void *args)
{
	struct armv7_attach_args *aa = args;
	struct imxahci_softc *imxsc = (struct imxahci_softc *) self;
	struct ahci_softc *sc = &imxsc->sc;
	uint32_t timeout = 0x100000;

	sc->sc_iot = aa->aa_iot;
	sc->sc_ios = aa->aa_dev->mem[0].size;
	sc->sc_dmat = aa->aa_dmat;

	if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr,
	    aa->aa_dev->mem[0].size, 0, &sc->sc_ioh))
		panic("imxahci_attach: bus_space_map failed!");

	sc->sc_ih = arm_intr_establish(aa->aa_dev->irq[0], IPL_BIO,
	    ahci_intr, sc, sc->sc_dev.dv_xname);
	if (sc->sc_ih == NULL) {
		printf(": unable to establish interrupt\n");
		goto unmap;
	}

	imxsc->sc_clk = clk_get("ahb");
	if (imxsc->sc_clk == NULL) {
		printf(": can't get clock\n");
		goto unmap;
	}
	clk_enable(imxsc->sc_clk);

	/* power it up */
	clk_enable(clk_get("sata_ref_100m"));
	clk_enable(clk_get("sata"));
	delay(100);

	/* power phy up */
	imxiomuxc_enable_sata();

	/* setup */
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYCR,
	    bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYCR) & ~SATA_P0PHYCR_TEST_PDDQ);

	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_GHC, SATA_GHC_HR);

	while (!bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_VERSIONR));

	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_CAP,
	    bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_CAP) | SATA_CAP_SSS);

	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_PI, 1);

	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_TIMER1MS, clk_get_rate(imxsc->sc_clk));

	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_P0SSTS) & 0xF) && timeout--);

	if (ahci_attach(sc) != 0) {
		/* error printed by ahci_attach */
		goto irq;
	}

	return;
irq:
	arm_intr_disestablish(sc->sc_ih);
unmap:
	bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
}
Ejemplo n.º 12
0
void
acpihpet_attach(struct device *parent, struct device *self, void *aux)
{
	struct acpihpet_softc *sc = (struct acpihpet_softc *) self;
	struct acpi_softc *psc = (struct acpi_softc *)parent;
	struct acpi_attach_args *aaa = aux;
	struct acpi_hpet *hpet = (struct acpi_hpet *)aaa->aaa_table;
	u_int64_t period, freq;	/* timer period in femtoseconds (10^-15) */
	u_int32_t v1, v2;
	int timeout;

	if (acpi_map_address(psc, &hpet->base_address, 0, HPET_REG_SIZE,
	    &sc->sc_ioh, &sc->sc_iot))	{
		printf(": can't map i/o space\n");
		return;
	}

	/*
	 * Revisions 0x30 through 0x3a of the AMD SB700, with spread
	 * spectrum enabled, have an SMM based HPET emulation that's
	 * subtly broken.  The hardware is initialized upon first
	 * access of the configuration register.  Initialization takes
	 * some time during which the configuration register returns
	 * 0xffffffff.
	 */
	timeout = 1000;
	do {
		if (bus_space_read_4(sc->sc_iot, sc->sc_ioh,
		    HPET_CONFIGURATION) != 0xffffffff)
			break;
	} while(--timeout > 0);

	if (timeout == 0) {
		printf(": disabled\n");
		return;
	}

	/* enable hpet */
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, HPET_CONFIGURATION, 1);

	/* make sure hpet is working */
	v1 = bus_space_read_4(sc->sc_iot, sc->sc_ioh, HPET_MAIN_COUNTER);
	delay(1);
	v2 = bus_space_read_4(sc->sc_iot, sc->sc_ioh, HPET_MAIN_COUNTER);
	if (v1 == v2) {
		printf(": counter not incrementing\n");
		bus_space_write_4(sc->sc_iot, sc->sc_ioh,
		    HPET_CONFIGURATION, 0);
		return;
	}

	period = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
	    HPET_CAPABILITIES + sizeof(u_int32_t));
	if (period == 0) {
		printf(": invalid period\n");
		bus_space_write_4(sc->sc_iot, sc->sc_ioh,
		    HPET_CONFIGURATION, 0);
		return;
	}
	freq =  1000000000000000ull / period;
	printf(": %lld Hz\n", freq);

	hpet_timecounter.tc_frequency = (u_int32_t)freq;
	hpet_timecounter.tc_priv = sc;
	hpet_timecounter.tc_name = sc->sc_dev.dv_xname;
	tc_init(&hpet_timecounter);
	acpihpet_attached++;
}
Ejemplo n.º 13
0
Archivo: ptx.c Proyecto: Piro77/fbsdpt3
static int
ptx_detach (device_t device)
{
	struct ptx_softc *scp = (struct ptx_softc *) device_get_softc(device);
	uint32_t val;
	int lp;

	if (scp->cardtype == PT3) {

		pt3_exit(scp);

		if (scp->res_memory) {
			bus_release_resource(device, SYS_RES_MEMORY,
				scp->rid_memory, scp->res_memory);
			scp->res_memory = 0;
		}
		if (scp->pt3_res_memory) {
			bus_release_resource(device, SYS_RES_MEMORY,
				scp->pt3_rid_memory, scp->pt3_res_memory);
			scp->pt3_res_memory = 0;
		}
		if (scp->dmat) {
			bus_dma_tag_destroy(scp->dmat);
		}
		if (scp->pt3_dmat) {
			bus_dma_tag_destroy(scp->pt3_dmat);
		}

		return 0;
	}

	if (scp->ptxdaemon) {
		ptx_proc_stop(scp);
	}

	// DMA終了
	if (scp->bh) {
		bus_space_write_4(scp->bt, scp->bh, 0x0, 0x08080000);
		for (lp = 0; lp < 10; lp++){
			val = bus_space_read_4(scp->bt, scp->bh, 0x0);
			if (!(val & (1 << 6))) {
				break;
			}
			ptx_pause("ptxdet", MSTOTICK(1));
		}
	}

	ptx_dma_free(scp);

	for (lp = 0; lp < MAX_STREAM; ++lp) {
		struct ptx_stream *s = &scp->stream[lp];
		if (mtx_initialized(&s->lock)) {
			mtx_destroy(&s->lock);
			cv_destroy(&s->not_full);
			cv_destroy(&s->not_empty);
		}
		if (s->buf != NULL) {
			free(s->buf, M_DEVBUF);
			s->buf = NULL;
		}

		if (scp->dev[lp]) {
			destroy_dev(scp->dev[lp]);
		}
	}

	if (scp->bh) {
		bus_space_write_4(scp->bt, scp->bh, 0x0, 0xb0b0000);
		bus_space_write_4(scp->bt, scp->bh, CFG_REGS_ADDR, 0x0);
	}
	settuner_reset(scp, LNB_OFF, TUNER_POWER_OFF);

	if (scp->dmat) {
		bus_dma_tag_destroy(scp->dmat);
	}

	if (mtx_initialized(&scp->lock)) {
		mtx_destroy(&scp->lock);
	}

	if (scp->res_memory) {
		bus_release_resource(device, SYS_RES_MEMORY,
			scp->rid_memory, scp->res_memory);
		scp->res_memory = 0;
	}

	return 0;
}
Ejemplo n.º 14
0
static void
npe_reg_write(struct ixpnpe_softc *sc, bus_size_t off, uint32_t val)
{
	DPRINTFn(9, sc->sc_dev, "%s(0x%lx, 0x%x)\n", __func__, off, val);
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, off, val);
}
Ejemplo n.º 15
0
static __inline void
malo_hal_write4(struct malo_hal *mh, bus_size_t off, uint32_t val)
{
	bus_space_write_4(mh->mh_iot, mh->mh_ioh, off, val);
}
Ejemplo n.º 16
0
__unused static inline void
bcmccb_write_4(struct bcmccb_softc *sc, bus_size_t o, uint32_t v)
{
	return bus_space_write_4(sc->sc_bst, sc->sc_bsh, o, v);
}
Ejemplo n.º 17
0
void
omgpio_intr_level(unsigned int gpio, unsigned int level)
{
	u_int32_t fe, re, l0, l1, bit;
	struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)];
	int s;

	s = splhigh();

	fe = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO_FALLINGDETECT);
	re = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO_RISINGDETECT);
	l0 = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO_LEVELDETECT0);
	l1 = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO_LEVELDETECT1);
	
	bit = 1 << GPIO_PIN_TO_OFFSET(gpio);

        switch (level) {
        case IST_NONE:
		fe &= ~bit;
		re &= ~bit;
		l0 &= ~bit;
		l1 &= ~bit;
		break;
        case IST_EDGE_FALLING:
		fe |= bit;
		re &= ~bit;
		l0 &= ~bit;
		l1 &= ~bit;
		break;
        case IST_EDGE_RISING:
		fe &= ~bit;
		re |= bit;
		l0 &= ~bit;
		l1 &= ~bit;
		break;
	case IST_PULSE: /* XXX */
		/* FALLTHRU */
        case IST_EDGE_BOTH:
		fe |= bit;
		re |= bit;
		l0 &= ~bit;
		l1 &= ~bit;
                break;
	case IST_LEVEL_LOW:
		fe &= ~bit;
		re &= ~bit;
		l0 |= bit;
		l1 &= ~bit;
                break;
	case IST_LEVEL_HIGH:
		fe &= ~bit;
		re &= ~bit;
		l0 &= ~bit;
		l1 |= bit;
                break;
		break;
        default:
                panic("omgpio_intr_level: bad level: %d", level);
                break;
        }

	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_FALLINGDETECT, fe);
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_RISINGDETECT, re);
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_LEVELDETECT0, l0);
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_LEVELDETECT1, l1);

	splx(s);
}
Ejemplo n.º 18
0
void
iof_attach(struct device *parent, struct device *self, void *aux)
{
	struct iof_softc *sc = (struct iof_softc *)self;
	struct pci_attach_args *pa = aux;
	pci_intr_handle_t ih;
	bus_space_tag_t memt;
	bus_space_handle_t memh;
	bus_size_t memsize;
	const char *intrstr;

	printf(": ");

	if (pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_TYPE_MEM, 0,
	    &memt, &memh, NULL, &memsize, 0)) {
		printf("can't map mem space\n");
		return;
	}

	sc->sc_pc = pa->pa_pc;
	sc->sc_tag = pa->pa_tag;
	sc->sc_dmat = pa->pa_dmat;

	/*
	 * Build a suitable bus_space_handle by restoring the original
	 * non-swapped subword access methods.
	 *
	 * XXX This is horrible and will need to be rethought if
	 * XXX IOC4 exist as real, removable PCI cards and
	 * XXX we ever support them cards not plugged to xbridges.
	 */

	sc->sc_mem_bus_space = malloc(sizeof (*sc->sc_mem_bus_space),
	    M_DEVBUF, M_NOWAIT);
	if (sc->sc_mem_bus_space == NULL) {
		printf("can't allocate bus_space\n");
		goto unmap;
	}

	bcopy(memt, sc->sc_mem_bus_space, sizeof(*sc->sc_mem_bus_space));
	sc->sc_mem_bus_space->_space_read_1 = xbow_read_1;
	sc->sc_mem_bus_space->_space_read_2 = xbow_read_2;
	sc->sc_mem_bus_space->_space_read_raw_2 = xbow_read_raw_2;
	sc->sc_mem_bus_space->_space_write_1 = xbow_write_1;
	sc->sc_mem_bus_space->_space_write_2 = xbow_write_2;
	sc->sc_mem_bus_space->_space_write_raw_2 = xbow_write_raw_2;

	sc->sc_memt = sc->sc_mem_bus_space;
	sc->sc_memh = memh;

	sc->sc_mcr = bus_space_read_4(sc->sc_memt, sc->sc_memh, IOC4_MCR);

	/*
	 * Acknowledge all pending interrupts, and disable them.
	 */

	bus_space_write_4(sc->sc_memt, sc->sc_memh, IOC4_SIO_IEC, ~0x0);
	bus_space_write_4(sc->sc_memt, sc->sc_memh, IOC4_SIO_IES, 0x0);
	bus_space_write_4(sc->sc_memt, sc->sc_memh, IOC4_SIO_IR,
	    bus_space_read_4(sc->sc_memt, sc->sc_memh, IOC4_SIO_IR));

	bus_space_write_4(sc->sc_memt, sc->sc_memh, IOC4_OTHER_IEC, ~0x0);
	bus_space_write_4(sc->sc_memt, sc->sc_memh, IOC4_OTHER_IES, 0x0);
	bus_space_write_4(sc->sc_memt, sc->sc_memh, IOC4_OTHER_IR,
	    bus_space_read_4(sc->sc_memt, sc->sc_memh, IOC4_OTHER_IR));

	if (pci_intr_map(pa, &ih) != 0) {
		printf("failed to map interrupt!\n");
		goto unmap;
	}
	intrstr = pci_intr_string(sc->sc_pc, ih);

	sc->sc_ih = pci_intr_establish(sc->sc_pc, ih, IPL_TTY, iof_intr,
	    sc, self->dv_xname);
	if (sc->sc_ih == NULL) {
		printf("failed to establish interrupt at %s\n", intrstr);
		goto unmap;
	}
	printf("%s\n", intrstr);

	/*
	 * Attach other sub-devices.
	 */

	iof_attach_child(self, "com", IOC4_UARTA_BASE, IOC4DEV_SERIAL_A);
	iof_attach_child(self, "com", IOC4_UARTB_BASE, IOC4DEV_SERIAL_B);
	iof_attach_child(self, "com", IOC4_UARTC_BASE, IOC4DEV_SERIAL_C);
	iof_attach_child(self, "com", IOC4_UARTD_BASE, IOC4DEV_SERIAL_D);
	iof_attach_child(self, "iockbc", IOC4_KBC_BASE, IOC4DEV_KBC);
	iof_attach_child(self, "dsrtc", IOC4_BYTEBUS_0, IOC4DEV_RTC);

	return;

unmap:
	bus_space_unmap(memt, memh, memsize);
}
Ejemplo n.º 19
0
void
amptimer_attach(struct device *parent, struct device *self, void *args)
{
	struct amptimer_softc *sc = (struct amptimer_softc *)self;
	struct cortex_attach_args *ia = args;
	bus_space_handle_t ioh, pioh;

	sc->sc_iot = ia->ca_iot;

	if (bus_space_map(sc->sc_iot, ia->ca_periphbase + GTIMER_ADDR,
	    GTIMER_SIZE, 0, &ioh))
		panic("amptimer_attach: bus_space_map global timer failed!");

	if (bus_space_map(sc->sc_iot, ia->ca_periphbase + PTIMER_ADDR,
	    PTIMER_SIZE, 0, &pioh))
		panic("amptimer_attach: bus_space_map priv timer failed!");

	sc->sc_ticks_per_second = amptimer_frequency;
	printf(": tick rate %d KHz\n", sc->sc_ticks_per_second /1000);

	sc->sc_ioh = ioh;
	sc->sc_pioh = pioh;

	/* disable global timer */
	bus_space_write_4(sc->sc_iot, ioh, GTIMER_CTRL, 0);

	/* XXX ??? reset counters to 0 - gives us uptime in the counter */
	bus_space_write_4(sc->sc_iot, ioh, GTIMER_CNT_LOW, 0);
	bus_space_write_4(sc->sc_iot, ioh, GTIMER_CNT_HIGH, 0);

	/* enable global timer */
	bus_space_write_4(sc->sc_iot, ioh, GTIMER_CTRL, GTIMER_CTRL_TIMER);

#if defined(USE_GTIMER_CMP)

	/* clear event */
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTIMER_STATUS, 1);
#else
	bus_space_write_4(sc->sc_iot, sc->sc_pioh, PTIMER_CTRL, 0);
	bus_space_write_4(sc->sc_iot, sc->sc_pioh, PTIMER_STATUS,
	    PTIMER_STATUS_EVENT);
#endif


#ifdef AMPTIMER_DEBUG
	evcount_attach(&sc->sc_clk_count, "clock", NULL);
	evcount_attach(&sc->sc_stat_count, "stat", NULL);
#endif

	/*
	 * private timer and interrupts not enabled until
	 * timer configures
	 */

	arm_clock_register(amptimer_cpu_initclocks, amptimer_delay,
	    amptimer_setstatclockrate, amptimer_startclock);

	amptimer_timecounter.tc_frequency = sc->sc_ticks_per_second;
	amptimer_timecounter.tc_priv = sc;

	tc_init(&amptimer_timecounter);
}
Ejemplo n.º 20
0
static int
at91_attach(device_t dev)
{
	struct at91_softc *sc = device_get_softc(dev);
	int i;

	at91_softc = sc;
	sc->sc_st = &at91_bs_tag;
	sc->sc_sh = AT91RM92_BASE;
	sc->dev = dev;
	if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91RM92_SYS_BASE,
	    AT91RM92_SYS_SIZE, &sc->sc_sys_sh) != 0)
		panic("Enable to map IRQ registers");
	sc->sc_irq_rman.rm_type = RMAN_ARRAY;
	sc->sc_irq_rman.rm_descr = "AT91 IRQs";
	sc->sc_mem_rman.rm_type = RMAN_ARRAY;
	sc->sc_mem_rman.rm_descr = "AT91 Memory";
#if 0
	sc->sc_usbmem_rman.rm_type = RMAN_ARRAY;
	sc->sc_usbmem_rman.rm_descr = "AT91RM9200 USB Memory-mapped regs";
#endif
	if (rman_init(&sc->sc_irq_rman) != 0 ||
	    rman_manage_region(&sc->sc_irq_rman, 1, 31) != 0)
		panic("at91_attach: failed to set up IRQ rman");
	if (rman_init(&sc->sc_mem_rman) != 0 ||
	    rman_manage_region(&sc->sc_mem_rman, 0xdff00000ul,
	    0xdffffffful) != 0)
		panic("at91_attach: failed to set up memory rman");
	if (rman_manage_region(&sc->sc_mem_rman, AT91RM92_OHCI_BASE,
	    AT91RM92_OHCI_BASE + AT91RM92_OHCI_SIZE - 1) != 0)
		panic("at91_attach: failed to set up ohci memory");

	for (i = 0; i < 32; i++) {
		bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_SVR + 
		    i * 4, i);
		/* Priority. */
		bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_SMR + i * 4,
		    irq_prio[i]);
		if (i < 8)
			bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_EOICR,
			    1);
	}
	bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_SPU, 32);
	/* No debug. */
	bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_DCR, 0);
	/* Disable and clear all interrupts. */
	bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_IDCR, 0xffffffff);
	bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_ICCR, 0xffffffff);

	/* XXX */
	/* Disable all interrupts for RTC (0xe24 == RTC_IDR) */
	bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xe24, 0xffffffff);
	/* DIsable all interrupts for DBGU */
	bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x20c, 0xffffffff);
	/* Disable all interrupts for the SDRAM controller */
	bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xfa8, 0xffffffff);

	at91_cpu_add_builtin_children(dev, sc);

	bus_generic_probe(dev);
	bus_generic_attach(dev);
	enable_interrupts(I32_bit | F32_bit);
	return (0);
}
Ejemplo n.º 21
0
int
beinit(struct ifnet *ifp)
{
	struct be_softc *sc = ifp->if_softc;
	bus_space_tag_t t = sc->sc_bustag;
	bus_space_handle_t br = sc->sc_br;
	bus_space_handle_t cr = sc->sc_cr;
	struct qec_softc *qec = sc->sc_qec;
	uint32_t v;
	uint32_t qecaddr;
	uint8_t *ea;
	int rc, s;

	s = splnet();

	qec_meminit(&sc->sc_rb, BE_PKT_BUF_SZ);

	bestop(ifp, 1);

	ea = sc->sc_enaddr;
	bus_space_write_4(t, br, BE_BRI_MACADDR0, (ea[0] << 8) | ea[1]);
	bus_space_write_4(t, br, BE_BRI_MACADDR1, (ea[2] << 8) | ea[3]);
	bus_space_write_4(t, br, BE_BRI_MACADDR2, (ea[4] << 8) | ea[5]);

	/* Clear hash table */
	bus_space_write_4(t, br, BE_BRI_HASHTAB0, 0);
	bus_space_write_4(t, br, BE_BRI_HASHTAB1, 0);
	bus_space_write_4(t, br, BE_BRI_HASHTAB2, 0);
	bus_space_write_4(t, br, BE_BRI_HASHTAB3, 0);

	/* Re-initialize RX configuration */
	v = BE_BR_RXCFG_FIFO;
	bus_space_write_4(t, br, BE_BRI_RXCFG, v);

	be_mcreset(sc);

	bus_space_write_4(t, br, BE_BRI_RANDSEED, 0xbd);

	bus_space_write_4(t, br,
	    BE_BRI_XIFCFG, BE_BR_XCFG_ODENABLE | BE_BR_XCFG_RESV);

	bus_space_write_4(t, br, BE_BRI_JSIZE, 4);

	/*
	 * Turn off counter expiration interrupts as well as
	 * 'gotframe' and 'sentframe'
	 */
	bus_space_write_4(t, br, BE_BRI_IMASK,
	    BE_BR_IMASK_GOTFRAME |
	    BE_BR_IMASK_RCNTEXP |
	    BE_BR_IMASK_ACNTEXP |
	    BE_BR_IMASK_CCNTEXP |
	    BE_BR_IMASK_LCNTEXP |
	    BE_BR_IMASK_CVCNTEXP |
	    BE_BR_IMASK_SENTFRAME |
	    BE_BR_IMASK_NCNTEXP |
	    BE_BR_IMASK_ECNTEXP |
	    BE_BR_IMASK_LCCNTEXP |
	    BE_BR_IMASK_FCNTEXP |
	    BE_BR_IMASK_DTIMEXP);

	/* Channel registers: */
	bus_space_write_4(t, cr, BE_CRI_RXDS, (uint32_t)sc->sc_rb.rb_rxddma);
	bus_space_write_4(t, cr, BE_CRI_TXDS, (uint32_t)sc->sc_rb.rb_txddma);

	qecaddr = sc->sc_channel * qec->sc_msize;
	bus_space_write_4(t, cr, BE_CRI_RXWBUF, qecaddr);
	bus_space_write_4(t, cr, BE_CRI_RXRBUF, qecaddr);
	bus_space_write_4(t, cr, BE_CRI_TXWBUF, qecaddr + qec->sc_rsize);
	bus_space_write_4(t, cr, BE_CRI_TXRBUF, qecaddr + qec->sc_rsize);

	bus_space_write_4(t, cr, BE_CRI_RIMASK, 0);
	bus_space_write_4(t, cr, BE_CRI_TIMASK, 0);
	bus_space_write_4(t, cr, BE_CRI_QMASK, 0);
	bus_space_write_4(t, cr, BE_CRI_BMASK, 0);
	bus_space_write_4(t, cr, BE_CRI_CCNT, 0);

	/* Set max packet length */
	v = ETHER_MAX_LEN;
	if (sc->sc_ethercom.ec_capenable & ETHERCAP_VLAN_MTU)
		v += ETHER_VLAN_ENCAP_LEN;
	bus_space_write_4(t, br, BE_BRI_RXMAX, v);
	bus_space_write_4(t, br, BE_BRI_TXMAX, v);

	/* Enable transmitter */
	bus_space_write_4(t, br,
	    BE_BRI_TXCFG, BE_BR_TXCFG_FIFO | BE_BR_TXCFG_ENABLE);

	/* Enable receiver */
	v = bus_space_read_4(t, br, BE_BRI_RXCFG);
	v |= BE_BR_RXCFG_FIFO | BE_BR_RXCFG_ENABLE;
	bus_space_write_4(t, br, BE_BRI_RXCFG, v);

	if ((rc = be_ifmedia_upd(ifp)) != 0)
		goto out;

	ifp->if_flags |= IFF_RUNNING;
	ifp->if_flags &= ~IFF_OACTIVE;

	callout_reset(&sc->sc_tick_ch, hz, be_tick, sc);

	return 0;
out:
	splx(s);
	return rc;
}
Ejemplo n.º 22
0
/**** Low-level hardware register groveling functions ****/
static void
rex3_write(struct newport_devconfig *dc, bus_size_t rexreg, uint32_t val)
{
	bus_space_write_4(dc->dc_st, dc->dc_sh, NEWPORT_REX3_OFFSET + rexreg,
	    val);
}
Ejemplo n.º 23
0
static void
obiosdhc_attach(device_t parent, device_t self, void *aux)
{
    struct obiosdhc_softc * const sc = device_private(self);
    struct obio_attach_args * const oa = aux;
    prop_dictionary_t prop = device_properties(self);
    uint32_t clkd, stat;
    int error, timo, clksft, n;
    bool support8bit = false;
    const char *transfer_mode = "PIO";
#ifdef TI_AM335X
    size_t i;
#endif

    prop_dictionary_get_bool(prop, "8bit", &support8bit);

    sc->sc.sc_dmat = oa->obio_dmat;
    sc->sc.sc_dev = self;
    sc->sc.sc_flags |= SDHC_FLAG_32BIT_ACCESS;
    sc->sc.sc_flags |= SDHC_FLAG_NO_LED_ON;
    sc->sc.sc_flags |= SDHC_FLAG_RSP136_CRC;
    sc->sc.sc_flags |= SDHC_FLAG_SINGLE_ONLY;
    if (support8bit)
        sc->sc.sc_flags |= SDHC_FLAG_8BIT_MODE;
#ifdef TI_AM335X
    sc->sc.sc_flags |= SDHC_FLAG_WAIT_RESET;
    sc->sc.sc_flags &= ~SDHC_FLAG_SINGLE_ONLY;
#endif
#if defined(OMAP_3530)
    sc->sc.sc_flags &= ~SDHC_FLAG_SINGLE_ONLY;
#endif
    sc->sc.sc_host = sc->sc_hosts;
    sc->sc.sc_clkbase = 96000;	/* 96MHZ */
    if (!prop_dictionary_get_uint32(prop, "clkmask", &sc->sc.sc_clkmsk))
        sc->sc.sc_clkmsk = 0x0000ffc0;
    sc->sc.sc_vendor_rod = obiosdhc_rod;
    sc->sc.sc_vendor_write_protect = obiosdhc_write_protect;
    sc->sc.sc_vendor_card_detect = obiosdhc_card_detect;
    sc->sc.sc_vendor_bus_clock = obiosdhc_bus_clock;
    sc->sc_bst = oa->obio_iot;

    clksft = ffs(sc->sc.sc_clkmsk) - 1;

    error = bus_space_map(sc->sc_bst, oa->obio_addr, oa->obio_size, 0,
                          &sc->sc_bsh);
    if (error) {
        aprint_error_dev(self,
                         "can't map registers: %d\n", error);
        return;
    }

    bus_space_subregion(sc->sc_bst, sc->sc_bsh, OMAP3_SDMMC_SDHC_OFFSET,
                        OMAP3_SDMMC_SDHC_SIZE, &sc->sc_sdhc_bsh);

#if NEDMA > 0
    if (oa->obio_edmabase != -1) {
        cv_init(&sc->sc_edma_cv, "sdhcedma");
        sc->sc_edma_fifo = oa->obio_addr +
                           OMAP3_SDMMC_SDHC_OFFSET + SDHC_DATA;
        obiosdhc_edma_init(sc, oa->obio_edmabase);
        sc->sc.sc_flags |= SDHC_FLAG_USE_DMA;
        sc->sc.sc_flags |= SDHC_FLAG_EXTERNAL_DMA;
        sc->sc.sc_flags |= SDHC_FLAG_EXTDMA_DMAEN;
        sc->sc.sc_flags &= ~SDHC_FLAG_SINGLE_ONLY;
        sc->sc.sc_vendor_transfer_data_dma = obiosdhc_edma_xfer_data;
        transfer_mode = "EDMA";
    }
#endif

    aprint_naive("\n");
    aprint_normal(": SDHC controller (%s)\n", transfer_mode);

#ifdef TI_AM335X
    /* XXX Not really AM335X-specific.  */
    for (i = 0; i < __arraycount(am335x_sdhc); i++)
        if ((oa->obio_addr == am335x_sdhc[i].as_base_addr) &&
                (oa->obio_intr == am335x_sdhc[i].as_intr)) {
            prcm_module_enable(&am335x_sdhc[i].as_module);
            break;
        }
    KASSERT(i < __arraycount(am335x_sdhc));
#endif

    /* XXXXXX: Turn-on regulator via I2C. */
    /* XXXXXX: And enable ICLOCK/FCLOCK. */

    /* MMCHS Soft reset */
    bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSCONFIG,
                      SYSCONFIG_SOFTRESET);
    timo = 3000000;	/* XXXX 3 sec. */
    while (timo--) {
        if (bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSSTATUS) &
                SYSSTATUS_RESETDONE)
            break;
        delay(1);
    }
    if (timo == 0)
        aprint_error_dev(self, "Soft reset timeout\n");
    bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSCONFIG,
                      SYSCONFIG_ENAWAKEUP | SYSCONFIG_AUTOIDLE | SYSCONFIG_SIDLEMODE_AUTO |
                      SYSCONFIG_CLOCKACTIVITY_FCLK | SYSCONFIG_CLOCKACTIVITY_ICLK);

    sc->sc_ih = intr_establish(oa->obio_intr, IPL_VM, IST_LEVEL,
                               sdhc_intr, &sc->sc);
    if (sc->sc_ih == NULL) {
        aprint_error_dev(self, "failed to establish interrupt %d\n",
                         oa->obio_intr);
        goto fail;
    }

    error = sdhc_host_found(&sc->sc, sc->sc_bst, sc->sc_sdhc_bsh,
                            oa->obio_size - OMAP3_SDMMC_SDHC_OFFSET);
    if (error != 0) {
        aprint_error_dev(self, "couldn't initialize host, error=%d\n",
                         error);
        goto fail;
    }

    /* Set SDVS 1.8v and DTW 1bit mode */
    SDHC_WRITE(sc, SDHC_HOST_CTL,
               SDHC_VOLTAGE_1_8V << (SDHC_VOLTAGE_SHIFT + 8));
    bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON,
                      bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) | CON_OD);
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_INTCLK_ENABLE |
               SDHC_SDCLK_ENABLE);
    SDHC_WRITE(sc, SDHC_HOST_CTL,
               SDHC_READ(sc, SDHC_HOST_CTL) | SDHC_BUS_POWER << 8);
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) | CLKD(150) << clksft);

    /*
     * 22.6.1.3.1.5 MMCHS Controller INIT Procedure Start
     * from 'OMAP35x Applications Processor  Technical Reference Manual'.
     *
     * During the INIT procedure, the MMCHS controller generates 80 clock
     * periods. In order to keep the 1ms gap, the MMCHS controller should
     * be configured to generate a clock whose frequency is smaller or
     * equal to 80 KHz.
     */

    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) & ~SDHC_SDCLK_ENABLE);
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) & ~sc->sc.sc_clkmsk);
    clkd = CLKD(80);
    n = 1;
    while (clkd & ~(sc->sc.sc_clkmsk >> clksft)) {
        clkd >>= 1;
        n <<= 1;
    }
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) | (clkd << clksft));
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_SDCLK_ENABLE);

    bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON,
                      bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) | CON_INIT);
    for (; n > 0; n--) {
        SDHC_WRITE(sc, SDHC_TRANSFER_MODE, 0x00000000);
        timo = 3000000;	/* XXXX 3 sec. */
        stat = 0;
        while (!(stat & SDHC_COMMAND_COMPLETE)) {
            stat = SDHC_READ(sc, SDHC_NINTR_STATUS);
            if (--timo == 0)
                break;
            delay(1);
        }
        if (timo == 0) {
            aprint_error_dev(self, "INIT Procedure timeout\n");
            break;
        }
        SDHC_WRITE(sc, SDHC_NINTR_STATUS, stat);
    }
    bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON,
                      bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) & ~CON_INIT);
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) & ~SDHC_SDCLK_ENABLE);
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) & ~sc->sc.sc_clkmsk);
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) | CLKD(150) << clksft);
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_SDCLK_ENABLE);

    return;

fail:
    if (sc->sc_ih) {
        intr_disestablish(sc->sc_ih);
        sc->sc_ih = NULL;
    }
    bus_space_unmap(sc->sc_bst, sc->sc_bsh, oa->obio_size);
}
Ejemplo n.º 24
0
void
ohci_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct ohci_pci_softc *sc = (struct ohci_pci_softc *)self;
	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	char const *intrstr;
	pci_intr_handle_t ih;
	int s;
	const char *vendor;
	char *devname = sc->sc.sc_bus.bdev.dv_xname;

	/* Map I/O registers */
	if (pci_mapreg_map(pa, PCI_CBMEM, PCI_MAPREG_TYPE_MEM, 0,
		    &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size, 0)) {
		printf(": can't map mem space\n");
		return;
	}

	/* Record what interrupts were enabled by SMM/BIOS. */
	sc->sc.sc_intre = bus_space_read_4(sc->sc.iot, sc->sc.ioh,
	    OHCI_INTERRUPT_ENABLE);

	/* Disable interrupts, so we don't get any spurious ones. */
	bus_space_write_4(sc->sc.iot, sc->sc.ioh, OHCI_INTERRUPT_DISABLE,
			  OHCI_MIE);

	sc->sc_pc = pc;
	sc->sc.sc_bus.dmatag = pa->pa_dmat;

	bus_space_barrier(sc->sc.iot, sc->sc.ioh, 0, sc->sc.sc_size,
	    BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
	bus_space_write_4(sc->sc.iot, sc->sc.ioh,
	    OHCI_INTERRUPT_DISABLE, OHCI_MIE);

	s = splusb();
	/* Map and establish the interrupt. */
	if (pci_intr_map(pa, &ih)) {
		printf(": couldn't map interrupt\n");
		bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
		splx(s);
		return;
	}

	intrstr = pci_intr_string(pc, ih);
	sc->sc_ih = pci_intr_establish(pc, ih, IPL_USB, ohci_intr, sc, devname);
	if (sc->sc_ih == NULL) {
		printf(": couldn't establish interrupt");
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
		splx(s);
		return;
	}
	printf(": %s", intrstr);

	/* Figure out vendor for root hub descriptor. */
	vendor = pci_findvendor(pa->pa_id);
	sc->sc.sc_id_vendor = PCI_VENDOR(pa->pa_id);
	if (vendor)
		strlcpy(sc->sc.sc_vendor, vendor, sizeof (sc->sc.sc_vendor));
	else
		snprintf(sc->sc.sc_vendor, sizeof (sc->sc.sc_vendor),
		    "vendor 0x%04x", PCI_VENDOR(pa->pa_id));

	/* Display revision and perform legacy emulation handover. */
	if (ohci_checkrev(&sc->sc) != USBD_NORMAL_COMPLETION ||
	    ohci_handover(&sc->sc) != USBD_NORMAL_COMPLETION) {
		bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
		pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
		splx(s);
		return;
	}

	/* Ignore interrupts for now */
	sc->sc.sc_bus.dying = 1;

	config_defer(self, ohci_pci_attach_deferred);

	splx(s);

	return;
}
Ejemplo n.º 25
0
static int
ohci_ec_attach(device_t dev)
{
	struct ec_ohci_softc *sc = device_get_softc(dev);
	bus_space_handle_t bsh;
	int err;
	int rid;

	/* initialise some bus fields */
	sc->sc_ohci.sc_bus.parent = dev;
	sc->sc_ohci.sc_bus.devices = sc->sc_ohci.sc_devices;
	sc->sc_ohci.sc_bus.devices_max = OHCI_MAX_DEVICES;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_ohci.sc_bus,
	    USB_GET_DMA_TAG(dev), &ohci_iterate_hw_softc)) {
		return (ENOMEM);
	}
	sc->sc_ohci.sc_dev = dev;

	rid = MEM_RID;

	sc->sc_ohci.sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &rid, RF_ACTIVE);

	if (!(sc->sc_ohci.sc_io_res)) {
		err = ENOMEM;
		goto error;
	}
	sc->sc_ohci.sc_io_tag = rman_get_bustag(sc->sc_ohci.sc_io_res);
	bsh = rman_get_bushandle(sc->sc_ohci.sc_io_res);
	/* Undocumented magic initialization */
	bus_space_write_4((sc)->sc_ohci.sc_io_tag, bsh,0x04, 0x146);

	bus_space_write_4((sc)->sc_ohci.sc_io_tag, bsh,0x44, 0x0200);

	DELAY(1000);

	sc->sc_ohci.sc_io_size = rman_get_size(sc->sc_ohci.sc_io_res);

	if (bus_space_subregion(sc->sc_ohci.sc_io_tag, bsh, 0x4000000,
	    sc->sc_ohci.sc_io_size, &sc->sc_ohci.sc_io_hdl) != 0)
		panic("%s: unable to subregion USB host registers",
		    device_get_name(dev));

	rid = 0;
	sc->sc_ohci.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
	    RF_ACTIVE);
	if (!(sc->sc_ohci.sc_irq_res)) {
		goto error;
	}
	sc->sc_ohci.sc_bus.bdev = device_add_child(dev, "usbus", -1);
	if (!(sc->sc_ohci.sc_bus.bdev)) {
		goto error;
	}
	device_set_ivars(sc->sc_ohci.sc_bus.bdev, &sc->sc_ohci.sc_bus);

	strlcpy(sc->sc_ohci.sc_vendor, "Cavium",
		sizeof(sc->sc_ohci.sc_vendor));

#if (__FreeBSD_version >= 700031)
	err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res,
	    INTR_TYPE_BIO | INTR_MPSAFE,  NULL,
	    (driver_intr_t *)ohci_interrupt, sc,
	    &sc->sc_ohci.sc_intr_hdl);
#else
	err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res,
	    INTR_TYPE_BIO | INTR_MPSAFE,
	    (driver_intr_t *)ohci_interrupt, sc,
	    &sc->sc_ohci.sc_intr_hdl);
#endif
	if (err) {
		sc->sc_ohci.sc_intr_hdl = NULL;
		goto error;
	}

	bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl,
	    OHCI_CONTROL, 0);

	err = ohci_init(&sc->sc_ohci);
	if (!err) {
		err = device_probe_and_attach(sc->sc_ohci.sc_bus.bdev);
	}
	if (err) {
		goto error;
	}
	return (0);

error:
	ohci_ec_detach(dev);
	return (ENXIO);
}
Ejemplo n.º 26
0
void
imxenet_chip_init(struct imxenet_softc *sc)
{
	struct device *dev = (struct device *) sc;
	int phy = 0;
	uint32_t reg;
	uint32_t rate = clk_get_rate(clk_get("enet_ref"));

	bus_space_write_4(sc->sc_iot, sc->sc_ioh, ENET_MSCR,
	    (((rate + (ENET_MII_CLK << 2) - 1) / (ENET_MII_CLK << 2)) << 1) | 0x100);

	switch (board_id)
	{
	case BOARD_ID_IMX6_HUMMINGBOARD:
		phy = ENET_HUMMINGBOARD_PHY;
		break;
	case BOARD_ID_IMX6_SABRELITE:
		phy = ENET_SABRELITE_PHY;
		break;
	case BOARD_ID_IMX6_UDOO:
		phy = ENET_UDOO_PHY;
		break;
	case BOARD_ID_IMX6_UTILITE:
		phy = ENET_UTILITE_PHY;
		break;
	case BOARD_ID_IMX6_WANDBOARD:
		phy = ENET_WANDBOARD_PHY;
		break;
	}

	switch (board_id)
	{
	case BOARD_ID_IMX6_UDOO:	/* Micrel KSZ9031 */
	case BOARD_ID_IMX6_SABRELITE:	/* Micrel KSZ9021 */
		/* prefer master mode */
		imxenet_miibus_writereg(dev, phy, 0x9, 0x1f00);

		/* min rx data delay */
		imxenet_miibus_writereg(dev, phy, 0x0b, 0x8105);
		imxenet_miibus_writereg(dev, phy, 0x0c, 0x0000);

		/* min tx data delay */
		imxenet_miibus_writereg(dev, phy, 0x0b, 0x8106);
		imxenet_miibus_writereg(dev, phy, 0x0c, 0x0000);

		/* max rx/tx clock delay, min rx/tx control delay */
		imxenet_miibus_writereg(dev, phy, 0x0b, 0x8104);
		imxenet_miibus_writereg(dev, phy, 0x0c, 0xf0f0);
		imxenet_miibus_writereg(dev, phy, 0x0b, 0x104);

		/* enable all interrupts */
		imxenet_miibus_writereg(dev, phy, 0x1b, 0xff00);
		break;
	case BOARD_ID_IMX6_HUMMINGBOARD:	/* AR8035 */
	case BOARD_ID_IMX6_UTILITE:
	case BOARD_ID_IMX6_WANDBOARD:		/* AR8031 */
		/* disable SmartEEE */
		imxenet_miibus_writereg(dev, phy, 0x0d, 0x0003);
		imxenet_miibus_writereg(dev, phy, 0x0e, 0x805d);
		imxenet_miibus_writereg(dev, phy, 0x0d, 0x4003);
		reg = imxenet_miibus_readreg(dev, phy, 0x0e);
		imxenet_miibus_writereg(dev, phy, 0x0e, reg & ~0x0100);

		/* enable 125MHz clk output */
		imxenet_miibus_writereg(dev, phy, 0x0d, 0x0007);
		imxenet_miibus_writereg(dev, phy, 0x0e, 0x8016);
		imxenet_miibus_writereg(dev, phy, 0x0d, 0x4007);

		reg = imxenet_miibus_readreg(dev, phy, 0x0e) & 0xffe3;
		imxenet_miibus_writereg(dev, phy, 0x0e, reg | 0x18);

		/* tx clock delay */
		imxenet_miibus_writereg(dev, phy, 0x1d, 0x0005);
		reg = imxenet_miibus_readreg(dev, phy, 0x1e);
		imxenet_miibus_writereg(dev, phy, 0x1e, reg | 0x0100);

		/* phy power */
		reg = imxenet_miibus_readreg(dev, phy, 0x00);
		if (reg & 0x0800)
			imxenet_miibus_writereg(dev, phy, 0x00, reg & ~0x0800);
		break;
	}
}
Ejemplo n.º 27
0
static void
tegra_ahcisata_init(struct tegra_ahcisata_softc *sc)
{
    bus_space_tag_t bst = sc->sc_bst;
    bus_space_handle_t bsh = sc->sc_bsh;

    const u_int gen1_tx_amp = 0x18;
    const u_int gen1_tx_peak = 0x04;
    const u_int gen2_tx_amp = 0x18;
    const u_int gen2_tx_peak = 0x0a;

    /* Enable IFPS device block */
    tegra_reg_set_clear(bst, bsh, TEGRA_SATA_CONFIGURATION_REG,
                        TEGRA_SATA_CONFIGURATION_EN_FPCI, 0);

    /* PHY config */
    bus_space_write_4(bst, bsh, TEGRA_T_SATA0_INDEX_REG,
                      TEGRA_T_SATA0_INDEX_CH1);
    tegra_reg_set_clear(bst, bsh, TEGRA_T_SATA0_CHX_PHY_CTRL1_GEN1_REG,
                        __SHIFTIN(gen1_tx_amp, TEGRA_T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP) |
                        __SHIFTIN(gen1_tx_peak, TEGRA_T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK),
                        TEGRA_T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP |
                        TEGRA_T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK);
    tegra_reg_set_clear(bst, bsh, TEGRA_T_SATA0_CHX_PHY_CTRL1_GEN2_REG,
                        __SHIFTIN(gen2_tx_amp, TEGRA_T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP) |
                        __SHIFTIN(gen2_tx_peak, TEGRA_T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK),
                        TEGRA_T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP |
                        TEGRA_T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK);
    bus_space_write_4(bst, bsh, TEGRA_T_SATA0_CHX_PHY_CTRL11_REG,
                      __SHIFTIN(0x2800, TEGRA_T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ));
    bus_space_write_4(bst, bsh, TEGRA_T_SATA0_CHX_PHY_CTRL2_REG,
                      __SHIFTIN(0x23, TEGRA_T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1));
    bus_space_write_4(bst, bsh, TEGRA_T_SATA0_INDEX_REG, 0);

    /* Backdoor update the programming interface field and class code */
    tegra_reg_set_clear(bst, bsh, TEGRA_T_SATA0_CFG_SATA_REG,
                        TEGRA_T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN, 0);
    bus_space_write_4(bst, bsh, TEGRA_T_SATA0_BKDOOR_CC_REG,
                      __SHIFTIN(0x1016, TEGRA_T_SATA0_BKDOOR_CC_CLASS_CODE) |
                      __SHIFTIN(0x1, TEGRA_T_SATA0_BKDOOR_CC_PROG_IF));
    tegra_reg_set_clear(bst, bsh, TEGRA_T_SATA0_CFG_SATA_REG,
                        0, TEGRA_T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN);

    /* Enable access and bus mastering */
    tegra_reg_set_clear(bst, bsh, TEGRA_T_SATA0_CFG1_REG,
                        TEGRA_T_SATA0_CFG1_SERR |
                        TEGRA_T_SATA0_CFG1_BUS_MASTER |
                        TEGRA_T_SATA0_CFG1_MEM_SPACE |
                        TEGRA_T_SATA0_CFG1_IO_SPACE,
                        0);

    /* MMIO setup */
    bus_space_write_4(bst, bsh, TEGRA_SATA_FPCI_BAR5_REG,
                      __SHIFTIN(0x10000, TEGRA_SATA_FPCI_BAR_START));
    bus_space_write_4(bst, bsh, TEGRA_T_SATA0_CFG9_REG,
                      __SHIFTIN(0x8000, TEGRA_T_SATA0_CFG9_BASE_ADDRESS));

    /* Enable interrupts */
    tegra_reg_set_clear(bst, bsh, TEGRA_SATA_INTR_MASK_REG,
                        TEGRA_SATA_INTR_MASK_IP_INT, 0);
}
Ejemplo n.º 28
0
void
imxenet_init(struct imxenet_softc *sc)
{
	struct ifnet *ifp = &sc->sc_ac.ac_if;
	int speed = 0;
	uint32_t rate = clk_get_rate(clk_get("enet_ref"));

	/* reset the controller */
	HWRITE4(sc, ENET_ECR, ENET_ECR_RESET);
	while(HREAD4(sc, ENET_ECR) & ENET_ECR_RESET);

	/* set hw address */
	HWRITE4(sc, ENET_PALR,
	    (sc->sc_ac.ac_enaddr[0] << 24) |
	    (sc->sc_ac.ac_enaddr[1] << 16) |
	    (sc->sc_ac.ac_enaddr[2] << 8) |
	     sc->sc_ac.ac_enaddr[3]);
	HWRITE4(sc, ENET_PAUR,
	    (sc->sc_ac.ac_enaddr[4] << 24) |
	    (sc->sc_ac.ac_enaddr[5] << 16));

	/* clear outstanding interrupts */
	HWRITE4(sc, ENET_EIR, 0xffffffff);

	/* set address filter */
	HWRITE4(sc, ENET_GAUR, 0);
	HWRITE4(sc, ENET_GALR, 0);

	/* set max receive buffer size, 3-0 bits always zero for alignment */
	HWRITE4(sc, ENET_MRBR, ENET_MAX_PKT_SIZE);

	/* init descriptor */
	imxenet_init_txd(sc);
	imxenet_init_rxd(sc);

	/* set descriptor */
	HWRITE4(sc, ENET_TDSR, sc->txdma.dma_paddr);
	HWRITE4(sc, ENET_RDSR, sc->rxdma.dma_paddr);

	/* set it to full-duplex */
	HWRITE4(sc, ENET_TCR, ENET_TCR_FDEN);

	/*
	 * Set max frame length to 1518 or 1522 with VLANs,
	 * pause frames and promisc mode.
	 * XXX: RGMII mode - phy dependant
	 */
	HWRITE4(sc, ENET_RCR,
	    ENET_RCR_MAX_FL(1522) | ENET_RCR_RGMII_MODE | ENET_RCR_MII_MODE |
	    ENET_RCR_FCE);

	bus_space_write_4(sc->sc_iot, sc->sc_ioh, ENET_MSCR,
	    (((rate + (ENET_MII_CLK << 2) - 1) / (ENET_MII_CLK << 2)) << 1) | 0x100);

	/* RX FIFO treshold and pause */
	HWRITE4(sc, ENET_RSEM, 0x84);
	HWRITE4(sc, ENET_RSFL, 16);
	HWRITE4(sc, ENET_RAEM, 8);
	HWRITE4(sc, ENET_RAFL, 8);
	HWRITE4(sc, ENET_OPD, 0xFFF0);

	/* do store and forward, only i.MX6, needs to be set correctly else */
	HWRITE4(sc, ENET_TFWR, ENET_TFWR_STRFWD);

	/* enable gigabit-ethernet and set it to support little-endian */
	switch (IFM_SUBTYPE(sc->sc_mii.mii_media_active)) {
	case IFM_1000_T:  /* Gigabit */
		speed |= ENET_ECR_SPEED;
		break;
	default:
		speed &= ~ENET_ECR_SPEED;
		break;
	}
	HWRITE4(sc, ENET_ECR, ENET_ECR_ETHEREN | speed | ENET_ECR_DBSWP);

#ifdef ENET_ENHANCED_BD
	HSET4(sc, ENET_ECR, ENET_ECR_EN1588);
#endif

	/* rx descriptors are ready */
	HWRITE4(sc, ENET_RDAR, ENET_RDAR_RDAR);

	/* Indicate we are up and running. */
	ifp->if_flags |= IFF_RUNNING;
	ifp->if_flags &= ~IFF_OACTIVE;

	/* enable interrupts for tx/rx */
	HWRITE4(sc, ENET_EIMR, ENET_EIR_TXF | ENET_EIR_RXF);
	HWRITE4(sc, ENET_EIMR, 0xffffffff);

	imxenet_start(ifp);
}
Ejemplo n.º 29
0
void
exynos_device_register(device_t self, void *aux)
{
	if (device_is_a(self, "armperiph")
	    && device_is_a(device_parent(self), "mainbus")) {
		/*
		 * XXX KLUDGE ALERT XXX
		 * The iot mainbus supplies is completely wrong since it scales
		 * addresses by 2.  The simplest remedy is to replace with our
		 * bus space used for the armcore registers (which armperiph uses).
		 */
		struct mainbus_attach_args * const mb = aux;
		mb->mb_iot = &armv7_generic_bs_tag;
		return;
	}
	if (device_is_a(self, "armgic")
	    && device_is_a(device_parent(self), "armperiph")) {
		/*
		 * The Exynos4420 armgic is located at a different location!
		 */

		extern uint32_t exynos_soc_id;

		switch (EXYNOS_PRODUCT_ID(exynos_soc_id)) {
#ifdef EXYNOS5
		case 0xe5410:
			/* offsets not changed on matt's request */
#if 0
			mpcaa->mpcaa_memh = EXYNOS_CORE_VBASE;
			mpcaa->mpcaa_off1 = EXYNOS5_GIC_IOP_DISTRIBUTOR_OFFSET;
			mpcaa->mpcaa_off2 = EXYNOS5_GIC_IOP_CONTROLLER_OFFSET;
#endif
			break;
		case 0xe5422: {
			struct mpcore_attach_args * const mpcaa = aux;

			mpcaa->mpcaa_memh = EXYNOS_CORE_VBASE;
			mpcaa->mpcaa_off1 = EXYNOS5_GIC_IOP_DISTRIBUTOR_OFFSET;
			mpcaa->mpcaa_off2 = EXYNOS5_GIC_IOP_CONTROLLER_OFFSET;
			break;
		}
#endif
#ifdef EXYNOS4
		case 0xe4410:
		case 0xe4412: {
			struct mpcore_attach_args * const mpcaa = aux;

			mpcaa->mpcaa_memh = EXYNOS_CORE_VBASE;
			mpcaa->mpcaa_off1 = EXYNOS4_GIC_DISTRIBUTOR_OFFSET;
			mpcaa->mpcaa_off2 = EXYNOS4_GIC_CNTR_OFFSET;
			break;
		      }
#endif
		default:
			panic("%s: unknown SoC product id %#x", __func__,
			    (u_int)EXYNOS_PRODUCT_ID(exynos_soc_id));
		}
		return;
	}
	if (device_is_a(self, "armgtmr") || device_is_a(self, "mct")) {
#ifdef EXYNOS5
		/*
		 * The global timer is dependent on the MCT running.
		 */
		bus_size_t o = EXYNOS5_MCT_OFFSET + MCT_G_TCON;
		uint32_t v = bus_space_read_4(&armv7_generic_bs_tag, exynos_core_bsh,
		     o);
		v |= G_TCON_START;
		bus_space_write_4(&armv7_generic_bs_tag, exynos_core_bsh, o, v);
#endif
		/*
		 * The frequencies of the timers are the reference
		 * frequency.
		 */
		prop_dictionary_set_uint32(device_properties(self),
		    "frequency", EXYNOS_F_IN_FREQ);
		return;
	}
}
Ejemplo n.º 30
0
static void
wi_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct wi_pci_softc *psc = (struct wi_pci_softc *)self;
	struct wi_softc *sc = &psc->psc_wi;
	struct pci_attach_args *pa = aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	const char *intrstr;
	const struct wi_pci_product *wpp;
	pci_intr_handle_t ih;
	bus_space_tag_t memt, iot, plxt, tmdt;
	bus_space_handle_t memh, ioh, plxh, tmdh;

	psc->psc_pc = pc;
	psc->psc_pcitag = pa->pa_tag;

	wpp = wi_pci_lookup(pa);
#ifdef DIAGNOSTIC
	if (wpp == NULL) {
		printf("\n");
		panic("wi_pci_attach: impossible");
	}
#endif

	switch (wpp->wpp_chip) {
	case CHIP_PLX_OTHER:
	case CHIP_PLX_9052:
		/* Map memory and I/O registers. */
		if (pci_mapreg_map(pa, WI_PCI_LOMEM, PCI_MAPREG_TYPE_MEM, 0,
		    &memt, &memh, NULL, NULL) != 0) {
			printf(": can't map mem space\n");
			return;
		}
		if (pci_mapreg_map(pa, WI_PCI_LOIO, PCI_MAPREG_TYPE_IO, 0,
		    &iot, &ioh, NULL, NULL) != 0) {
			printf(": can't map I/O space\n");
			return;
		}

		if (wpp->wpp_chip == CHIP_PLX_OTHER) {
			/* The PLX 9052 doesn't have IO at 0x14.  Perhaps
			   other chips have, so we'll make this conditional. */
			if (pci_mapreg_map(pa, WI_PCI_PLX_LOIO,
				PCI_MAPREG_TYPE_IO, 0, &plxt,
				&plxh, NULL, NULL) != 0) {
					printf(": can't map PLX\n");
					return;
				}
		}
		break;
	case CHIP_TMD_7160:
		/* Used instead of PLX on at least one revision of
		 * the National Datacomm Corporation NCP130. Values
		 * for registers acquired from OpenBSD, which in
		 * turn got them from a Linux driver.
		 */
		/* Map COR and I/O registers. */
		if (pci_mapreg_map(pa, WI_TMD_COR, PCI_MAPREG_TYPE_IO, 0,
		    &tmdt, &tmdh, NULL, NULL) != 0) {
			printf(": can't map TMD\n");
			return;
		}
		if (pci_mapreg_map(pa, WI_TMD_IO, PCI_MAPREG_TYPE_IO, 0,
		    &iot, &ioh, NULL, NULL) != 0) {
			printf(": can't map I/O space\n");
			return;
		}
		break;
	default:
		if (pci_mapreg_map(pa, WI_PCI_CBMA,
		    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
		    0, &iot, &ioh, NULL, NULL) != 0) {
			printf(": can't map mem space\n");
			return;
		}

		memt = iot;
		memh = ioh;
		sc->sc_pci = 1;
		break;
	}

	{
		char devinfo[256];

		pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
		printf(": %s (rev. 0x%02x)\n", devinfo,
		       PCI_REVISION(pa->pa_class));
	}

	sc->sc_enabled = 1;
	sc->sc_enable = wi_pci_enable;
	sc->sc_disable = wi_pci_disable;

	sc->sc_iot = iot;
	sc->sc_ioh = ioh;
	/* Make sure interrupts are disabled. */
	CSR_WRITE_2(sc, WI_INT_EN, 0);
	CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);

	if (wpp->wpp_chip == CHIP_PLX_OTHER) {
		uint32_t command;
#define	WI_LOCAL_INTCSR		0x4c
#define	WI_LOCAL_INTEN		0x40	/* poke this into INTCSR */

		command = bus_space_read_4(plxt, plxh, WI_LOCAL_INTCSR);
		command |= WI_LOCAL_INTEN;
		bus_space_write_4(plxt, plxh, WI_LOCAL_INTCSR, command);
	}

	/* Map and establish the interrupt. */
	if (pci_intr_map(pa, &ih)) {
		aprint_error_dev(self, "couldn't map interrupt\n");
		return;
	}
	intrstr = pci_intr_string(pc, ih);

	psc->psc_ih = ih;
	sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, wi_intr, sc);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(self, "couldn't establish interrupt");
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		return;
	}

	printf("%s: interrupting at %s\n", device_xname(self), intrstr);

	switch (wpp->wpp_chip) {
	case CHIP_PLX_OTHER:
	case CHIP_PLX_9052:
		/*
		 * Setup the PLX chip for level interrupts and config index 1
		 * XXX - should really reset the PLX chip too.
		 */
		bus_space_write_1(memt, memh,
		    WI_PLX_COR_OFFSET, WI_PLX_COR_VALUE);
		break;
	case CHIP_TMD_7160:
		/* Enable I/O mode and level interrupts on the embedded
		 * card. The card's COR is the first byte of BAR 0.
		 */
		bus_space_write_1(tmdt, tmdh, 0, WI_COR_IOMODE);
		break;
	default:
		/* reset HFA3842 MAC core */
		wi_pci_reset(sc);
		break;
	}

	printf("%s:", device_xname(self));

	if (wi_attach(sc, 0) != 0) {
		aprint_error_dev(self, "failed to attach controller\n");
		pci_intr_disestablish(pa->pa_pc, sc->sc_ih);
		return;
	}

	if (!wpp->wpp_chip)
		sc->sc_reset = wi_pci_reset;

	if (!pmf_device_register(self, NULL, NULL))
		aprint_error_dev(self, "couldn't establish power handler\n");
	else
		pmf_class_network_register(self, &sc->sc_if);
}