Пример #1
0
int
exiic_wait_state(struct exiic_softc *sc, uint32_t reg, uint32_t mask, uint32_t value)
{
	uint32_t state;
	int timeout;
	state = HREAD4(sc, reg);
	for (timeout = 1000; timeout > 0; timeout--) {
		if (((state = HREAD4(sc, reg)) & mask) == value)
			return 0;
		delay(1000);
	}
	return ETIMEDOUT;
}
Пример #2
0
static void
pxaohci_disable(struct pxaohci_softc *sc)
{
	uint32_t hr;

	/* Full host reset */
	hr = HREAD4(sc, USBHC_HR);
	HWRITE4(sc, USBHC_HR, (hr & USBHC_HR_MASK) | USBHC_HR_FHR);

	DELAY(USBHC_RST_WAIT);

	hr = HREAD4(sc, USBHC_HR);
	HWRITE4(sc, USBHC_HR, (hr & USBHC_HR_MASK) & ~(USBHC_HR_FHR));
}
Пример #3
0
static void
obioohci_disable(struct obioohci_softc *sc)
{
#ifdef NOTYET
	uint32_t hr;

	/* Full host reset */
	hr = HREAD4(sc, USBHC_HR);
	HWRITE4(sc, USBHC_HR, (hr & USBHC_HR_MASK) | USBHC_HR_FHR);

	DELAY(USBHC_RST_WAIT);

	hr = HREAD4(sc, USBHC_HR);
	HWRITE4(sc, USBHC_HR, (hr & USBHC_HR_MASK) & ~(USBHC_HR_FHR));
#endif
}
Пример #4
0
static void
pxaohci_enable(struct pxaohci_softc *sc)
{
	uint32_t hr;

	/* Full host reset */
	hr = HREAD4(sc, USBHC_HR);
	HWRITE4(sc, USBHC_HR, (hr & USBHC_HR_MASK) | USBHC_HR_FHR);

	DELAY(USBHC_RST_WAIT);

	hr = HREAD4(sc, USBHC_HR);
	HWRITE4(sc, USBHC_HR, (hr & USBHC_HR_MASK) & ~(USBHC_HR_FHR));

	/* Force system bus interface reset */
	hr = HREAD4(sc, USBHC_HR);
	HWRITE4(sc, USBHC_HR, (hr & USBHC_HR_MASK) | USBHC_HR_FSBIR);

	while (HREAD4(sc, USBHC_HR) & USBHC_HR_FSBIR)
		DELAY(3);

	/* Enable the ports (physically only one, only enable that one?) */
	hr = HREAD4(sc, USBHC_HR);
	HWRITE4(sc, USBHC_HR, (hr & USBHC_HR_MASK) & ~(USBHC_HR_SSE));
	hr = HREAD4(sc, USBHC_HR);
	HWRITE4(sc, USBHC_HR, (hr & USBHC_HR_MASK) &
			~(USBHC_HR_SSEP1 | USBHC_HR_SSEP2 | USBHC_HR_SSEP3));
	HWRITE4(sc, USBHC_HIE, USBHC_HIE_RWIE | USBHC_HIE_UPRIE);

	hr = HREAD4(sc, USBHC_UHCRHDA);
}
Пример #5
0
int
exiic_xfer_wait(struct exiic_softc *sc)
{
	if (!exiic_wait_state(sc, I2C_CON, I2C_CON_INTPENDING,
					   I2C_CON_INTPENDING))
		return (HREAD4(sc, I2C_STAT) & I2C_STAT_LAST_RVCD_BIT) ?
			I2C_NACK : I2C_ACK;
	else
		return I2C_TIMEOUT;
}
Пример #6
0
void
imxenet_stop(struct imxenet_softc *sc)
{
	struct ifnet *ifp = &sc->sc_ac.ac_if;

	/* Tell the stack that the interface is no longer active */
	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
	ifp->if_timer = 0;

	/* reset the controller */
	HSET4(sc, ENET_ECR, ENET_ECR_RESET);
	while(HREAD4(sc, ENET_ECR) & ENET_ECR_RESET);
}
Пример #7
0
void
imxenet_miibus_writereg(struct device *dev, int phy, int reg, int val)
{
	struct imxenet_softc *sc = (struct imxenet_softc *)dev;

	HSET4(sc, ENET_EIR, ENET_EIR_MII);

	bus_space_write_4(sc->sc_iot, sc->sc_ioh, ENET_MMFR,
	    ENET_MMFR_ST | ENET_MMFR_OP_WR | ENET_MMFR_TA |
	    phy << ENET_MMFR_PA_SHIFT | reg << ENET_MMFR_RA_SHIFT |
	    (val & 0xffff));

	while(!(HREAD4(sc, ENET_EIR) & ENET_EIR_MII));

	return;
}
Пример #8
0
/*
 * MII
 * Interrupts need ENET_ECR_ETHEREN to be set,
 * so we just read the interrupt status registers.
 */
