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 */
27static 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
36typedef unsigned char uint8;
37typedef 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
84void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
85{
86        /* disable interrupts */
87        UART16550_WRITE(OFS_INTR_ENABLE, 0);
88
89        /* set up buad 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
110uint8 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
124int 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}
137