1 /*
2 * PMC-Sierra Inc. Stretch Board
3 * Author: Manish Lachwani (lachwani@pmc-sierra.com)
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
11 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
13 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
14 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
15 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
16 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
17 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
19 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * KGDB support for the PMC-Sierra Stretch board
26 *
27 */
28
29 #include <linux/config.h>
30
31 #if defined(CONFIG_REMOTE_DEBUG)
32
33 #include <asm/serial.h> /* For the serial port location and base baud */
34
35
36 typedef unsigned char uint8;
37 typedef unsigned int uint32;
38
39 /*
40 * Baud rate
41 */
42 #define UART16550_BAUD_2400 2400
43 #define UART16550_BAUD_4800 4800
44 #define UART16550_BAUD_9600 9600
45 #define UART16550_BAUD_19200 19200
46 #define UART16550_BAUD_38400 38400
47 #define UART16550_BAUD_57600 57600
48 #define UART16550_BAUD_115200 115200
49
50 /*
51 * Parity bit
52 */
53 #define UART16550_PARITY_NONE 0
54 #define UART16550_PARITY_ODD 0x08
55 #define UART16550_PARITY_EVEN 0x18
56 #define UART16550_PARITY_MARK 0x28
57 #define UART16550_PARITY_SPACE 0x38
58
59 /*
60 * Data bit
61 */
62 #define UART16550_DATA_5BIT 0x0
63 #define UART16550_DATA_6BIT 0x1
64 #define UART16550_DATA_7BIT 0x2
65 #define UART16550_DATA_8BIT 0x3
66
67 /*
68 * Stop bit
69 */
70 #define UART16550_STOP_1BIT 0x0
71 #define UART16550_STOP_2BIT 0x4
72
73 /*
74 * Serial port defines
75 */
76 #define BASE PMC_STRETCH_SERIAL1_BASE
77 #define MAX_BAUD PMC_STRETCH_BASE_BAUD
78
79
80 #define REG_OFFSET 2
81
82 /*
83 * register offset
84 */
85 #define OFS_RCV_BUFFER 0
86 #define OFS_TRANS_HOLD 0
87 #define OFS_SEND_BUFFER 0
88 #define OFS_INTR_ENABLE (1*REG_OFFSET)
89 #define OFS_INTR_ID (2*REG_OFFSET)
90 #define OFS_DATA_FORMAT (3*REG_OFFSET)
91 #define OFS_LINE_CONTROL (3*REG_OFFSET)
92 #define OFS_MODEM_CONTROL (4*REG_OFFSET)
93 #define OFS_RS232_OUTPUT (4*REG_OFFSET)
94 #define OFS_LINE_STATUS (5*REG_OFFSET)
95 #define OFS_MODEM_STATUS (6*REG_OFFSET)
96 #define OFS_RS232_INPUT (6*REG_OFFSET)
97 #define OFS_SCRATCH_PAD (7*REG_OFFSET)
98
99 #define OFS_DIVISOR_LSB (0*REG_OFFSET)
100 #define OFS_DIVISOR_MSB (1*REG_OFFSET)
101
102
103 /*
104 * memory-mapped read/write of the port
105 */
106 #define UART16550_READ(y) (*((volatile uint8*)(BASE + y)))
107 #define UART16550_WRITE(y, z) ((*((volatile uint8*)(BASE + y))) = z)
108
debugInit(uint32 baud,uint8 data,uint8 parity,uint8 stop)109 void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
110 {
111 /* disable interrupts */
112 UART16550_WRITE(OFS_INTR_ENABLE, 0);
113
114 /* set up buad rate */
115 {
116 uint32 divisor;
117
118 /* set DIAB bit */
119 UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
120
121 /* set divisor */
122 divisor = MAX_BAUD / baud;
123 UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
124 UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
125
126 /* clear DIAB bit */
127 UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
128 }
129
130 /* set data format */
131 UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
132 }
133
134 static int remoteDebugInitialized = 0;
135
getDebugChar(void)136 uint8 getDebugChar(void)
137 {
138 if (!remoteDebugInitialized) {
139 remoteDebugInitialized = 1;
140 debugInit(UART16550_BAUD_38400,
141 UART16550_DATA_8BIT,
142 UART16550_PARITY_NONE, UART16550_STOP_1BIT);
143 }
144
145 while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
146 return UART16550_READ(OFS_RCV_BUFFER);
147 }
148
149
putDebugChar(uint8 byte)150 int putDebugChar(uint8 byte)
151 {
152 if (!remoteDebugInitialized) {
153 remoteDebugInitialized = 1;
154 debugInit(UART16550_BAUD_38400,
155 UART16550_DATA_8BIT,
156 UART16550_PARITY_NONE, UART16550_STOP_1BIT);
157 }
158
159 while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
160 UART16550_WRITE(OFS_SEND_BUFFER, byte);
161 return 1;
162 }
163
164 #endif
165