int
imxenet_miibus_readreg(struct device *dev, int phy, int reg)
{
	int r = 0;
	struct imxenet_softc *sc = (struct imxenet_softc *)dev;

	HSET4(sc, ENET_EIR, ENET_EIR_MII);

	bus_space_write_4(sc->sc_iot, sc->sc_ioh, ENET_MMFR,
	    ENET_MMFR_ST | ENET_MMFR_OP_RD | ENET_MMFR_TA |
	    phy << ENET_MMFR_PA_SHIFT | reg << ENET_MMFR_RA_SHIFT);

	while(!(HREAD4(sc, ENET_EIR) & ENET_EIR_MII));

	r = bus_space_read_4(sc->sc_iot, sc->sc_ioh, ENET_MMFR);

	return (r & 0xffff);
}
Пример #9
0
void
imxenet_miibus_statchg(struct device *dev)
{
	struct imxenet_softc *sc = (struct imxenet_softc *)dev;
	int ecr;

	ecr = HREAD4(sc, ENET_ECR);
	switch (IFM_SUBTYPE(sc->sc_mii.mii_media_active)) {
	case IFM_1000_T:  /* Gigabit */
		ecr |= ENET_ECR_SPEED;
		break;
	default:
		ecr &= ~ENET_ECR_SPEED;
		break;
	}
	HWRITE4(sc, ENET_ECR, ecr);

	return;
}
Пример #10
0
int
exiic_intr(void *arg)
{
	struct exiic_softc *sc = arg;
	u_int16_t status;
	int rc = 0;

	status = HREAD4(sc, I2C_CON);

	if (ISSET(status, I2C_CON_INTPENDING)) {
		/* we do not acknowledge the interrupt here */
		rc = 1;

		sc->intr_status |= status;
		wakeup(&sc->intr_status);
	}

	return (rc);
}
Пример #11
0
void
bcmpm_wdog_set(struct bcmpm_softc *sc, uint32_t period)
{
	uint32_t rstc, wdog;

	if (period == 0) {
		HWRITE4(sc, PM_RSTC, PM_RSTC_RESET | PM_PASSWORD);
		return;
	}

	rstc = HREAD4(sc, PM_RSTC) & PM_RSTC_CONFIGMASK;
	rstc |= PM_RSTC_FULL_RESET;
	rstc |= PM_PASSWORD;

	wdog = period & PM_WDOG_TIMEMASK;
	wdog |= PM_PASSWORD;

	HWRITE4(sc, PM_RSTC, wdog);
	HWRITE4(sc, PM_RSTC, rstc);
}
Пример #12
0
/*
 * Established by attachment driver at interrupt priority IPL_NET.
 */
