Merge branch 'merge'
[linux-2.6] / arch / mips / ddb5xxx / ddb5477 / kgdb_io.c
1 /*
2  * kgdb io functions for DDB5477.  We use the second serial port (upper one).
3  *
4  * Copyright (C) 2001 MontaVista Software Inc.
5  * Author: jsun@mvista.com or jsun@junsun.net
6  *
7  * This program is free software; you can redistribute  it and/or modify it
8  * under  the terms of  the GNU General  Public License as published by the
9  * Free Software Foundation;  either version 2 of the  License, or (at your
10  * option) any later version.
11  *
12  */
13
14 /* ======================= CONFIG ======================== */
15
16 /* [jsun] we use the second serial port for kdb */
17 #define         BASE                    0xbfa04240
18 #define         MAX_BAUD                115200
19
20 /* distance in bytes between two serial registers */
21 #define         REG_OFFSET              8
22
23 /*
24  * 0 - kgdb does serial init
25  * 1 - kgdb skip serial init
26  */
27 static int remoteDebugInitialized = 0;
28
29 /*
30  * the default baud rate *if* kgdb does serial init
31  */
32 #define         BAUD_DEFAULT            UART16550_BAUD_38400
33
34 /* ======================= END OF CONFIG ======================== */
35
36 typedef unsigned char uint8;
37 typedef unsigned int uint32;
38
39 #define         UART16550_BAUD_2400             2400
40 #define         UART16550_BAUD_4800             4800
41 #define         UART16550_BAUD_9600             9600
42 #define         UART16550_BAUD_19200            19200
43 #define         UART16550_BAUD_38400            38400
44 #define         UART16550_BAUD_57600            57600
45 #define         UART16550_BAUD_115200           115200
46
47 #define         UART16550_PARITY_NONE           0
48 #define         UART16550_PARITY_ODD            0x08
49 #define         UART16550_PARITY_EVEN           0x18
50 #define         UART16550_PARITY_MARK           0x28
51 #define         UART16550_PARITY_SPACE          0x38
52
53 #define         UART16550_DATA_5BIT             0x0
54 #define         UART16550_DATA_6BIT             0x1
55 #define         UART16550_DATA_7BIT             0x2
56 #define         UART16550_DATA_8BIT             0x3
57
58 #define         UART16550_STOP_1BIT             0x0
59 #define         UART16550_STOP_2BIT             0x4
60
61 /* register offset */
62 #define         OFS_RCV_BUFFER          0
63 #define         OFS_TRANS_HOLD          0
64 #define         OFS_SEND_BUFFER         0
65 #define         OFS_INTR_ENABLE         (1*REG_OFFSET)
66 #define         OFS_INTR_ID             (2*REG_OFFSET)
67 #define         OFS_DATA_FORMAT         (3*REG_OFFSET)
68 #define         OFS_LINE_CONTROL        (3*REG_OFFSET)
69 #define         OFS_MODEM_CONTROL       (4*REG_OFFSET)
70 #define         OFS_RS232_OUTPUT        (4*REG_OFFSET)
71 #define         OFS_LINE_STATUS         (5*REG_OFFSET)
72 #define         OFS_MODEM_STATUS        (6*REG_OFFSET)
73 #define         OFS_RS232_INPUT         (6*REG_OFFSET)
74 #define         OFS_SCRATCH_PAD         (7*REG_OFFSET)
75
76 #define         OFS_DIVISOR_LSB         (0*REG_OFFSET)
77 #define         OFS_DIVISOR_MSB         (1*REG_OFFSET)
78
79
80 /* memory-mapped read/write of the port */
81 #define         UART16550_READ(y)    (*((volatile uint8*)(BASE + y)))
82 #define         UART16550_WRITE(y, z)  ((*((volatile uint8*)(BASE + y))) = z)
83
84 void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
85 {
86         /* disable interrupts */
87         UART16550_WRITE(OFS_INTR_ENABLE, 0);
88
89         /* set up baud rate */
90         {
91                 uint32 divisor;
92
93                 /* set DIAB bit */
94                 UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
95
96                 /* set divisor */
97                 divisor = MAX_BAUD / baud;
98                 UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
99                 UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
100
101                 /* clear DIAB bit */
102                 UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
103         }
104
105         /* set data format */
106         UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
107 }
108
109
110 uint8 getDebugChar(void)
111 {
112         if (!remoteDebugInitialized) {
113                 remoteDebugInitialized = 1;
114                 debugInit(BAUD_DEFAULT,
115                           UART16550_DATA_8BIT,
116                           UART16550_PARITY_NONE, UART16550_STOP_1BIT);
117         }
118
119         while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
120         return UART16550_READ(OFS_RCV_BUFFER);
121 }
122
123
124 int putDebugChar(uint8 byte)
125 {
126         if (!remoteDebugInitialized) {
127                 remoteDebugInitialized = 1;
128                 debugInit(BAUD_DEFAULT,
129                           UART16550_DATA_8BIT,
130                           UART16550_PARITY_NONE, UART16550_STOP_1BIT);
131         }
132
133         while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
134         UART16550_WRITE(OFS_SEND_BUFFER, byte);
135         return 1;
136 }