| /****************************************************************************** |
| * |
| * (C)Copyright 2014 Marvell Hefei Branch. All Rights Reserved. |
| * |
| * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MARVELL. |
| * The copyright notice above does not evidence any actual or intended |
| * publication of such source code. |
| * This Module contains Proprietary Information of Marvell and should be |
| * treated as Confidential. |
| * The information in this file is provided for the exclusive use of the |
| * licensees of Marvell. |
| * Such users have the right to use, modify, and incorporate this code into |
| * products for purposes authorized by the license agreement provided they |
| * include this notice and the associated copyright notice with any such |
| * product. |
| * The information in this file is provided "AS IS" without warranty. |
| * |
| ******************************************************************************/ |
| |
| #include "Typedef.h" |
| #include "PMUM.h" |
| #include "APBC.h" |
| |
| #define __REG(x) (*((volatile unsigned int *)(x))) |
| |
| #if NZA2 || CPUART |
| #define UART_BASE 0xd4036000 // For AP UART1 |
| #elif KSTR |
| #define UART_BASE 0xd4018000 // For AP UART2 |
| #else |
| #if LAPW |
| #define UART_BASE 0xD401F000 // For AP UART3 |
| #else |
| #define UART_BASE 0xd4017000 // For AP UART1 |
| #endif |
| #endif |
| |
| #define SerialDATA __REG(UART_BASE+0x00) /* Receive Buffer Register (read only) */ |
| #define SerialFIFO __REG(UART_BASE+0x08) /* FIFO Control Register (write only) */ |
| #define SerialLCR __REG(UART_BASE+0x0c) /* Line Control Register (read/write) */ |
| #define SerialMCR __REG(UART_BASE+0x10) /* Modem Control Register (read/write) */ |
| #define SerialLSR __REG(UART_BASE+0x14) /* Line Status Register (read only) */ |
| #define SerialMSR __REG(UART_BASE+0x18) /* Modem Status Register (read only) */ |
| #define SerialSCR __REG(UART_BASE+0x1c) /* Scratchpad Register*/ |
| #define SerialIER __REG(UART_BASE+0x04) /* Interrupt Enable Register (read/write) */ |
| #define SerialABR __REG(UART_BASE+0x28) |
| |
| #define IER_DMAE (1 << 7) /* DMA Requests Enable */ |
| #define IER_UUE (1 << 6) /* UART Unit Enable */ |
| #define IER_NRZE (1 << 5) /* NRZ coding Enable */ |
| #define IER_RTIOE (1 << 4) /* Receiver Time Out Interrupt Enable */ |
| #define IER_MIE (1 << 3) /* Modem Interrupt Enable */ |
| #define IER_RLSE (1 << 2) /* Receiver Line Status Interrupt Enable */ |
| #define IER_TIE (1 << 1) /* Transmit Data request Interrupt Enable */ |
| #define IER_RAVIE (1 << 0) /* Receiver Data Available Interrupt Enable */ |
| |
| #define IIR_FIFOES1 (1 << 7) /* FIFO Mode Enable Status */ |
| #define IIR_FIFOES0 (1 << 6) /* FIFO Mode Enable Status */ |
| #define IIR_TOD (1 << 3) /* Time Out Detected */ |
| #define IIR_IID2 (1 << 2) /* Interrupt Source Encoded */ |
| #define IIR_IID1 (1 << 1) /* Interrupt Source Encoded */ |
| #define IIR_IP (1 << 0) /* Interrupt Pending (active low) */ |
| #define LCR_DLAB (1 << 7) /* Divisor Latch Access Bit */ |
| #define LCR_SB (1 << 6) /* Set Break */ |
| #define LCR_STKYP (1 << 5) /* Sticky Parity */ |
| #define LCR_EPS (1 << 4) /* Even Parity Select */ |
| #define LCR_PEN (1 << 3) /* Parity Enable */ |
| #define LCR_STB (1 << 2) /* Stop Bit */ |
| #define LCR_WLS1 (1 << 1) /* Word Length Select */ |
| #define LCR_WLS0 (1 << 0) /* Word Length Select */ |
| |
| #define LSR_FIFOE (1 << 7) /* FIFO Error Status */ |
| #define LSR_TEMT (1 << 6) /* Transmitter Empty */ |
| #define LSR_TDRQ (1 << 5) /* Transmit Data Request */ |
| #define LSR_BI (1 << 4) /* Break Interrupt */ |
| #define LSR_FE (1 << 3) /* Framing Error */ |
| #define LSR_PE (1 << 2) /* Parity Error */ |
| #define LSR_OE (1 << 1) /* Overrun Error */ |
| #define LSR_DR (1 << 0) /* Data Ready */ |
| |
| #define BAUD_RATE_921600 1 |
| void serial_init(void); |
| int serial_poll(void); |
| int serial_read(void); |
| int serial_write(int c); |
| |
| void serial_init(void) |
| { |
| /*115200 unsigned int divisor = 24; */ |
| //unsigned int divisor = 31; // 31 for 38400 baudrate; |
| unsigned int divisor = 8; |
| int i; |
| |
| #if FPGA |
| divisor = 7; |
| #elif EMULATOR |
| divisor = 1; |
| #endif |
| #ifdef CONFIG_UART_921600 |
| divisor = BAUD_RATE_921600; |
| #endif |
| #if EMULATOR |
| __REG(PMUM_ACGR) |= PMUM_ACGR_AP_FUART; |
| i = 0; |
| while(i++ < 400); |
| #if KSTR |
| __REG(APBC_UART1_CLK_RST) = 0x3; |
| #else |
| __REG(APBC_UART0_CLK_RST) = 0x3; |
| #endif |
| SerialIER |= 0x100; |
| #endif |
| |
| /* switch receiver and transmitter off */ |
| SerialLCR = 0; |
| SerialIER = 0; |
| //SerialFIFO = 0; |
| /* rest tx/rx/ FIFOs*/ |
| SerialFIFO = BIT2 | BIT1; |
| SerialSCR = 0; |
| |
| /* read this to clear them*/ |
| i = SerialDATA; |
| i = SerialLSR; |
| i = SerialMSR; |
| |
| /* 1 stop bit, 8 bit character */ |
| SerialLCR = LCR_WLS0 | LCR_WLS1 | LCR_DLAB; |
| |
| /* Load baud rate divisor in two steps, lsb, then msb of value */ |
| SerialDATA = divisor & 0xff; |
| SerialIER = (divisor >> 8) & 0xff; |
| |
| /* set the port to sensible defaults (no break, no interrupts, |
| * no parity, 8 databits, 1 stopbit, transmitter and receiver |
| * enabled), reset dlab bit: |
| */ |
| //SerialLCR = LCR_WLS1 | LCR_WLS0; |
| /* gain access*/ |
| SerialLCR &= 0x7f; |
| SerialMCR |= BIT3; // enable UART interrupte |
| |
| /*enable and clear FIFOs and set INT trigger level to be 8 bytes*/ |
| SerialFIFO = BIT0 | BIT3 | BIT6; |
| |
| #if EMULATOR |
| SerialMCR = 0x3; |
| #endif |
| |
| /* turn the receiver and transmitter back on */ |
| /* enable UART and individual interruptes*/ |
| SerialIER = BIT0 | BIT2 | BIT6; |
| } |
| |
| |
| /* check if there is a character available to read. returns 1 if there |
| * is a character available, 0 if not, and negative error number on |
| * failure */ |
| int serial_poll(void) |
| { |
| /* check for errors */ |
| if(SerialLSR & (LSR_FE | LSR_PE | LSR_OE)) |
| return -1; |
| |
| if(SerialLSR & LSR_DR) |
| return 1; |
| else |
| return 0; |
| } |
| |
| |
| /* read one character from the serial port. return character (between |
| * 0 and 255) on success, or negative error number on failure. this |
| * function is blocking */ |
| int serial_read(void) |
| { |
| int rv; |
| |
| for(;;) { |
| rv = serial_poll(); |
| |
| if(rv < 0) |
| return rv; |
| |
| if(rv > 0) |
| return SerialDATA & 0xff; |
| } |
| } |
| |
| /* read one character from the serial port. return character (between |
| * 0 and 255) on success, or negative error number on failure. this |
| * function is blocking */ |
| int serial_read_byte(void) |
| { |
| int rv = 0; |
| |
| rv = serial_poll(); |
| |
| if(rv < 0) |
| return rv; |
| |
| if(rv > 0) |
| return SerialDATA & 0xff; |
| |
| return rv; |
| } |
| |
| /* write character to serial port. return 0 on success, or negative |
| * error number on failure. this function is blocking |
| */ |
| int serial_write(int c) |
| { |
| #if USE_SERIAL_DEBUG |
| /* wait for room in the transmit FIFO */ |
| while((SerialLSR & LSR_TDRQ) == 0) { |
| } |
| |
| SerialDATA = c & 0xff; |
| #endif |
| return 0; |
| } |