int
imxenet_intr(void *arg)
{
	struct imxenet_softc *sc = arg;
	struct ifnet *ifp = &sc->sc_ac.ac_if;
	u_int32_t status;

	/* Find out which interrupts are pending. */
	status = HREAD4(sc, ENET_EIR);

	/* Acknowledge the interrupts we are about to handle. */
	HWRITE4(sc, ENET_EIR, status);

	/*
	 * Wake up the blocking process to service command
	 * related interrupt(s).
	 */
	if (ISSET(status, ENET_EIR_MII)) {
		sc->intr_status |= status;
		wakeup(&sc->intr_status);
	}

	/*
	 * Handle incoming packets.
	 */
	if (ISSET(status, ENET_EIR_RXF)) {
		if (ifp->if_flags & IFF_RUNNING)
			imxenet_recv(sc);
	}

	/* Try to transmit. */
	if (ifp->if_flags & IFF_RUNNING && !IFQ_IS_EMPTY(&ifp->if_snd))
		imxenet_start(ifp);

	return 1;
}
Пример #13
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);
}
Пример #14
0
void
imxenet_attach(struct device *parent, struct device *self, void *args)
{
	struct armv7_attach_args *aa = args;
	struct imxenet_softc *sc = (struct imxenet_softc *) self;
	struct mii_data *mii;
	struct ifnet *ifp;
	int tsize, rsize, tbsize, rbsize, s;

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

	sc->sc_dma_tag = aa->aa_dmat;

	/* power it up */
	clk_enable(clk_get("enet_ref"));
	clk_enable(clk_get("enet"));

	switch (board_id)
	{
	case BOARD_ID_IMX6_HUMMINGBOARD:
		imxgpio_set_dir(ENET_HUMMINGBOARD_PHY_RST, IMXGPIO_DIR_OUT);
		delay(10);
		imxgpio_set_bit(ENET_HUMMINGBOARD_PHY_RST);
		delay(10);
		break;
	case BOARD_ID_IMX6_SABRELITE:
		/* SABRE Lite PHY reset */
		imxgpio_set_dir(ENET_SABRELITE_PHY_RST, IMXGPIO_DIR_OUT);
		delay(10);
		imxgpio_set_bit(ENET_SABRELITE_PHY_RST);
		delay(10);
		break;
	case BOARD_ID_IMX6_UDOO:
		// UDOO PHY reset
		imxgpio_set_dir(ENET_UDOO_PHY_RST, IMXGPIO_DIR_OUT);
		delay(10);
		imxgpio_set_bit(ENET_UDOO_PHY_RST);
		delay(10);
		break;
	}

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

	HWRITE4(sc, ENET_EIMR, 0);
	HWRITE4(sc, ENET_EIR, 0xffffffff);

	sc->sc_ih = arm_intr_establish(aa->aa_dev->irq[0], IPL_NET,
	    imxenet_intr, sc, sc->sc_dev.dv_xname);

	tsize = ENET_MAX_TXD * sizeof(struct imxenet_buf_desc);
	tsize = ENET_ROUNDUP(tsize, PAGE_SIZE);

	if (imxenet_dma_malloc(sc, tsize, &sc->txdma)) {
		printf("%s: Unable to allocate tx_desc memory\n",
		    sc->sc_dev.dv_xname);
		goto bad;
	}
	sc->tx_desc_base = (struct imxenet_buf_desc *)sc->txdma.dma_vaddr;

	rsize = ENET_MAX_RXD * sizeof(struct imxenet_buf_desc);
	rsize = ENET_ROUNDUP(rsize, PAGE_SIZE);

	if (imxenet_dma_malloc(sc, rsize, &sc->rxdma)) {
		printf("%s: Unable to allocate rx_desc memory\n",
		    sc->sc_dev.dv_xname);
		goto txdma;
	}
	sc->rx_desc_base = (struct imxenet_buf_desc *)sc->rxdma.dma_vaddr;

	tbsize = ENET_MAX_TXD * ENET_MAX_PKT_SIZE;
	tbsize = ENET_ROUNDUP(tbsize, PAGE_SIZE);

	if (imxenet_dma_malloc(sc, tbsize, &sc->tbdma)) {
		printf("%s: Unable to allocate tx_buffer memory\n",
		    sc->sc_dev.dv_xname);
		goto rxdma;
	}
	sc->tx_buffer_base = (struct imxenet_buffer *)sc->tbdma.dma_vaddr;

	rbsize = ENET_MAX_RXD * ENET_MAX_PKT_SIZE;
	rbsize = ENET_ROUNDUP(rbsize, PAGE_SIZE);

	if (imxenet_dma_malloc(sc, rbsize, &sc->rbdma)) {
		printf("%s: Unable to allocate rx_buffer memory\n",
		    sc->sc_dev.dv_xname);
		goto tbdma;
	}
	sc->rx_buffer_base = (struct imxenet_buffer *)sc->rbdma.dma_vaddr;

	sc->cur_tx = 0;
	sc->cur_rx = 0;

	printf("\n");

	s = splnet();

	ifp = &sc->sc_ac.ac_if;
	ifp->if_softc = sc;
	strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_ioctl = imxenet_ioctl;
	ifp->if_start = imxenet_start;
	ifp->if_capabilities = IFCAP_VLAN_MTU;

	memset(sc->sc_ac.ac_enaddr, 0xff, ETHER_ADDR_LEN);
	imxocotp_get_ethernet_address(sc->sc_ac.ac_enaddr);

	printf("%s: address %s\n", sc->sc_dev.dv_xname,
	    ether_sprintf(sc->sc_ac.ac_enaddr));

	/* initialize the chip */
	imxenet_chip_init(sc);

	IFQ_SET_READY(&ifp->if_snd);

	/* Initialize MII/media info. */
	mii = &sc->sc_mii;
	mii->mii_ifp = ifp;
	mii->mii_readreg = imxenet_miibus_readreg;
	mii->mii_writereg = imxenet_miibus_writereg;
	mii->mii_statchg = imxenet_miibus_statchg;
	mii->mii_flags = MIIF_AUTOTSLEEP;

	ifmedia_init(&mii->mii_media, 0, imxenet_ifmedia_upd, imxenet_ifmedia_sts);
	mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);

	if (LIST_FIRST(&mii->mii_phys) == NULL) {
		ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
		ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
	} else
		ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);

	if_attach(ifp);
	ether_ifattach(ifp);
	splx(s);

	imxenet_sc = sc;
	return;

