1/***********************license start*************** 2 * Copyright (c) 2003-2010 Cavium Networks (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 Networks 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 NETWORKS 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 "executive-config.h" 48#include "cvmx.h" 49#include "cvmx-uart.h" 50#include "cvmx-interrupt.h" 51#endif 52 53#ifndef __OCTEON_NEWLIB__ 54void cvmx_uart_enable_intr(int uart, cvmx_uart_intr_handler_t handler) 55{ 56#ifndef CVMX_BUILD_FOR_LINUX_KERNEL 57 cvmx_uart_ier_t ier; 58 59 cvmx_interrupt_register(CVMX_IRQ_UART0 + uart, handler, NULL); 60 /* Enable uart interrupts for debugger Control-C processing */ 61 ier.u64 = cvmx_read_csr(CVMX_MIO_UARTX_IER(uart)); 62 ier.s.erbfi = 1; 63 cvmx_write_csr(CVMX_MIO_UARTX_IER(uart), ier.u64); 64 65 cvmx_interrupt_unmask_irq(CVMX_IRQ_UART0 + uart); 66#endif 67} 68#endif 69 70static int cvmx_uart_simulator_p(void) 71{ 72#ifndef __OCTEON_NEWLIB__ 73 return cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM; 74#else 75 extern int __octeon_simulator_p; 76 return __octeon_simulator_p; 77#endif 78} 79 80 81/** 82 * Function that does the real work of setting up the Octeon uart. 83 * Takes all parameters as arguments, so it does not require gd 84 * structure to be set up. 85 * 86 * @param uart_index Index of uart to configure 87 * @param cpu_clock_hertz 88 * CPU clock frequency in Hz 89 * @param baudrate Baudrate to configure 90 * 91 * @return 0 on success 92 * !0 on error 93 */ 94int cvmx_uart_setup2(int uart_index, int cpu_clock_hertz, int baudrate) 95{ 96 uint16_t divisor; 97 cvmx_uart_fcr_t fcrval; 98 cvmx_uart_mcr_t mcrval; 99 cvmx_uart_lcr_t lcrval; 100 101 fcrval.u64 = 0; 102 fcrval.s.en = 1; /* enable the FIFO's */ 103 fcrval.s.rxfr = 1; /* reset the RX fifo */ 104 fcrval.s.txfr = 1; /* reset the TX fifo */ 105 106 if (cvmx_uart_simulator_p()) 107 divisor = 1; 108 else 109 divisor = ((unsigned long)(cpu_clock_hertz + 8 * baudrate) / (unsigned long)(16 * baudrate)); 110 111 cvmx_write_csr(CVMX_MIO_UARTX_FCR(uart_index), fcrval.u64); 112 113 mcrval.u64 = 0; 114 if (uart_index == 1 && cvmx_uart_simulator_p()) 115 mcrval.s.afce = 1; /* enable auto flow control for simulator. Needed for gdb regression callfuncs.exp. */ 116 else 117 mcrval.s.afce = 0; /* disable auto flow control so board can power on without serial port connected */ 118 119 mcrval.s.rts = 1; /* looks like this must be set for auto flow control to work */ 120 121 cvmx_read_csr(CVMX_MIO_UARTX_LSR(uart_index)); 122 123 lcrval.u64 = 0; 124 lcrval.s.cls = CVMX_UART_BITS8; 125 lcrval.s.stop = 0; /* stop bit included? */ 126 lcrval.s.pen = 0; /* no parity? */ 127 lcrval.s.eps = 1; /* even parity? */ 128 lcrval.s.dlab = 1; /* temporary to program the divisor */ 129 cvmx_write_csr(CVMX_MIO_UARTX_LCR(uart_index), lcrval.u64); 130 131 cvmx_write_csr(CVMX_MIO_UARTX_DLL(uart_index), divisor & 0xff); 132 cvmx_write_csr(CVMX_MIO_UARTX_DLH(uart_index), (divisor>>8) & 0xff); 133 134 lcrval.s.dlab = 0; /* divisor is programmed now, set this back to normal */ 135 cvmx_write_csr(CVMX_MIO_UARTX_LCR(uart_index), lcrval.u64); 136 137 /* spec says need to wait after you program the divisor */ 138 if (!cvmx_uart_simulator_p()) 139 { 140 uint64_t read_cycle; 141 CVMX_MF_CYCLE (read_cycle); 142 read_cycle += (2 * divisor * 16) + 10000; 143 144 /* Spin */ 145 while (1) 146 { 147 uint64_t new_cycle; 148 CVMX_MF_CYCLE (new_cycle); 149 if (new_cycle >= read_cycle) 150 break; 151 } 152 } 153 154 /* Don't enable flow control until after baud rate is configured. - we don't want 155 ** to allow characters in until after the baud rate is fully configured */ 156 cvmx_write_csr(CVMX_MIO_UARTX_MCR(uart_index), mcrval.u64); 157 return 0; 158 159} 160 161/** 162 * Setup a uart for use 163 * 164 * @param uart_index Uart to setup (0 or 1) 165 * @return Zero on success 166 */ 167int cvmx_uart_setup (int uart_index) 168{ 169 return cvmx_uart_setup2(uart_index, cvmx_clock_get_rate (CVMX_CLOCK_SCLK), 115200); 170} 171 172