aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/arch/mips/pmc-sierra/yosemite/dbg_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/pmc-sierra/yosemite/dbg_io.c')
-rw-r--r--arch/mips/pmc-sierra/yosemite/dbg_io.c180
1 files changed, 180 insertions, 0 deletions
diff --git a/arch/mips/pmc-sierra/yosemite/dbg_io.c b/arch/mips/pmc-sierra/yosemite/dbg_io.c
new file mode 100644
index 000000000000..0f659c9106ac
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/dbg_io.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Support for KGDB for the Yosemite board. We make use of single serial
+ * port to be used for KGDB as well as console. The second serial port
+ * seems to be having a problem. Single IRQ is allocated for both the
+ * ports. Hence, the interrupt routing code needs to figure out whether
+ * the interrupt came from channel A or B.
+ */
+
+#include <asm/serial.h>
+
+/*
+ * Baud rate, Parity, Data and Stop bit settings for the
+ * serial port on the Yosemite. Note that the Early printk
+ * patch has been added. So, we should be all set to go
+ */
+#define YOSEMITE_BAUD_2400 2400
+#define YOSEMITE_BAUD_4800 4800
+#define YOSEMITE_BAUD_9600 9600
+#define YOSEMITE_BAUD_19200 19200
+#define YOSEMITE_BAUD_38400 38400
+#define YOSEMITE_BAUD_57600 57600
+#define YOSEMITE_BAUD_115200 115200
+
+#define YOSEMITE_PARITY_NONE 0
+#define YOSEMITE_PARITY_ODD 0x08
+#define YOSEMITE_PARITY_EVEN 0x18
+#define YOSEMITE_PARITY_MARK 0x28
+#define YOSEMITE_PARITY_SPACE 0x38
+
+#define YOSEMITE_DATA_5BIT 0x0
+#define YOSEMITE_DATA_6BIT 0x1
+#define YOSEMITE_DATA_7BIT 0x2
+#define YOSEMITE_DATA_8BIT 0x3
+
+#define YOSEMITE_STOP_1BIT 0x0
+#define YOSEMITE_STOP_2BIT 0x4
+
+/* This is crucial */
+#define SERIAL_REG_OFS 0x1
+
+#define SERIAL_RCV_BUFFER 0x0
+#define SERIAL_TRANS_HOLD 0x0
+#define SERIAL_SEND_BUFFER 0x0
+#define SERIAL_INTR_ENABLE (1 * SERIAL_REG_OFS)
+#define SERIAL_INTR_ID (2 * SERIAL_REG_OFS)
+#define SERIAL_DATA_FORMAT (3 * SERIAL_REG_OFS)
+#define SERIAL_LINE_CONTROL (3 * SERIAL_REG_OFS)
+#define SERIAL_MODEM_CONTROL (4 * SERIAL_REG_OFS)
+#define SERIAL_RS232_OUTPUT (4 * SERIAL_REG_OFS)
+#define SERIAL_LINE_STATUS (5 * SERIAL_REG_OFS)
+#define SERIAL_MODEM_STATUS (6 * SERIAL_REG_OFS)
+#define SERIAL_RS232_INPUT (6 * SERIAL_REG_OFS)
+#define SERIAL_SCRATCH_PAD (7 * SERIAL_REG_OFS)
+
+#define SERIAL_DIVISOR_LSB (0 * SERIAL_REG_OFS)
+#define SERIAL_DIVISOR_MSB (1 * SERIAL_REG_OFS)
+
+/*
+ * Functions to READ and WRITE to serial port 0
+ */
+#define SERIAL_READ(ofs) (*((volatile unsigned char*) \
+ (TITAN_SERIAL_BASE + ofs)))
+
+#define SERIAL_WRITE(ofs, val) ((*((volatile unsigned char*) \
+ (TITAN_SERIAL_BASE + ofs))) = val)
+
+/*
+ * Functions to READ and WRITE to serial port 1
+ */
+#define SERIAL_READ_1(ofs) (*((volatile unsigned char*) \
+ (TITAN_SERIAL_BASE_1 + ofs)
+
+#define SERIAL_WRITE_1(ofs, val) ((*((volatile unsigned char*) \
+ (TITAN_SERIAL_BASE_1 + ofs))) = val)
+
+/*
+ * Second serial port initialization
+ */
+void init_second_port(void)
+{
+ /* Disable Interrupts */
+ SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x0);
+ SERIAL_WRITE_1(SERIAL_INTR_ENABLE, 0x0);
+
+ {
+ unsigned int divisor;
+
+ SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x80);
+ divisor = TITAN_SERIAL_BASE_BAUD / YOSEMITE_BAUD_115200;
+ SERIAL_WRITE_1(SERIAL_DIVISOR_LSB, divisor & 0xff);
+
+ SERIAL_WRITE_1(SERIAL_DIVISOR_MSB,
+ (divisor & 0xff00) >> 8);
+ SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x0);
+ }
+
+ SERIAL_WRITE_1(SERIAL_DATA_FORMAT, YOSEMITE_DATA_8BIT |
+ YOSEMITE_PARITY_NONE | YOSEMITE_STOP_1BIT);
+
+ /* Enable Interrupts */
+ SERIAL_WRITE_1(SERIAL_INTR_ENABLE, 0xf);
+}
+
+/* Initialize the serial port for KGDB debugging */
+void debugInit(unsigned int baud, unsigned char data, unsigned char parity,
+ unsigned char stop)
+{
+ /* Disable Interrupts */
+ SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x0);
+ SERIAL_WRITE(SERIAL_INTR_ENABLE, 0x0);
+
+ {
+ unsigned int divisor;
+
+ SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x80);
+
+ divisor = TITAN_SERIAL_BASE_BAUD / baud;
+ SERIAL_WRITE(SERIAL_DIVISOR_LSB, divisor & 0xff);
+
+ SERIAL_WRITE(SERIAL_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+ SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x0);
+ }
+
+ SERIAL_WRITE(SERIAL_DATA_FORMAT, data | parity | stop);
+}
+
+static int remoteDebugInitialized = 0;
+
+unsigned char getDebugChar(void)
+{
+ if (!remoteDebugInitialized) {
+ remoteDebugInitialized = 1;
+ debugInit(YOSEMITE_BAUD_115200,
+ YOSEMITE_DATA_8BIT,
+ YOSEMITE_PARITY_NONE, YOSEMITE_STOP_1BIT);
+ }
+
+ while ((SERIAL_READ(SERIAL_LINE_STATUS) & 0x1) == 0);
+ return SERIAL_READ(SERIAL_RCV_BUFFER);
+}
+
+int putDebugChar(unsigned char byte)
+{
+ if (!remoteDebugInitialized) {
+ remoteDebugInitialized = 1;
+ debugInit(YOSEMITE_BAUD_115200,
+ YOSEMITE_DATA_8BIT,
+ YOSEMITE_PARITY_NONE, YOSEMITE_STOP_1BIT);
+ }
+
+ while ((SERIAL_READ(SERIAL_LINE_STATUS) & 0x20) == 0);
+ SERIAL_WRITE(SERIAL_SEND_BUFFER, byte);
+
+ return 1;
+}