Ejemplo n.º 1
0
void
at91ohci_callback(device_t self)
{
	struct at91ohci_softc *sc = device_private(self);
	usbd_status r;

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

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

	sc->sc_ih = at91_intr_establish(sc->sc_pid, IPL_USB, INTR_HIGH_LEVEL, ohci_intr, sc);
	r = ohci_init(&sc->sc);

	if (r != USBD_NORMAL_COMPLETION) {
		printf("%s: init failed, error=%d\n", device_xname(self), r);

		at91_intr_disestablish(sc->sc_ih);
		return;
	}

	/* Attach usb device. */
	sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint);
}
Ejemplo n.º 2
0
static void
emac_attach(device_t parent, device_t self, void *aux)
{
	struct emac_softc		*sc = device_private(self);
	struct at91bus_attach_args	*sa = aux;
	prop_data_t			enaddr;
	uint32_t			u;

	printf("\n");
	sc->sc_dev = self;
	sc->sc_iot = sa->sa_iot;
	sc->sc_pid = sa->sa_pid;
	sc->sc_dmat = sa->sa_dmat;

	if (bus_space_map(sa->sa_iot, sa->sa_addr, sa->sa_size, 0, &sc->sc_ioh))
		panic("%s: Cannot map registers", device_xname(self));

	/* enable peripheral clock */
	at91_peripheral_clock(sc->sc_pid, 1);

	/* configure emac: */
	EMAC_WRITE(ETH_CTL, 0);			// disable everything
	EMAC_WRITE(ETH_IDR, -1);		// disable interrupts
	EMAC_WRITE(ETH_RBQP, 0);		// clear receive
	EMAC_WRITE(ETH_CFG, ETH_CFG_CLK_32 | ETH_CFG_SPD | ETH_CFG_FD | ETH_CFG_BIG);
	EMAC_WRITE(ETH_TCR, 0);			// send nothing
	//(void)EMAC_READ(ETH_ISR);
	u = EMAC_READ(ETH_TSR);
	EMAC_WRITE(ETH_TSR, (u & (ETH_TSR_UND | ETH_TSR_COMP | ETH_TSR_BNQ
				  | ETH_TSR_IDLE | ETH_TSR_RLE
				  | ETH_TSR_COL|ETH_TSR_OVR)));
	u = EMAC_READ(ETH_RSR);
	EMAC_WRITE(ETH_RSR, (u & (ETH_RSR_OVR|ETH_RSR_REC|ETH_RSR_BNA)));

	/* Fetch the Ethernet address from property if set. */
	enaddr = prop_dictionary_get(device_properties(self), "mac-addr");

	if (enaddr != NULL) {
		KASSERT(prop_object_type(enaddr) == PROP_TYPE_DATA);
		KASSERT(prop_data_size(enaddr) == ETHER_ADDR_LEN);
		memcpy(sc->sc_enaddr, prop_data_data_nocopy(enaddr),
		       ETHER_ADDR_LEN);
	} else {
		static const uint8_t hardcoded[ETHER_ADDR_LEN] = {
		  0x00, 0x0d, 0x10, 0x81, 0x0c, 0x94
		};
		memcpy(sc->sc_enaddr, hardcoded, ETHER_ADDR_LEN);
	}

        at91_intr_establish(sc->sc_pid, IPL_NET, INTR_HIGH_LEVEL, emac_intr, sc);
	emac_init(sc);
}
Ejemplo n.º 3
0
void
cpu_initclocks(void)
{
    struct at91st_softc *sc = at91st_sc;

    if (!sc || !sc->sc_initialized)
	panic("%s: driver has not been initialized! (sc=%p)", __FUNCTION__, sc);

    stathz = profhz = 0;

    /* set up and enable interval timer 1 as kernel timer, */
    /* using 32kHz clock source */
    WRITE_ST(ST_PIMR, AT91ST_DIVIDER);

    /* register interrupt handler */
    at91_intr_establish(sc->sc_pid, IPL_CLOCK, INTR_HIGH_LEVEL, at91st_intr, NULL);

    /* enable interrupts from timer */
    WRITE_ST(ST_IER, ST_SR_PITS);
}
Ejemplo n.º 4
0
void
cpu_initclocks(void)
{
    struct at91tctmr_softc *sc = at91tctmr_sc;

    if (!sc || !sc->sc_initialized)
        panic("%s: driver has not been initialized! (sc=%p)", __FUNCTION__, sc);

    hz = sc->sc_timerclock / sc->sc_divider;
    stathz = profhz = 0;

    /* set up and enable interval timer 1 as kernel timer, */
    /* using 32kHz clock source */

    /* register interrupt handler */
    at91_intr_establish(sc->sc_pid, IPL_CLOCK, INTR_HIGH_LEVEL, at91tctmr_intr, sc);

    /* enable interrupts from timer */
    WRITE_TC(sc, TC_IER, TC_SR_CPCS);
}
Ejemplo n.º 5
0
void
at91usart_attach_subr(struct at91usart_softc *sc, struct at91bus_attach_args *sa)
{
	struct tty *tp;
	int err;

	printf("\n");

	if (bus_space_map(sa->sa_iot, sa->sa_addr, sa->sa_size, 0, &sc->sc_ioh))
		panic("%s: Cannot map registers", device_xname(sc->sc_dev));

	sc->sc_iot = sa->sa_iot;
	sc->sc_hwbase = sa->sa_addr;
	sc->sc_dmat = sa->sa_dmat;
	sc->sc_pid = sa->sa_pid;

	/* allocate fifos */
	err = at91pdc_alloc_fifo(sc->sc_dmat, &sc->sc_rx_fifo, AT91USART_RING_SIZE, BUS_DMA_READ | BUS_DMA_STREAMING);
	if (err)
		panic("%s: cannot allocate rx fifo", device_xname(sc->sc_dev));

	err = at91pdc_alloc_fifo(sc->sc_dmat, &sc->sc_tx_fifo, AT91USART_RING_SIZE, BUS_DMA_WRITE | BUS_DMA_STREAMING);
	if (err)
		panic("%s: cannot allocate tx fifo", device_xname(sc->sc_dev));

	/* initialize uart */
	at91_peripheral_clock(sc->sc_pid, 1);

	at91usart_writereg(sc, US_IDR, -1);
	at91usart_writereg(sc, US_RTOR, 12);	// 12-bit timeout
	at91usart_writereg(sc, US_PDC + PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS);
	at91_intr_establish(sa->sa_pid, IPL_TTY, INTR_HIGH_LEVEL, at91usart_intr, sc);
	USART_INIT(sc, 115200U);

#ifdef	NOTYET
	if (sc->sc_iot == usart_cn_sc.sc_iot
	    && sc->sc_hwbase == usart_cn_sc.sc_hwbase) {
		usart_cn_sc.sc_attached = 1;
		/* Make sure the console is always "hardwired". */
		delay(10000);	/* wait for output to finish */
		SET(sc->sc_hwflags, COM_HW_CONSOLE);
		SET(sc->sc_swflags, TIOCFLAG_SOFTCAR);
		SET(sc->sc_ier, USART_INT_RXRDY);
		USARTREG(USART_IER) = USART_INT_RXRDY; // @@@@@
	}
#endif	// NOTYET

	tp = tty_alloc();
	tp->t_oproc = at91usart_start;
	tp->t_param = at91usart_param;
	tp->t_hwiflow = at91usart_hwiflow;

	sc->sc_tty = tp;

	tty_attach(tp);

#if	NOTYET
	if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
		int maj;

		/* locate the major number */
		maj = cdevsw_lookup_major(&at91usart_cdevsw);

		cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev));

		aprint_normal("%s: console (maj %u  min %u  cn_dev %u)\n",
		    device_xname(sc->sc_dev), maj, device_unit(sc->sc_dev),
		    cn_tab->cn_dev);
	}
