cvmx-uart.c revision 302408
1/***********************license start*************** 2 * Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights 3 * reserved. 4 * 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * * Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following 15 * disclaimer in the documentation and/or other materials provided 16 * with the distribution. 17 18 * * Neither the name of Cavium Inc. nor the names of 19 * its contributors may be used to endorse or promote products 20 * derived from this software without specific prior written 21 * permission. 22 23 * This Software, including technical data, may be subject to U.S. export control 24 * laws, including the U.S. Export Administration Act and its associated 25 * regulations, and may be subject to export or import regulations in other 26 * countries. 27 28 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 29 * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR 30 * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO 31 * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR 32 * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM 33 * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, 34 * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF 35 * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR 36 * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR 37 * PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 38 ***********************license end**************************************/ 39 40 41#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 42#include <linux/module.h> 43#include <asm/octeon/cvmx.h> 44#include <asm/octeon/cvmx-clock.h> 45#include <asm/octeon/cvmx-uart.h> 46#else 47#include "cvmx.h" 48#include "cvmx-uart.h" 49#include "cvmx-interrupt.h" 50#endif 51 52#ifndef CVMX_BUILD_FOR_TOOLCHAIN 53void cvmx_uart_enable_intr(int uart, cvmx_uart_intr_handler_t handler) 54{ 55#ifndef CVMX_BUILD_FOR_LINUX_KERNEL 56 cvmx_uart_ier_t ier; 57 58 cvmx_interrupt_register(CVMX_IRQ_UART0 + uart, handler, NULL); 59 /* Enable uart interrupts for debugger Control-C processing */ 60 ier.u64 = cvmx_read_csr(CVMX_MIO_UARTX_IER(uart)); 61 ier.s.erbfi = 1; 62 cvmx_write_csr(CVMX_MIO_UARTX_IER(uart), ier.u64); 63 64 cvmx_interrupt_unmask_irq(CVMX_IRQ_UART0 + uart); 65#endif 66} 67#endif 68 69static int cvmx_uart_simulator_p(void) 70{ 71#ifndef CVMX_BUILD_FOR_TOOLCHAIN 72 return cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM; 73#else 74 extern int __octeon_simulator_p; 75 return __octeon_simulator_p; 76#endif 77} 78 79 80/** 81 * Function that does the real work of setting up the Octeon uart. 82 * Takes all parameters as arguments, so it does not require gd 83 * structure to be set up. 84 * 85 * @param uart_index Index of uart to configure 86 * @param cpu_clock_hertz 87 * CPU clock frequency in Hz 88 * @param baudrate Baudrate to configure 89 * 90 * @return 0 on success 91 * !0 on error 92 */ 93int cvmx_uart_setup2(int uart_index, int cpu_clock_hertz, int baudrate) 94{ 95 uint16_t divisor; 96 cvmx_uart_fcr_t fcrval; 97 cvmx_uart_mcr_t mcrval; 98 cvmx_uart_lcr_t lcrval; 99 100 fcrval.u64 = 0; 101 fcrval.s.en = 1; /* enable the FIFO's */ 102 fcrval.s.rxfr = 1; /* reset the RX fifo */ 103 fcrval.s.txfr = 1; /* reset the TX fifo */ 104 105 if (cvmx_uart_simulator_p()) 106 divisor = 1; 107 else 108 divisor = ((unsigned long)(cpu_clock_hertz + 8 * baudrate) / (unsigned long)(16 * baudrate)); 109 110 cvmx_write_csr(CVMX_MIO_UARTX_FCR(uart_index), fcrval.u64); 111 112 mcrval.u64 = 0; 113 if (uart_index == 1 && cvmx_uart_simulator_p()) 114 mcrval.s.afce = 1; /* enable auto flow control for simulator. Needed for gdb regression callfuncs.exp. */ 115 else 116 mcrval.s.afce = 0; /* disable auto flow control so board can power on without serial port connected */ 117 118 mcrval.s.rts = 1; /* looks like this must be set for auto flow control to work */ 119 120 cvmx_read_csr(CVMX_MIO_UARTX_LSR(uart_index)); 121 122 lcrval.u64 = 0; 123 lcrval.s.cls = CVMX_UART_BITS8; 124 lcrval.s.stop = 0; /* stop bit included? */ 125 lcrval.s.pen = 0; /* no parity? */ 126 lcrval.s.eps = 1; /* even parity? */ 127 lcrval.s.dlab = 1; /* temporary to program the divisor */ 128 cvmx_write_csr(CVMX_MIO_UARTX_LCR(uart_index), lcrval.u64); 129 130 cvmx_write_csr(CVMX_MIO_UARTX_DLL(uart_index), divisor & 0xff); 131 cvmx_write_csr(CVMX_MIO_UARTX_DLH(uart_index), (divisor>>8) & 0xff); 132 133 lcrval.s.dlab = 0; /* divisor is programmed now, set this back to normal */ 134 cvmx_write_csr(CVMX_MIO_UARTX_LCR(uart_index), lcrval.u64); 135 136 /* spec says need to wait after you program the divisor */ 137 if (!cvmx_uart_simulator_p()) 138 { 139 uint64_t read_cycle; 140 CVMX_MF_CYCLE (read_cycle); 141 read_cycle += (2 * divisor * 16) + 10000; 142 143 /* Spin */ 144 while (1) 145 { 146 uint64_t new_cycle; 147 CVMX_MF_CYCLE (new_cycle); 148 if (new_cycle >= read_cycle) 149 break; 150 } 151 } 152 153 /* Don't enable flow control until after baud rate is configured. - we don't want 154 ** to allow characters in until after the baud rate is fully configured */ 155 cvmx_write_csr(CVMX_MIO_UARTX_MCR(uart_index), mcrval.u64); 156 return 0; 157 158} 159 160/** 161 * Setup a uart for use 162 * 163 * @param uart_index Uart to setup (0 or 1) 164 * @return Zero on success 165 */ 166int cvmx_uart_setup (int uart_index) 167{ 168 return cvmx_uart_setup2(uart_index, cvmx_clock_get_rate (CVMX_CLOCK_SCLK), 115200); 169} 170 171