1215976Sjmallett/***********************license start*************** 2232812Sjmallett * Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights 3215976Sjmallett * reserved. 4215976Sjmallett * 5215976Sjmallett * 6215976Sjmallett * Redistribution and use in source and binary forms, with or without 7215976Sjmallett * modification, are permitted provided that the following conditions are 8215976Sjmallett * met: 9215976Sjmallett * 10215976Sjmallett * * Redistributions of source code must retain the above copyright 11215976Sjmallett * notice, this list of conditions and the following disclaimer. 12215976Sjmallett * 13215976Sjmallett * * Redistributions in binary form must reproduce the above 14215976Sjmallett * copyright notice, this list of conditions and the following 15215976Sjmallett * disclaimer in the documentation and/or other materials provided 16215976Sjmallett * with the distribution. 17215976Sjmallett 18232812Sjmallett * * Neither the name of Cavium Inc. nor the names of 19215976Sjmallett * its contributors may be used to endorse or promote products 20215976Sjmallett * derived from this software without specific prior written 21215976Sjmallett * permission. 22215976Sjmallett 23215976Sjmallett * This Software, including technical data, may be subject to U.S. export control 24215976Sjmallett * laws, including the U.S. Export Administration Act and its associated 25215976Sjmallett * regulations, and may be subject to export or import regulations in other 26215976Sjmallett * countries. 27215976Sjmallett 28215976Sjmallett * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 29232812Sjmallett * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR 30215976Sjmallett * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO 31215976Sjmallett * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR 32215976Sjmallett * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM 33215976Sjmallett * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, 34215976Sjmallett * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF 35215976Sjmallett * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR 36215976Sjmallett * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR 37215976Sjmallett * PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 38215976Sjmallett ***********************license end**************************************/ 39215976Sjmallett 40215976Sjmallett 41215976Sjmallett#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 42215976Sjmallett#include <linux/module.h> 43215976Sjmallett#include <asm/octeon/cvmx.h> 44215976Sjmallett#include <asm/octeon/cvmx-clock.h> 45215976Sjmallett#include <asm/octeon/cvmx-uart.h> 46215976Sjmallett#else 47215976Sjmallett#include "cvmx.h" 48215976Sjmallett#include "cvmx-uart.h" 49215976Sjmallett#include "cvmx-interrupt.h" 50215976Sjmallett#endif 51215976Sjmallett 52232812Sjmallett#ifndef CVMX_BUILD_FOR_TOOLCHAIN 53215976Sjmallettvoid cvmx_uart_enable_intr(int uart, cvmx_uart_intr_handler_t handler) 54215976Sjmallett{ 55215976Sjmallett#ifndef CVMX_BUILD_FOR_LINUX_KERNEL 56215976Sjmallett cvmx_uart_ier_t ier; 57215976Sjmallett 58215976Sjmallett cvmx_interrupt_register(CVMX_IRQ_UART0 + uart, handler, NULL); 59215976Sjmallett /* Enable uart interrupts for debugger Control-C processing */ 60215976Sjmallett ier.u64 = cvmx_read_csr(CVMX_MIO_UARTX_IER(uart)); 61215976Sjmallett ier.s.erbfi = 1; 62215976Sjmallett cvmx_write_csr(CVMX_MIO_UARTX_IER(uart), ier.u64); 63215976Sjmallett 64215976Sjmallett cvmx_interrupt_unmask_irq(CVMX_IRQ_UART0 + uart); 65215976Sjmallett#endif 66215976Sjmallett} 67215976Sjmallett#endif 68215976Sjmallett 69215976Sjmallettstatic int cvmx_uart_simulator_p(void) 70215976Sjmallett{ 71232812Sjmallett#ifndef CVMX_BUILD_FOR_TOOLCHAIN 72215976Sjmallett return cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM; 73215976Sjmallett#else 74215976Sjmallett extern int __octeon_simulator_p; 75215976Sjmallett return __octeon_simulator_p; 76215976Sjmallett#endif 77215976Sjmallett} 78215976Sjmallett 79215976Sjmallett 80215976Sjmallett/** 81215976Sjmallett * Function that does the real work of setting up the Octeon uart. 82215976Sjmallett * Takes all parameters as arguments, so it does not require gd 83215976Sjmallett * structure to be set up. 84215976Sjmallett * 85215976Sjmallett * @param uart_index Index of uart to configure 86215976Sjmallett * @param cpu_clock_hertz 87215976Sjmallett * CPU clock frequency in Hz 88215976Sjmallett * @param baudrate Baudrate to configure 89215976Sjmallett * 90215976Sjmallett * @return 0 on success 91215976Sjmallett * !0 on error 92215976Sjmallett */ 93215976Sjmallettint cvmx_uart_setup2(int uart_index, int cpu_clock_hertz, int baudrate) 94215976Sjmallett{ 95215976Sjmallett uint16_t divisor; 96215976Sjmallett cvmx_uart_fcr_t fcrval; 97215976Sjmallett cvmx_uart_mcr_t mcrval; 98215976Sjmallett cvmx_uart_lcr_t lcrval; 99215976Sjmallett 100215976Sjmallett fcrval.u64 = 0; 101215976Sjmallett fcrval.s.en = 1; /* enable the FIFO's */ 102215976Sjmallett fcrval.s.rxfr = 1; /* reset the RX fifo */ 103215976Sjmallett fcrval.s.txfr = 1; /* reset the TX fifo */ 104215976Sjmallett 105215976Sjmallett if (cvmx_uart_simulator_p()) 106215976Sjmallett divisor = 1; 107215976Sjmallett else 108215976Sjmallett divisor = ((unsigned long)(cpu_clock_hertz + 8 * baudrate) / (unsigned long)(16 * baudrate)); 109215976Sjmallett 110215976Sjmallett cvmx_write_csr(CVMX_MIO_UARTX_FCR(uart_index), fcrval.u64); 111215976Sjmallett 112215976Sjmallett mcrval.u64 = 0; 113215976Sjmallett if (uart_index == 1 && cvmx_uart_simulator_p()) 114215976Sjmallett mcrval.s.afce = 1; /* enable auto flow control for simulator. Needed for gdb regression callfuncs.exp. */ 115215976Sjmallett else 116215976Sjmallett mcrval.s.afce = 0; /* disable auto flow control so board can power on without serial port connected */ 117215976Sjmallett 118215976Sjmallett mcrval.s.rts = 1; /* looks like this must be set for auto flow control to work */ 119215976Sjmallett 120215976Sjmallett cvmx_read_csr(CVMX_MIO_UARTX_LSR(uart_index)); 121215976Sjmallett 122215976Sjmallett lcrval.u64 = 0; 123215976Sjmallett lcrval.s.cls = CVMX_UART_BITS8; 124215976Sjmallett lcrval.s.stop = 0; /* stop bit included? */ 125215976Sjmallett lcrval.s.pen = 0; /* no parity? */ 126215976Sjmallett lcrval.s.eps = 1; /* even parity? */ 127215976Sjmallett lcrval.s.dlab = 1; /* temporary to program the divisor */ 128215976Sjmallett cvmx_write_csr(CVMX_MIO_UARTX_LCR(uart_index), lcrval.u64); 129215976Sjmallett 130215976Sjmallett cvmx_write_csr(CVMX_MIO_UARTX_DLL(uart_index), divisor & 0xff); 131215976Sjmallett cvmx_write_csr(CVMX_MIO_UARTX_DLH(uart_index), (divisor>>8) & 0xff); 132215976Sjmallett 133215976Sjmallett lcrval.s.dlab = 0; /* divisor is programmed now, set this back to normal */ 134215976Sjmallett cvmx_write_csr(CVMX_MIO_UARTX_LCR(uart_index), lcrval.u64); 135215976Sjmallett 136215976Sjmallett /* spec says need to wait after you program the divisor */ 137215976Sjmallett if (!cvmx_uart_simulator_p()) 138215976Sjmallett { 139215976Sjmallett uint64_t read_cycle; 140215976Sjmallett CVMX_MF_CYCLE (read_cycle); 141215976Sjmallett read_cycle += (2 * divisor * 16) + 10000; 142215976Sjmallett 143215976Sjmallett /* Spin */ 144215976Sjmallett while (1) 145215976Sjmallett { 146215976Sjmallett uint64_t new_cycle; 147215976Sjmallett CVMX_MF_CYCLE (new_cycle); 148215976Sjmallett if (new_cycle >= read_cycle) 149215976Sjmallett break; 150215976Sjmallett } 151215976Sjmallett } 152215976Sjmallett 153215976Sjmallett /* Don't enable flow control until after baud rate is configured. - we don't want 154215976Sjmallett ** to allow characters in until after the baud rate is fully configured */ 155215976Sjmallett cvmx_write_csr(CVMX_MIO_UARTX_MCR(uart_index), mcrval.u64); 156215976Sjmallett return 0; 157215976Sjmallett 158215976Sjmallett} 159215976Sjmallett 160215976Sjmallett/** 161215976Sjmallett * Setup a uart for use 162215976Sjmallett * 163215976Sjmallett * @param uart_index Uart to setup (0 or 1) 164215976Sjmallett * @return Zero on success 165215976Sjmallett */ 166215976Sjmallettint cvmx_uart_setup (int uart_index) 167215976Sjmallett{ 168215976Sjmallett return cvmx_uart_setup2(uart_index, cvmx_clock_get_rate (CVMX_CLOCK_SCLK), 115200); 169215976Sjmallett} 170215976Sjmallett 171