Beispiel #1
0
static int
ns8250_param(struct uart_bas *bas, int baudrate, int databits, int stopbits,
    int parity)
{
	int divisor;
	uint8_t lcr;

	lcr = 0;
	if (databits >= 8)
		lcr |= LCR_8BITS;
	else if (databits == 7)
		lcr |= LCR_7BITS;
	else if (databits == 6)
		lcr |= LCR_6BITS;
	else
		lcr |= LCR_5BITS;
	if (stopbits > 1)
		lcr |= LCR_STOPB;
	lcr |= parity << 3;

	/* Set baudrate. */
	if (baudrate > 0) {
		divisor = ns8250_divisor(bas->rclk, baudrate);
		if (divisor == 0)
			return (EINVAL);
		uart_setreg(bas, REG_LCR, lcr | LCR_DLAB);
		uart_barrier(bas);
		uart_setreg(bas, REG_DLL, divisor & 0xff);
		uart_setreg(bas, REG_DLH, (divisor >> 8) & 0xff);
		uart_barrier(bas);
	}
Beispiel #2
0
static int
oct16550_delay (struct uart_bas *bas)
{
	int divisor;
	u_char lcr;
        static int delay = 0;

        if (!delay_changed) return delay;
        delay_changed = 0;
	lcr = uart_getreg(bas, REG_LCR);
	uart_setreg(bas, REG_LCR, lcr | LCR_DLAB);
	uart_barrier(bas);
	divisor = uart_getreg(bas, REG_DLL) | (uart_getreg(bas, REG_DLH) << 8);
	uart_barrier(bas);
	uart_setreg(bas, REG_LCR, lcr);
	uart_barrier(bas);
	
	if(!bas->rclk)
		return 10; /* return an approx delay value */

	/* 1/10th the time to transmit 1 character (estimate). */
	if (divisor <= 134)
		return (16000000 * divisor / bas->rclk);
	return (16000 * divisor / (bas->rclk / 1000));

}
Beispiel #3
0
static int
sa1110_bus_transmit(struct uart_softc *sc)
{
	int i;
#if 0
	int sr = uart_getreg(&sc->sc_bas, SACOM_SR0);

	while (!(uart_getreg(&sc->sc_bas, SACOM_CR3) & CR3_TIE))
		uart_setreg(&sc->sc_bas, SACOM_CR3,
		    uart_getreg(&sc->sc_bas, SACOM_CR3) | CR3_TIE);    
#endif

	sc->sc_txbusy = 1;
	uart_setreg(&sc->sc_bas, SACOM_CR3, uart_getreg(&sc->sc_bas, SACOM_CR3)
	    | CR3_TIE);    
	for (i = 0; i < sc->sc_txdatasz; i++) {
		while (!(uart_getreg(&sc->sc_bas, SACOM_SR1) & SR1_TNF));

		uart_setreg(&sc->sc_bas, SACOM_DR, sc->sc_txbuf[i]);
		uart_barrier(&sc->sc_bas);
	}
#if 0
	sr = uart_getreg(&sc->sc_bas, SACOM_SR0);
#endif

	return (0);
}
Beispiel #4
0
/* Multiplexed I/O. */
static __inline void
uart_setmreg(struct uart_bas *bas, int reg, int val)
{

	uart_setreg(bas, REG_CTRL, reg);
	uart_barrier(bas);
	uart_setreg(bas, REG_CTRL, val);
}
Beispiel #5
0
static int
s3c24x0_uart_param(struct uart_bas *bas, int baudrate, int databits,
    int stopbits, int parity)
{
	int brd, ulcon;

	ulcon = 0;

	switch(databits) {
	case 5:
		ulcon |= ULCON_LENGTH_5;
		break;
	case 6:
		ulcon |= ULCON_LENGTH_6;
		break;
	case 7:
		ulcon |= ULCON_LENGTH_7;
		break;
	case 8:
		ulcon |= ULCON_LENGTH_8;
		break;
	default:
		return (EINVAL);
	}

	switch (parity) {
	case UART_PARITY_NONE:
		ulcon |= ULCON_PARITY_NONE;
		break;
	case UART_PARITY_ODD:
		ulcon |= ULCON_PARITY_ODD;
		break;
	case UART_PARITY_EVEN:
		ulcon |= ULCON_PARITY_EVEN;
		break;
	case UART_PARITY_MARK:
	case UART_PARITY_SPACE:
	default:
		return (EINVAL);
	}

	if (stopbits == 2)
		ulcon |= ULCON_STOP;

	uart_setreg(bas, SSCOM_ULCON, ulcon);

	brd = sscomspeed(baudrate, bas->rclk);
	uart_setreg(bas, SSCOM_UBRDIV, brd);

	return (0);
}
Beispiel #6
0
static void
tegra_uart_ungrab(struct uart_softc *sc)
{
	struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc;
	struct uart_bas *bas = &sc->sc_bas;

	/*
	 * Restore previous interrupt mask
	 */
	uart_lock(sc->sc_hwmtx);
	uart_setreg(bas, REG_FCR, ns8250->fcr);
	uart_setreg(bas, REG_IER, ns8250->ier);
	uart_barrier(bas);
	uart_unlock(sc->sc_hwmtx);
}
Beispiel #7
0
static void
sa1110_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
    int parity)
{
	int brd;
	
	if (bas->rclk == 0)
		bas->rclk = DEFAULT_RCLK;
	while (uart_getreg(bas, SACOM_SR1) & SR1_TBY);
	uart_setreg(bas, SACOM_CR3, 0);
	brd = SACOMSPEED(baudrate);
	uart_setreg(bas, SACOM_CR1, brd >> 8);
	uart_setreg(bas, SACOM_CR2, brd & 0xff);
	uart_setreg(bas, SACOM_CR3, CR3_RXE | CR3_TXE);
}
Beispiel #8
0
static void
msm_putc(struct uart_bas *bas, int c)
{
	int limit;

	/*
	 * Write to NO_CHARS_FOR_TX register the number of characters
	 * to be transmitted. However, before writing TX_FIFO must
	 * be empty as indicated by TX_READY interrupt in IMR register
	 */

	/*
	 * Check if transmit FIFO is empty.
	 * If not wait for TX_READY interrupt.
	 */
	limit = 1000;
	if (!(uart_getreg(bas, UART_DM_SR) & UART_DM_SR_TXEMT)) {
		while ((uart_getreg(bas, UART_DM_ISR) & UART_DM_TX_READY) == 0
		    && --limit)
			DELAY(4);
	}
	/* FIFO is ready, write number of characters to be written */
	uart_setreg(bas, UART_DM_NO_CHARS_FOR_TX, 1);

	/* Wait till TX FIFO has space */
	while ((uart_getreg(bas, UART_DM_SR) & UART_DM_SR_TXRDY) == 0)
		DELAY(4);

	/* TX FIFO has space. Write char */
	SETREG(bas, UART_DM_TF(0), (c & 0xff));
}
Beispiel #9
0
static int
ti8250_bus_probe(struct uart_softc *sc)
{
	int status;
	int devid;
	clk_ident_t clkid;
	pcell_t prop;
	phandle_t node;

	/*
	 * Get the device id from FDT.  If it's not there we can't turn on the
	 * right clocks, so bail, unless we're doing unit 0.  We assume that's
	 * the serial console, whose clock isn't controllable anyway, and we
	 * sure don't want to break the console because of a config error.
	 */
	node = ofw_bus_get_node(sc->sc_dev);
	if ((OF_getprop(node, "uart-device-id", &prop, sizeof(prop))) <= 0) {
		device_printf(sc->sc_dev, 
		    "missing uart-device-id attribute in FDT\n");
		if (device_get_unit(sc->sc_dev) != 0)
			return (ENXIO);
		devid = 0;
	} else
		devid = fdt32_to_cpu(prop);

	/* Enable clocks for this device.  We can't continue if that fails.  */
	clkid = UART0_CLK + devid;
	if ((status = ti_prcm_clk_enable(clkid)) != 0)
		return (status);

	/*
	 * Set the hardware to disabled mode, do a full device reset, then set
	 * it to uart mode.  Most devices will be reset-and-disabled already,
	 * but you never know what a bootloader might have done.
	 */
	uart_setreg(&sc->sc_bas, MDR1_REG, MDR1_MODE_DISABLE);
	uart_setreg(&sc->sc_bas, SYSCC_REG, SYSCC_SOFTRESET);
	while (uart_getreg(&sc->sc_bas, SYSS_REG) & SYSS_STATUS_RESETDONE)
		continue;
	uart_setreg(&sc->sc_bas, MDR1_REG, MDR1_MODE_UART);

	status = ns8250_bus_probe(sc); 
	if (status == 0)
		device_set_desc(sc->sc_dev, "TI UART (16550 compatible)");

	return (status);
}
Beispiel #10
0
static __inline uint8_t
uart_getmreg(struct uart_bas *bas, int reg)
{

	uart_setreg(bas, REG_CTRL, reg);
	uart_barrier(bas);
	return (uart_getreg(bas, REG_CTRL));
}
Beispiel #11
0
static void
vf_uart_putc(struct uart_bas *bas, int c)
{

    while (!(uart_getreg(bas, UART_S1) & UART_S1_TDRE))
        ;

    uart_setreg(bas, UART_D, c);
}
Beispiel #12
0
static int
sa1110_bus_attach(struct uart_softc *sc)
{
    bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));

    sc->sc_hwiflow = 0;
    uart_setreg(&sc->sc_bas, SACOM_CR3, CR3_RXE | CR3_TXE | CR3_RIE | CR3_TIE);
    return (0);
}
Beispiel #13
0
static void
s3c2410_putc(struct uart_bas *bas, int c)
{
	while ((bus_space_read_4(bas->bst, bas->bsh, SSCOM_UFSTAT) &
	    UFSTAT_TXFULL) == UFSTAT_TXFULL)
		continue;

	uart_setreg(bas, SSCOM_UTXH, c);
}
Beispiel #14
0
static int
sa1110_getc(struct uart_bas *bas, struct mtx *mtx)
{
	int c;

	while (!(uart_getreg(bas, SACOM_SR1) & SR1_RNE)) {
		u_int32_t sr0;

		sr0 = uart_getreg(bas, SACOM_SR0);
		if (ISSET(sr0, SR0_RBB))
			uart_setreg(bas, SACOM_SR0, SR0_RBB);
		if (ISSET(sr0, SR0_REB))
			uart_setreg(bas, SACOM_SR0, SR0_REB);
	}
	c = uart_getreg(bas, SACOM_DR);
	c &= 0xff;
	return (c);
}
Beispiel #15
0
static int
ns8250_delay(struct uart_bas *bas)
{
	int divisor;
	u_char lcr;

	lcr = uart_getreg(bas, REG_LCR);
	uart_setreg(bas, REG_LCR, lcr | LCR_DLAB);
	uart_barrier(bas);
	divisor = uart_getreg(bas, REG_DLL) | (uart_getreg(bas, REG_DLH) << 8);
	uart_barrier(bas);
	uart_setreg(bas, REG_LCR, lcr);
	uart_barrier(bas);

	/* 1/10th the time to transmit 1 character (estimate). */
	if (divisor <= 134)
		return (16000000 * divisor / bas->rclk);
	return (16000 * divisor / (bas->rclk / 1000));
}
Beispiel #16
0
static void
tegra_uart_grab(struct uart_softc *sc)
{
	struct uart_bas *bas = &sc->sc_bas;
	struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc;
	u_char ier;

	/*
	 * turn off all interrupts to enter polling mode. Leave the
	 * saved mask alone. We'll restore whatever it was in ungrab.
	 * All pending interrupt signals are reset when IER is set to 0.
	 */
	uart_lock(sc->sc_hwmtx);
	ier = uart_getreg(bas, REG_IER);
	uart_setreg(bas, REG_IER, ier & ns8250->ier_mask);
	uart_setreg(bas, REG_FCR, 0);
	uart_barrier(bas);
	uart_unlock(sc->sc_hwmtx);
}
Beispiel #17
0
static int
sa1110_bus_param(struct uart_softc *sc, int baudrate, int databits,
    int stopbits, int parity)
{
	int brd;
	
	if (baudrate > 0) {
		brd = SACOMSPEED(baudrate);
		uart_setreg(&sc->sc_bas, SACOM_CR1, brd >> 8);
		uart_setreg(&sc->sc_bas, SACOM_CR2, brd & 0xff);
	}
Beispiel #18
0
static void
mtk_uart_putc(struct uart_bas *bas, int c)
{
	char chr;
	if (!uart_output) return;
	chr = c;
	while (!(uart_getreg(bas, UART_LSR_REG) & UART_LSR_THRE));
	uart_setreg(bas, UART_TX_REG, c);
	uart_barrier(bas);
	while (!(uart_getreg(bas, UART_LSR_REG) & UART_LSR_THRE));
}
Beispiel #19
0
static void
s3c2410_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
    int parity)
{
	if (bas->rclk == 0)
		bas->rclk = s3c2410_pclk;
	KASSERT(bas->rclk != 0, ("s3c2410_init: Invalid rclk"));

	uart_setreg(bas, SSCOM_UCON, 0);
	uart_setreg(bas, SSCOM_UFCON,
	    UFCON_TXTRIGGER_8 | UFCON_RXTRIGGER_8 |
	    UFCON_TXFIFO_RESET | UFCON_RXFIFO_RESET |
	    UFCON_FIFO_ENABLE);
	s3c24x0_uart_param(bas, baudrate, databits, stopbits, parity);

	/* Enable UART. */
	uart_setreg(bas, SSCOM_UCON, UCON_TXMODE_INT | UCON_RXMODE_INT |
	    UCON_TOINT);
	uart_setreg(bas, SSCOM_UMCON, UMCON_RTS);
}
Beispiel #20
0
static void
mtk_uart_init(struct uart_bas *bas, int baudrate, int databits,
    int stopbits, int parity)
{
        /* CLKDIV  = 384000000/ 3/ 16/ br */
        /* for 384MHz CLKDIV = 8000000 / baudrate; */
        switch (databits) {
        case 5:
    		databits = UART_LCR_5B;
    		break;
        case 6:
    		databits = UART_LCR_6B;
    		break;
        case 7:
    		databits = UART_LCR_7B;
    		break;
        case 8:
    		databits = UART_LCR_8B;
    		break;
    	default:
    		/* Unsupported */
    		return;
        }
	switch (parity) {
	case UART_PARITY_EVEN:	parity = (UART_LCR_PEN|UART_LCR_EVEN); break;
	case UART_PARITY_ODD:	parity = (UART_LCR_PEN); break;
	case UART_PARITY_NONE:	parity = 0; break;
	/* Unsupported */
	default:		return;
	}

	if (bas->rclk && baudrate) {
        	uart_setreg(bas, UART_CDDL_REG, bas->rclk/16/baudrate);
		uart_barrier(bas);
	}

        uart_setreg(bas, UART_LCR_REG, databits |
				(stopbits==1?0:UART_LCR_STB_15) |
       			 	parity);
	uart_barrier(bas);
}
Beispiel #21
0
static void
adm5120_uart_putc(struct uart_bas *bas, int c)
{
	char chr;
	chr = c;
	while (uart_getreg(bas, UART_FR_REG) & UART_FR_TX_FIFO_FULL)
		;
	uart_setreg(bas, UART_DR_REG, c);
	while (uart_getreg(bas, UART_FR_REG) & UART_FR_BUSY)
		;
	uart_barrier(bas);
}
Beispiel #22
0
static int
sa1110_bus_receive(struct uart_softc *sc)
{
	
#if 0
	while (!(uart_getreg(&sc->sc_bas, SACOM_SR1) & SR1_RNE)) {
		u_int32_t sr0;

		sr0 = uart_getreg(&sc->sc_bas, SACOM_SR0);
		if (ISSET(sr0, SR0_RBB))
			uart_setreg(&sc->sc_bas, SACOM_SR0, SR0_RBB);
		if (ISSET(sr0, SR0_REB))
			uart_setreg(&sc->sc_bas, SACOM_SR0, SR0_REB);
	}
#endif
	
	uart_setreg(&sc->sc_bas, SACOM_CR3, uart_getreg(&sc->sc_bas, SACOM_CR3)
	    | CR3_RIE);
	uart_rx_put(sc, uart_getreg(&sc->sc_bas, SACOM_DR));
	return (0);
}
Beispiel #23
0
/*
 * We can only flush UARTs with FIFOs. UARTs without FIFOs should be
 * drained. WARNING: this function clobbers the FIFO setting!
 */
