b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame^] | 1 | /****************************************************************************** |
| 2 | * |
| 3 | * (C)Copyright 2014 Marvell Hefei Branch. All Rights Reserved. |
| 4 | * |
| 5 | * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MARVELL. |
| 6 | * The copyright notice above does not evidence any actual or intended |
| 7 | * publication of such source code. |
| 8 | * This Module contains Proprietary Information of Marvell and should be |
| 9 | * treated as Confidential. |
| 10 | * The information in this file is provided for the exclusive use of the |
| 11 | * licensees of Marvell. |
| 12 | * Such users have the right to use, modify, and incorporate this code into |
| 13 | * products for purposes authorized by the license agreement provided they |
| 14 | * include this notice and the associated copyright notice with any such |
| 15 | * product. |
| 16 | * The information in this file is provided "AS IS" without warranty. |
| 17 | * |
| 18 | ******************************************************************************/ |
| 19 | |
| 20 | #include "Typedef.h" |
| 21 | #include "PMUM.h" |
| 22 | #include "APBC.h" |
| 23 | |
| 24 | #define __REG(x) (*((volatile unsigned int *)(x))) |
| 25 | |
| 26 | #if NZA2 || CPUART |
| 27 | #define UART_BASE 0xd4036000 // For AP UART1 |
| 28 | #elif KSTR |
| 29 | #define UART_BASE 0xd4018000 // For AP UART2 |
| 30 | #else |
| 31 | #if LAPW |
| 32 | #define UART_BASE 0xD401F000 // For AP UART3 |
| 33 | #else |
| 34 | #define UART_BASE 0xd4017000 // For AP UART1 |
| 35 | #endif |
| 36 | #endif |
| 37 | |
| 38 | #define SerialDATA __REG(UART_BASE+0x00) /* Receive Buffer Register (read only) */ |
| 39 | #define SerialFIFO __REG(UART_BASE+0x08) /* FIFO Control Register (write only) */ |
| 40 | #define SerialLCR __REG(UART_BASE+0x0c) /* Line Control Register (read/write) */ |
| 41 | #define SerialMCR __REG(UART_BASE+0x10) /* Modem Control Register (read/write) */ |
| 42 | #define SerialLSR __REG(UART_BASE+0x14) /* Line Status Register (read only) */ |
| 43 | #define SerialMSR __REG(UART_BASE+0x18) /* Modem Status Register (read only) */ |
| 44 | #define SerialSCR __REG(UART_BASE+0x1c) /* Scratchpad Register*/ |
| 45 | #define SerialIER __REG(UART_BASE+0x04) /* Interrupt Enable Register (read/write) */ |
| 46 | #define SerialABR __REG(UART_BASE+0x28) |
| 47 | |
| 48 | #define IER_DMAE (1 << 7) /* DMA Requests Enable */ |
| 49 | #define IER_UUE (1 << 6) /* UART Unit Enable */ |
| 50 | #define IER_NRZE (1 << 5) /* NRZ coding Enable */ |
| 51 | #define IER_RTIOE (1 << 4) /* Receiver Time Out Interrupt Enable */ |
| 52 | #define IER_MIE (1 << 3) /* Modem Interrupt Enable */ |
| 53 | #define IER_RLSE (1 << 2) /* Receiver Line Status Interrupt Enable */ |
| 54 | #define IER_TIE (1 << 1) /* Transmit Data request Interrupt Enable */ |
| 55 | #define IER_RAVIE (1 << 0) /* Receiver Data Available Interrupt Enable */ |
| 56 | |
| 57 | #define IIR_FIFOES1 (1 << 7) /* FIFO Mode Enable Status */ |
| 58 | #define IIR_FIFOES0 (1 << 6) /* FIFO Mode Enable Status */ |
| 59 | #define IIR_TOD (1 << 3) /* Time Out Detected */ |
| 60 | #define IIR_IID2 (1 << 2) /* Interrupt Source Encoded */ |
| 61 | #define IIR_IID1 (1 << 1) /* Interrupt Source Encoded */ |
| 62 | #define IIR_IP (1 << 0) /* Interrupt Pending (active low) */ |
| 63 | #define LCR_DLAB (1 << 7) /* Divisor Latch Access Bit */ |
| 64 | #define LCR_SB (1 << 6) /* Set Break */ |
| 65 | #define LCR_STKYP (1 << 5) /* Sticky Parity */ |
| 66 | #define LCR_EPS (1 << 4) /* Even Parity Select */ |
| 67 | #define LCR_PEN (1 << 3) /* Parity Enable */ |
| 68 | #define LCR_STB (1 << 2) /* Stop Bit */ |
| 69 | #define LCR_WLS1 (1 << 1) /* Word Length Select */ |
| 70 | #define LCR_WLS0 (1 << 0) /* Word Length Select */ |
| 71 | |
| 72 | #define LSR_FIFOE (1 << 7) /* FIFO Error Status */ |
| 73 | #define LSR_TEMT (1 << 6) /* Transmitter Empty */ |
| 74 | #define LSR_TDRQ (1 << 5) /* Transmit Data Request */ |
| 75 | #define LSR_BI (1 << 4) /* Break Interrupt */ |
| 76 | #define LSR_FE (1 << 3) /* Framing Error */ |
| 77 | #define LSR_PE (1 << 2) /* Parity Error */ |
| 78 | #define LSR_OE (1 << 1) /* Overrun Error */ |
| 79 | #define LSR_DR (1 << 0) /* Data Ready */ |
| 80 | |
| 81 | #define BAUD_RATE_921600 1 |
| 82 | void serial_init(void); |
| 83 | int serial_poll(void); |
| 84 | int serial_read(void); |
| 85 | int serial_write(int c); |
| 86 | |
| 87 | void serial_init(void) |
| 88 | { |
| 89 | /*115200 unsigned int divisor = 24; */ |
| 90 | //unsigned int divisor = 31; // 31 for 38400 baudrate; |
| 91 | unsigned int divisor = 8; |
| 92 | int i; |
| 93 | |
| 94 | #if FPGA |
| 95 | divisor = 7; |
| 96 | #elif EMULATOR |
| 97 | divisor = 1; |
| 98 | #endif |
| 99 | #ifdef CONFIG_UART_921600 |
| 100 | divisor = BAUD_RATE_921600; |
| 101 | #endif |
| 102 | #if EMULATOR |
| 103 | __REG(PMUM_ACGR) |= PMUM_ACGR_AP_FUART; |
| 104 | i = 0; |
| 105 | while(i++ < 400); |
| 106 | #if KSTR |
| 107 | __REG(APBC_UART1_CLK_RST) = 0x3; |
| 108 | #else |
| 109 | __REG(APBC_UART0_CLK_RST) = 0x3; |
| 110 | #endif |
| 111 | SerialIER |= 0x100; |
| 112 | #endif |
| 113 | |
| 114 | /* switch receiver and transmitter off */ |
| 115 | SerialLCR = 0; |
| 116 | SerialIER = 0; |
| 117 | //SerialFIFO = 0; |
| 118 | /* rest tx/rx/ FIFOs*/ |
| 119 | SerialFIFO = BIT2 | BIT1; |
| 120 | SerialSCR = 0; |
| 121 | |
| 122 | /* read this to clear them*/ |
| 123 | i = SerialDATA; |
| 124 | i = SerialLSR; |
| 125 | i = SerialMSR; |
| 126 | |
| 127 | /* 1 stop bit, 8 bit character */ |
| 128 | SerialLCR = LCR_WLS0 | LCR_WLS1 | LCR_DLAB; |
| 129 | |
| 130 | /* Load baud rate divisor in two steps, lsb, then msb of value */ |
| 131 | SerialDATA = divisor & 0xff; |
| 132 | SerialIER = (divisor >> 8) & 0xff; |
| 133 | |
| 134 | /* set the port to sensible defaults (no break, no interrupts, |
| 135 | * no parity, 8 databits, 1 stopbit, transmitter and receiver |
| 136 | * enabled), reset dlab bit: |
| 137 | */ |
| 138 | //SerialLCR = LCR_WLS1 | LCR_WLS0; |
| 139 | /* gain access*/ |
| 140 | SerialLCR &= 0x7f; |
| 141 | SerialMCR |= BIT3; // enable UART interrupte |
| 142 | |
| 143 | /*enable and clear FIFOs and set INT trigger level to be 8 bytes*/ |
| 144 | SerialFIFO = BIT0 | BIT3 | BIT6; |
| 145 | |
| 146 | #if EMULATOR |
| 147 | SerialMCR = 0x3; |
| 148 | #endif |
| 149 | |
| 150 | /* turn the receiver and transmitter back on */ |
| 151 | /* enable UART and individual interruptes*/ |
| 152 | SerialIER = BIT0 | BIT2 | BIT6; |
| 153 | } |
| 154 | |
| 155 | |
| 156 | /* check if there is a character available to read. returns 1 if there |
| 157 | * is a character available, 0 if not, and negative error number on |
| 158 | * failure */ |
| 159 | int serial_poll(void) |
| 160 | { |
| 161 | /* check for errors */ |
| 162 | if(SerialLSR & (LSR_FE | LSR_PE | LSR_OE)) |
| 163 | return -1; |
| 164 | |
| 165 | if(SerialLSR & LSR_DR) |
| 166 | return 1; |
| 167 | else |
| 168 | return 0; |
| 169 | } |
| 170 | |
| 171 | |
| 172 | /* read one character from the serial port. return character (between |
| 173 | * 0 and 255) on success, or negative error number on failure. this |
| 174 | * function is blocking */ |
| 175 | int serial_read(void) |
| 176 | { |
| 177 | int rv; |
| 178 | |
| 179 | for(;;) { |
| 180 | rv = serial_poll(); |
| 181 | |
| 182 | if(rv < 0) |
| 183 | return rv; |
| 184 | |
| 185 | if(rv > 0) |
| 186 | return SerialDATA & 0xff; |
| 187 | } |
| 188 | } |
| 189 | |
| 190 | /* read one character from the serial port. return character (between |
| 191 | * 0 and 255) on success, or negative error number on failure. this |
| 192 | * function is blocking */ |
| 193 | int serial_read_byte(void) |
| 194 | { |
| 195 | int rv = 0; |
| 196 | |
| 197 | rv = serial_poll(); |
| 198 | |
| 199 | if(rv < 0) |
| 200 | return rv; |
| 201 | |
| 202 | if(rv > 0) |
| 203 | return SerialDATA & 0xff; |
| 204 | |
| 205 | return rv; |
| 206 | } |
| 207 | |
| 208 | /* write character to serial port. return 0 on success, or negative |
| 209 | * error number on failure. this function is blocking |
| 210 | */ |
| 211 | int serial_write(int c) |
| 212 | { |
| 213 | #if USE_SERIAL_DEBUG |
| 214 | /* wait for room in the transmit FIFO */ |
| 215 | while((SerialLSR & LSR_TDRQ) == 0) { |
| 216 | } |
| 217 | |
| 218 | SerialDATA = c & 0xff; |
| 219 | #endif |
| 220 | return 0; |
| 221 | } |