tbdma:
	imxenet_dma_free(sc, &sc->tbdma);
rxdma:
	imxenet_dma_free(sc, &sc->rxdma);
txdma:
	imxenet_dma_free(sc, &sc->txdma);
bad:
	bus_space_unmap(sc->sc_iot, sc->sc_ioh, aa->aa_dev->mem[0].size);
}
Пример #15
0
int
exiic_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t _addr,
    const void *cmdbuf, size_t cmdlen, void *databuf, size_t datalen, int flags)
{
	struct exiic_softc *sc = cookie;
	uint32_t ret = 0;
	u_int8_t addr = 0;
	int i = 0;

	addr = (_addr & 0x7f) << 1;

	/* clock gating */
	//exccm_enable_i2c(sc->unit);

	if (exiic_wait_state(sc, I2C_STAT, I2C_STAT_BUSY_SIGNAL, 0)) {
		printf("%s: busy\n", __func__);
		return (EIO);
	}

	/* acknowledge generation */
	HSET4(sc, I2C_CON, I2C_CON_ACK);

	/* Send the slave-address */
	HWRITE4(sc, I2C_DS, addr);
	if (!I2C_OP_READ_P(op) || (cmdbuf && cmdlen))
		HWRITE4(sc, I2C_STAT, I2C_STAT_MODE_SEL_MASTER_TX
				    | I2C_STAT_SERIAL_OUTPUT
				    | I2C_STAT_BUSY_SIGNAL);
	else
		HWRITE4(sc, I2C_STAT, I2C_STAT_MODE_SEL_MASTER_RX
				    | I2C_STAT_SERIAL_OUTPUT
				    | I2C_STAT_BUSY_SIGNAL);

	ret = exiic_xfer_wait(sc);
	if (ret != I2C_ACK)
		goto fail;

	/* transmit commands */
	if (cmdbuf && cmdlen) {
		for (i = 0; i < cmdlen; i++) {
			HWRITE4(sc, I2C_DS, ((uint8_t *)cmdbuf)[i]);
			exiic_xfer_start(sc);
			ret = exiic_xfer_wait(sc);
			if (ret != I2C_ACK)
				goto fail;
		}
	}

	if (I2C_OP_READ_P(op)) {
		if (cmdbuf && cmdlen) {
			/* write slave chip address again for actual read */
			HWRITE4(sc, I2C_DS, addr);

			/* restart */
			HWRITE4(sc, I2C_STAT, I2C_STAT_MODE_SEL_MASTER_RX
					    | I2C_STAT_SERIAL_OUTPUT
					    | I2C_STAT_BUSY_SIGNAL);
			exiic_xfer_start(sc);
			ret = exiic_xfer_wait(sc);
			if (ret != I2C_ACK)
				goto fail;
		}

		for (i = 0; i < datalen && ret == I2C_ACK; i++) {
			/* disable ACK for final read */
			if (i == datalen - 1)
				HCLR4(sc, I2C_CON, I2C_CON_ACK);
			exiic_xfer_start(sc);
			ret = exiic_xfer_wait(sc);
			((uint8_t *)databuf)[i] = HREAD4(sc, I2C_DS);
		}
		if (ret == I2C_NACK)
			ret = I2C_ACK; /* Normal terminated read. */
	} else {
		for (i = 0; i < datalen && ret == I2C_ACK; i++) {
			HWRITE4(sc, I2C_DS, ((uint8_t *)databuf)[i]);
			exiic_xfer_start(sc);
			ret = exiic_xfer_wait(sc);
		}
	}

fail:
	/* send STOP */
	if (op & I2C_OP_READ_WITH_STOP) {
		HWRITE4(sc, I2C_STAT, I2C_STAT_MODE_SEL_MASTER_RX
				    | I2C_STAT_SERIAL_OUTPUT);
		exiic_xfer_start(sc);
	}

	return ret;
}