void at91ohci_attach(device_t parent, device_t self, void *aux) { struct at91ohci_softc *sc = device_private(self); struct at91bus_attach_args *sa = aux; sc->sc.sc_dev = self; sc->sc.sc_bus.hci_private = sc; sc->sc.sc_bus.dmatag = sa->sa_dmat; sc->sc.iot = sa->sa_iot; sc->sc_pid = sa->sa_pid; /* Map I/O space */ if (bus_space_map(sc->sc.iot, sa->sa_addr, sa->sa_size, 0, &sc->sc.ioh)) { printf(": cannot map mem space\n"); return; } sc->sc.sc_size = sa->sa_size; /* enable peripheral clock */ at91_peripheral_clock(sc->sc_pid, 1); printf("\n"); /* Defer the rest until later */ config_defer(self, at91ohci_callback); }
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); }
static void at91tctmr_attach(device_t parent, device_t self, void *aux) { struct at91tctmr_softc *sc = device_private(self); struct at91bus_attach_args *sa = aux; aprint_normal("\n"); sc->sc_dev = self; sc->sc_addr = (void*)sa->sa_addr; sc->sc_pid = sa->sa_pid; if (at91tctmr_sc == NULL) at91tctmr_sc = sc; at91_peripheral_clock(sc->sc_pid, 1); WRITE_TC(sc, TC_CCR, TC_CCR_CLKDIS); WRITE_TC(sc, TC_IDR, -1); /* make sure interrupts are disabled */ /* find divider */ u_int32_t cmr = 0; if (AT91_MSTCLK / 2U / HZ <= 65536) { sc->sc_timerclock = AT91_MSTCLK / 2U; cmr = TC_CMR_TCCLKS_MCK_DIV_2; } else if (AT91_MSTCLK / 8U / HZ <= 65536) { sc->sc_timerclock = AT91_MSTCLK / 8U; cmr = TC_CMR_TCCLKS_MCK_DIV_8; } else if (AT91_MSTCLK / 32U / HZ <= 65536) { sc->sc_timerclock = AT91_MSTCLK / 32U; cmr = TC_CMR_TCCLKS_MCK_DIV_32; } else if (AT91_MSTCLK / 128U / HZ <= 65536) { sc->sc_timerclock = AT91_MSTCLK / 128U; cmr = TC_CMR_TCCLKS_MCK_DIV_128; } else panic("%s: cannot setup timer to reach HZ", device-xname(sc->sc_dev)); sc->sc_divider = (sc->sc_timerclock + HZ - 1) / HZ; /* round up */ sc->sc_usec_per_tick = 1000000UL / (sc->sc_timerclock / sc->sc_divider); WRITE_TC(sc, TC_CMR, TC_CMR_WAVE | cmr | TC_CMR_WAVSEL_UP_RC); WRITE_TC(sc, TC_CCR, TC_CCR_CLKEN); WRITE_TC(sc, TC_RC, sc->sc_divider - 1); WRITE_TC(sc, TC_CCR, TC_CCR_SWTRG); sc->sc_initialized = 1; DPRINTF("%s: done, tclock=%"PRIu32" div=%"PRIu32" uspertick=%"PRIu32"\n", __FUNCTION__, sc->sc_timerclock, sc->sc_divider, sc->sc_usec_per_tick); }
static void at91st_attach(device_t parent, device_t self, void *aux) { struct at91st_softc *sc = (struct at91st_softc*) self; struct at91bus_attach_args *sa = (struct at91bus_attach_args*) aux; printf("\n"); sc->sc_iot = sa->sa_iot; sc->sc_pid = sa->sa_pid; #if 0 DPRINTF("-> bus_space_map()\n"); /* map bus space and get handle */ if (bus_space_map(sc->sc_iot, sa->sa_addr, sa->sa_size, 0, &sc->sc_ioh) != 0) panic("%s: Cannot map registers", self->dv_xname); #endif if (at91st_sc == NULL) at91st_sc = sc; at91_peripheral_clock(sc->sc_pid, 1); WRITE_ST(ST_IDR, -1); /* make sure interrupts are disabled */ /* set up and enable interval timer 1 as kernel timer, */ /* using 32kHz clock source */ WRITE_ST(ST_PIMR, AT91ST_DIVIDER); WRITE_ST(ST_RTMR, 1); sc->sc_initialized = 1; DPRINTF("%s: done\n", __FUNCTION__); }
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); }
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); }