blob: d962ffa799fce337b696e48d5c8564f33e7d053c [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/******************************************************************************
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
82void serial_init(void);
83int serial_poll(void);
84int serial_read(void);
85int serial_write(int c);
86
87void 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 */
159int 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 */
175int 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 */
193int 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 */
211int 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}