#endif	/* NOTYET */

	sc->sc_si = softint_establish(SOFTINT_SERIAL, at91usart_soft, sc);

#ifdef RND_COM
	rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
			  RND_TYPE_TTY, RND_FLAG_DEFAULT);
#endif

	/* if there are no enable/disable functions, assume the device
	   is always enabled */
	if (!sc->enable)
		sc->enabled = 1;

	/* XXX configure register */
	/* xxx_config(sc) */

	SET(sc->sc_hwflags, COM_HW_DEV_OK);
}
Ejemplo n.º 6
0
static void
at91dbgu_attach(device_t parent, device_t self, void *aux)
{
	struct at91dbgu_softc *sc = device_private(self);
	struct at91bus_attach_args *sa = aux;
	struct tty *tp;

	printf("\n");

	sc->sc_dev = self;
	bus_space_map(sa->sa_iot, sa->sa_addr, sa->sa_size, 0, &sc->sc_ioh);
	sc->sc_iot = sa->sa_iot;
	sc->sc_hwbase = sa->sa_addr;

	DBGUREG(DBGU_IDR) = -1;
	at91_intr_establish(sa->sa_pid, IPL_SERIAL, INTR_HIGH_LEVEL, dbgu_intr, sc);
	DBGU_INIT(AT91_MSTCLK, 115200U);

	if (sc->sc_iot == dbgu_cn_sc.sc_iot
	    && sc->sc_hwbase == dbgu_cn_sc.sc_hwbase) {
		dbgu_cn_sc.sc_attached = 1;
		/* Make sure the console is always "hardwired". */
		delay(10000);	/* wait for output to finish */
		SET(sc->sc_hwflags, COM_HW_CONSOLE);
		SET(sc->sc_swflags, TIOCFLAG_SOFTCAR);
		SET(sc->sc_ier, DBGU_INT_RXRDY);
		DBGUREG(DBGU_IER) = DBGU_INT_RXRDY; // @@@@@
	}

	tp = tty_alloc();
	tp->t_oproc = at91dbgu_start;
	tp->t_param = at91dbgu_param;
	tp->t_hwiflow = at91dbgu_hwiflow;

	sc->sc_tty = tp;
	sc->sc_rbuf = malloc(AT91DBGU_RING_SIZE << 1, M_DEVBUF, M_NOWAIT);
	sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
	sc->sc_rbavail = AT91DBGU_RING_SIZE;
	if (sc->sc_rbuf == NULL) {
		printf("%s: unable to allocate ring buffer\n",
		    device_xname(sc->sc_dev));
		return;
	}
	sc->sc_ebuf = sc->sc_rbuf + (AT91DBGU_RING_SIZE << 1);
	sc->sc_tbc = 0;

	tty_attach(tp);

	if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
		int maj;

		/* locate the major number */
		maj = cdevsw_lookup_major(&at91dbgu_cdevsw);

		cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev));

		aprint_normal("%s: console (maj %u min %u cn_dev %#"PRIx64")\n",
		    device_xname(sc->sc_dev), maj, device_unit(sc->sc_dev),
		    cn_tab->cn_dev);
	}

	sc->sc_si = softint_establish(SOFTINT_SERIAL, at91dbgu_soft, sc);

