Exemplo n.º 1
0
void octeon_set_baud(uint32_t uart, uint32_t baud)
{
    uint16_t divisor;
    uint8_t uart_index = GET_UART_INDEX(uart);
    uint8_t node = GET_UART_NODE(uart);
    cvmx_uart_lcr_t lcrval;

    divisor = compute_divisor(octeon_get_ioclk_hz(), baud);

    lcrval.u64 = cvmx_read_csr_node(node, CVMX_MIO_UARTX_LCR(uart_index));

    cvmx_wait((2 * divisor * 16) + 10000);

    lcrval.s.dlab = 1;	/* temporary to program the divisor */
    cvmx_write_csr_node(node, CVMX_MIO_UARTX_LCR(uart_index), lcrval.u64);

    cvmx_write_csr_node(node, CVMX_MIO_UARTX_DLL(uart_index), divisor & 0xff);
    cvmx_write_csr_node(node, CVMX_MIO_UARTX_DLH(uart_index), (divisor >> 8) & 0xff);
    /* divisor is programmed now, set this back to normal */
    lcrval.s.dlab = 0;
    cvmx_write_csr_node(node, CVMX_MIO_UARTX_LCR(uart_index), lcrval.u64);

#ifndef CONFIG_OCTEON_SIM_SPEED
    /* spec says need to wait after you program the divisor */
    cvmx_wait((2 * divisor * 16) + 10000);
    /* Wait a little longer..... */
    mdelay(5);
#endif
}
Exemplo n.º 2
0
int uart_configure(unsigned int uart_num, uint32_t baudrate)
{
    UxMODE(uart_num) = 0;
    UxSTA(uart_num) = 0;
    return compute_divisor(uart_num, baudrate);
}
Exemplo n.º 3
0
/**
 * Function that does the real work of setting up the Octeon uart.
 * Takes all parameters as arguments, so it does not require gd
 * structure to be set up.
 *
 * @param uart_index Index of uart to configure
 * @param cpu_clock_hertz
 *                   CPU clock frequency in Hz
 * @param baudrate   Baudrate to configure
 *
 * @return 0 on success
 *         !0 on error
 */
int octeon_uart_setup2(int uart, int cpu_clock_hertz, int baudrate)
{
    uint16_t divisor;
    cvmx_uart_fcr_t fcrval;
    cvmx_uart_mcr_t mcrval;
    cvmx_uart_lcr_t lcrval;
    uint8_t uart_index = GET_UART_INDEX(uart);
    uint8_t node = GET_UART_NODE(uart);
#if !CONFIG_OCTEON_SIM_SPEED
    uint64_t read_cycle;
#endif

    fcrval.u64 = 0;
    fcrval.s.en = 1;	/* enable the FIFO's */
    fcrval.s.rxfr = 1;	/* reset the RX fifo */
    fcrval.s.txfr = 1;	/* reset the TX fifo */

    divisor = compute_divisor(cpu_clock_hertz, baudrate);

    cvmx_write_csr_node(node, CVMX_MIO_UARTX_FCR(uart_index), fcrval.u64);

    mcrval.u64 = 0;
#if CONFIG_OCTEON_SIM_SETUP
    if (uart_index == 1)
        mcrval.s.afce = 1;	/* enable auto flow control for
					 * simulator. Needed for gdb
					 * regression callfuncs.exp.
					 */
    else
        mcrval.s.afce = 0;	/* disable auto flow control so board
					 * can power on without serial port
					 * connected
					 */
#else
    mcrval.s.afce = 0;	/* disable auto flow control so board can power
				 * on without serial port connected
				 */
#endif
    mcrval.s.rts = 1;	/* looks like this must be set for auto flow
				 * control to work
				 */

    cvmx_read_csr_node(node, CVMX_MIO_UARTX_LSR(uart_index));

    lcrval.u64 = 0;
    lcrval.s.cls = CVMX_UART_BITS8;
    lcrval.s.stop = 0;	/* stop bit included? */
    lcrval.s.pen = 0;	/* no parity? */
    lcrval.s.eps = 1;	/* even parity? */
    lcrval.s.dlab = 1;	/* temporary to program the divisor */
    cvmx_write_csr_node(node, CVMX_MIO_UARTX_LCR(uart_index), lcrval.u64);

    cvmx_write_csr_node(node, CVMX_MIO_UARTX_DLL(uart_index), divisor & 0xff);
    cvmx_write_csr_node(node, CVMX_MIO_UARTX_DLH(uart_index), (divisor >> 8) & 0xff);

    /* divisor is programmed now, set this back to normal */
    lcrval.s.dlab = 0;
    cvmx_write_csr_node(node, CVMX_MIO_UARTX_LCR(uart_index), lcrval.u64);

#if !CONFIG_OCTEON_SIM_SPEED
    /* spec says need to wait after you program the divisor */
    read_cycle = octeon_get_cycles() + (2 * divisor * 16) + 10000;
    while (octeon_get_cycles() < read_cycle) {
        /* Spin */
    }
#endif

    /* Don't enable flow control until after baud rate is configured. - we
     * don't want to allow characters in until after the baud rate is
     * fully configured
     */
    cvmx_write_csr_node(node, CVMX_MIO_UARTX_MCR(uart_index), mcrval.u64);
    return 0;

}