static void
ns8250_flush(struct uart_bas *bas, int what)
{
	uint8_t fcr;

	fcr = FCR_ENABLE;
	if (what & UART_FLUSH_TRANSMITTER)
		fcr |= FCR_XMT_RST;
	if (what & UART_FLUSH_RECEIVER)
		fcr |= FCR_RCV_RST;
	uart_setreg(bas, REG_FCR, fcr);
	uart_barrier(bas);
}
Beispiel #24
0
static int
msm_bus_attach(struct uart_softc *sc)
{
	struct msm_uart_softc *u = (struct msm_uart_softc *)sc;
	struct uart_bas *bas = &sc->sc_bas;

	sc->sc_hwiflow = 0;
	sc->sc_hwoflow = 0;

	/* Set TX_READY, TXLEV, RXLEV, RXSTALE */
	u->ier = UART_DM_IMR_ENABLED;

	/* Configure Interrupt Mask register IMR */
	uart_setreg(bas, UART_DM_IMR, u->ier);

	return (0);
}
Beispiel #25
0
/*
 * UART class interface.
 */
static int
tegra_uart_attach(struct uart_softc *sc)
{
	int rv;
	struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc;
	struct uart_bas *bas = &sc->sc_bas;

	rv = ns8250_bus_attach(sc);
	if (rv != 0)
		return (rv);

	ns8250->ier_rxbits = 0x1d;
	ns8250->ier_mask = 0xc0;
	ns8250->ier = uart_getreg(bas, REG_IER) & ns8250->ier_mask;
	ns8250->ier = ns8250->ier_rxbits;
	uart_setreg(bas, REG_IER, ns8250->ier);
	uart_barrier(bas);
	return (0);
}
Beispiel #26
0
static int
msm_getc(struct uart_bas *bas, struct mtx *mtx)
{
	int c;

	uart_lock(mtx);

	/* Wait for a character to come ready */
	while ((uart_getreg(bas, UART_DM_SR) & UART_DM_SR_RXRDY) !=
	    UART_DM_SR_RXRDY)
		DELAY(4);

	/* Check for Overrun error. If so reset Error Status */
	if (uart_getreg(bas, UART_DM_SR) & UART_DM_SR_UART_OVERRUN)
		uart_setreg(bas, UART_DM_CR, UART_DM_RESET_ERROR_STATUS);

	/* Read char */
	c = uart_getreg(bas, UART_DM_RF(0));

	uart_unlock(mtx);

	return (c);
}
Beispiel #27
0
static int
jz4780_bus_attach(struct uart_softc *sc)
{
    struct ns8250_softc *ns8250;
    struct uart_bas *bas;
    int rv;

    ns8250 = (struct ns8250_softc *)sc;
    bas = &sc->sc_bas;

    rv = ns8250_bus_attach(sc);
    if (rv != 0)
        return (0);

    /* Configure uart to use extra IER_RXTMOUT bit */
    ns8250->ier_rxbits = IER_RXTMOUT | IER_EMSC | IER_ERLS | IER_ERXRDY;
    ns8250->ier_mask = ~(ns8250->ier_rxbits);
    ns8250->ier = uart_getreg(bas, REG_IER) & ns8250->ier_mask;
    ns8250->ier |= ns8250->ier_rxbits;
    uart_setreg(bas, REG_IER, ns8250->ier);
    uart_barrier(bas);
    return (0);
}
Beispiel #28
0
static void
msm_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
    int parity)
{

	if (bas->rclk == 0)
		bas->rclk = DEF_CLK;

	KASSERT(bas->rclk != 0, ("msm_init: Invalid rclk"));

	/* Set default parameters */
	msm_uart_param(bas, baudrate, databits, stopbits, parity);

	/*
	 * Configure UART mode registers MR1 and MR2.
	 * Hardware flow control isn't supported.
	 */
	uart_setreg(bas, UART_DM_MR1, 0x0);

	/* Reset interrupt mask register. */
	uart_setreg(bas, UART_DM_IMR, 0);

	/*
	 * Configure Tx and Rx watermarks configuration registers.
	 * TX watermark value is set to 0 - interrupt is generated when
	 * FIFO level is less than or equal to 0.
	 */
	uart_setreg(bas, UART_DM_TFWR, UART_DM_TFW_VALUE);

	/* Set RX watermark value */
	uart_setreg(bas, UART_DM_RFWR, UART_DM_RFW_VALUE);

	/*
	 * Configure Interrupt Programming Register.
	 * Set initial Stale timeout value.
	 */
	uart_setreg(bas, UART_DM_IPR, UART_DM_STALE_TIMEOUT_LSB);

	/* Disable IRDA mode */
	uart_setreg(bas, UART_DM_IRDA, 0x0);

	/*
	 * Configure and enable sim interface if required.
	 * Configure hunt character value in HCR register.
	 * Keep it in reset state.
	 */
	uart_setreg(bas, UART_DM_HCR, 0x0);

	/* Issue soft reset command */
	SETREG(bas, UART_DM_CR, UART_DM_RESET_TX);
	SETREG(bas, UART_DM_CR, UART_DM_RESET_RX);
	SETREG(bas, UART_DM_CR, UART_DM_RESET_ERROR_STATUS);
	SETREG(bas, UART_DM_CR, UART_DM_RESET_BREAK_INT);
	SETREG(bas, UART_DM_CR, UART_DM_RESET_STALE_INT);

	/* Enable/Disable Rx/Tx DM interfaces */
	/* Disable Data Mover for now. */
	uart_setreg(bas, UART_DM_DMEN, 0x0);

	/* Enable transmitter and receiver */
	uart_setreg(bas, UART_DM_CR, UART_DM_CR_RX_ENABLE);
	uart_setreg(bas, UART_DM_CR, UART_DM_CR_TX_ENABLE);

	uart_barrier(bas);
}
Beispiel #29
0
static void
sa1110_putc(struct uart_bas *bas, int c)
{
	while (!(uart_getreg(bas, SACOM_SR1) & SR1_TNF));
	uart_setreg(bas, SACOM_DR, c);
}
Beispiel #30
0
static int
msm_uart_param(struct uart_bas *bas, int baudrate, int databits,
    int stopbits, int parity)
{
	int ulcon;

	ulcon = 0;

	switch (databits) {
	case 5:
		ulcon |= (UART_DM_5_BPS << 4);
		break;
	case 6:
		ulcon |= (UART_DM_6_BPS << 4);
		break;
	case 7:
		ulcon |= (UART_DM_7_BPS << 4);
		break;
	case 8:
		ulcon |= (UART_DM_8_BPS << 4);
		break;
	default:
		return (EINVAL);
	}

	switch (parity) {
	case UART_PARITY_NONE:
		ulcon |= UART_DM_NO_PARITY;
		break;
	case UART_PARITY_ODD:
		ulcon |= UART_DM_ODD_PARITY;
		break;
	case UART_PARITY_EVEN:
		ulcon |= UART_DM_EVEN_PARITY;
		break;
	case UART_PARITY_SPACE:
		ulcon |= UART_DM_SPACE_PARITY;
		break;
	case UART_PARITY_MARK:
	default:
		return (EINVAL);
	}

	switch (stopbits) {
	case 1:
		ulcon |= (UART_DM_SBL_1 << 2);
		break;
	case 2:
		ulcon |= (UART_DM_SBL_2 << 2);
		break;
	default:
		return (EINVAL);
	}
	uart_setreg(bas, UART_DM_MR2, ulcon);

	/* Set 115200 for both TX and RX. */;
	uart_setreg(bas, UART_DM_CSR, UART_DM_CSR_115200);
	uart_barrier(bas);

	return (0);
}