#ifdef RND_COM
	rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
			  RND_TYPE_TTY, 0);
#endif

	/* if there are no enable/disable functions, assume the device
	   is always enabled */
	if (!sc->enable)
		sc->enabled = 1;

	/* XXX configure register */
	/* xxx_config(sc) */

	SET(sc->sc_hwflags, COM_HW_DEV_OK);
}
Ejemplo n.º 7
0
void
at91spi_attach_common(device_t parent, device_t self, void *aux,
		      at91spi_machdep_tag_t md)
{
	struct at91spi_softc *sc = device_private(self);
	struct at91bus_attach_args *sa = aux;
	struct spibus_attach_args sba;
	bus_dma_segment_t segs;
	int rsegs, err;

	aprint_normal(": AT91 SPI Controller\n");

	sc->sc_dev = self;
	sc->sc_iot = sa->sa_iot;
	sc->sc_pid = sa->sa_pid;
	sc->sc_dmat = sa->sa_dmat;
	sc->sc_md = md;

	if (bus_space_map(sa->sa_iot, sa->sa_addr, sa->sa_size, 0, &sc->sc_ioh))
		panic("%s: Cannot map registers", device_xname(self));

	/* we want to use dma, so allocate dma memory: */
	err = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, 0, PAGE_SIZE,
			       &segs, 1, &rsegs, BUS_DMA_WAITOK);
	if (err == 0) {
		err = bus_dmamem_map(sc->sc_dmat, &segs, 1, PAGE_SIZE,
				     &sc->sc_dmapage,
				     BUS_DMA_WAITOK);
	}
	if (err == 0) {
		err = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1,
					 PAGE_SIZE, 0, BUS_DMA_WAITOK,
					 &sc->sc_dmamap);
	}
	if (err == 0) {
		err = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap,
				      sc->sc_dmapage, PAGE_SIZE, NULL,
				      BUS_DMA_WAITOK);
	}
	if (err != 0) {
		panic("%s: Cannot get DMA memory", device_xname(sc->sc_dev));
	}
	sc->sc_dmaaddr = sc->sc_dmamap->dm_segs[0].ds_addr;

	/*
	 * Initialize SPI controller
	 */
	sc->sc_spi.sct_cookie = sc;
	sc->sc_spi.sct_configure = at91spi_configure;
	sc->sc_spi.sct_transfer = at91spi_transfer;

	//sc->sc_spi.sct_nslaves must have been initialized by machdep code
	if (!sc->sc_spi.sct_nslaves) {
		aprint_error("%s: no slaves!\n", device_xname(sc->sc_dev));
	}

	sba.sba_controller = &sc->sc_spi;

	/* initialize the queue */
	SIMPLEQ_INIT(&sc->sc_q);

	/* reset the SPI */
	at91_peripheral_clock(sc->sc_pid, 1);
	PUTREG(sc, SPI_CR, SPI_CR_SWRST);
	delay(100);

	/* be paranoid and make sure the PDC is dead */
	PUTREG(sc, SPI_PDC_BASE + PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS);
	PUTREG(sc, SPI_PDC_BASE + PDC_RNCR, 0);
	PUTREG(sc, SPI_PDC_BASE + PDC_RCR, 0);
	PUTREG(sc, SPI_PDC_BASE + PDC_TNCR, 0);
	PUTREG(sc, SPI_PDC_BASE + PDC_TCR, 0);

	// configure SPI:
	PUTREG(sc, SPI_IDR, -1);
	PUTREG(sc, SPI_CSR(0), SPI_CSR_SCBR | SPI_CSR_BITS_8);
	PUTREG(sc, SPI_CSR(1), SPI_CSR_SCBR | SPI_CSR_BITS_8);
	PUTREG(sc, SPI_CSR(2), SPI_CSR_SCBR | SPI_CSR_BITS_8);
	PUTREG(sc, SPI_CSR(3), SPI_CSR_SCBR | SPI_CSR_BITS_8);
	PUTREG(sc, SPI_MR, SPI_MR_MODFDIS/* <- machdep? */ | SPI_MR_MSTR);

	/* enable device interrupts */
	sc->sc_ih = at91_intr_establish(sc->sc_pid, IPL_BIO, INTR_HIGH_LEVEL,
					at91spi_intr, sc);

	/* enable SPI */
	PUTREG(sc, SPI_CR, SPI_CR_SPIEN);
	if (GETREG(sc, SPI_SR) & SPI_SR_RDRF)
		(void)GETREG(sc, SPI_RDR);

	PUTREG(sc, SPI_PDC_BASE + PDC_PTCR, PDC_PTCR_TXTEN | PDC_PTCR_RXTEN);

	/* attach slave devices */
	(void) config_found_ia(sc->sc_dev, "spibus", &sba, spibus_print);
}