1/* ASB2303-specific 8250 serial ports 2 * 3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public Licence 8 * as published by the Free Software Foundation; either version 9 * 2 of the Licence, or (at your option) any later version. 10 */ 11 12#ifndef _ASM_UNIT_SERIAL_H 13#define _ASM_UNIT_SERIAL_H 14 15#include <asm/cpu-regs.h> 16#include <proc/irq.h> 17#include <linux/serial_reg.h> 18 19#define SERIAL_PORT0_BASE_ADDRESS 0xA6FB0000 20#define SERIAL_PORT1_BASE_ADDRESS 0xA6FC0000 21 22#define SERIAL_IRQ XIRQ0 /* Dual serial (PC16552) (Hi) */ 23 24/* 25 * The ASB2303 has an 18.432 MHz clock the UART 26 */ 27#define BASE_BAUD (18432000 / 16) 28 29/* 30 * dispose of the /dev/ttyS0 and /dev/ttyS1 serial ports 31 */ 32#ifndef CONFIG_GDBSTUB_ON_TTYSx 33 34#define SERIAL_PORT_DFNS \ 35 { \ 36 .baud_base = BASE_BAUD, \ 37 .irq = SERIAL_IRQ, \ 38 .flags = STD_COM_FLAGS, \ 39 .iomem_base = (u8 *) SERIAL_PORT0_BASE_ADDRESS, \ 40 .iomem_reg_shift = 2, \ 41 .io_type = SERIAL_IO_MEM, \ 42 }, \ 43 { \ 44 .baud_base = BASE_BAUD, \ 45 .irq = SERIAL_IRQ, \ 46 .flags = STD_COM_FLAGS, \ 47 .iomem_base = (u8 *) SERIAL_PORT1_BASE_ADDRESS, \ 48 .iomem_reg_shift = 2, \ 49 .io_type = SERIAL_IO_MEM, \ 50 }, 51 52#ifndef __ASSEMBLY__ 53 54static inline void __debug_to_serial(const char *p, int n) 55{ 56} 57 58#endif /* !__ASSEMBLY__ */ 59 60#else /* CONFIG_GDBSTUB_ON_TTYSx */ 61 62#define SERIAL_PORT_DFNS /* both stolen by gdb-stub because they share an IRQ */ 63 64#if defined(CONFIG_GDBSTUB_ON_TTYS0) 65#define GDBPORT_SERIAL_RX __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_RX * 4, u8) 66#define GDBPORT_SERIAL_TX __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_TX * 4, u8) 67#define GDBPORT_SERIAL_DLL __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_DLL * 4, u8) 68#define GDBPORT_SERIAL_DLM __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_DLM * 4, u8) 69#define GDBPORT_SERIAL_IER __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_IER * 4, u8) 70#define GDBPORT_SERIAL_IIR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_IIR * 4, u8) 71#define GDBPORT_SERIAL_FCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_FCR * 4, u8) 72#define GDBPORT_SERIAL_LCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LCR * 4, u8) 73#define GDBPORT_SERIAL_MCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MCR * 4, u8) 74#define GDBPORT_SERIAL_LSR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LSR * 4, u8) 75#define GDBPORT_SERIAL_MSR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MSR * 4, u8) 76#define GDBPORT_SERIAL_SCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_SCR * 4, u8) 77#define GDBPORT_SERIAL_IRQ SERIAL_IRQ 78 79#elif defined(CONFIG_GDBSTUB_ON_TTYS1) 80#define GDBPORT_SERIAL_RX __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_RX * 4, u8) 81#define GDBPORT_SERIAL_TX __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_TX * 4, u8) 82#define GDBPORT_SERIAL_DLL __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_DLL * 4, u8) 83#define GDBPORT_SERIAL_DLM __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_DLM * 4, u8) 84#define GDBPORT_SERIAL_IER __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_IER * 4, u8) 85#define GDBPORT_SERIAL_IIR __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_IIR * 4, u8) 86#define GDBPORT_SERIAL_FCR __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_FCR * 4, u8) 87#define GDBPORT_SERIAL_LCR __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_LCR * 4, u8) 88#define GDBPORT_SERIAL_MCR __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_MCR * 4, u8) 89#define GDBPORT_SERIAL_LSR __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_LSR * 4, u8) 90#define GDBPORT_SERIAL_MSR __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_MSR * 4, u8) 91#define GDBPORT_SERIAL_SCR __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_SCR * 4, u8) 92#define GDBPORT_SERIAL_IRQ SERIAL_IRQ 93#endif 94 95#ifndef __ASSEMBLY__ 96 97#define LSR_WAIT_FOR(STATE) \ 98do { \ 99 while (!(GDBPORT_SERIAL_LSR & UART_LSR_##STATE)) {} \ 100} while (0) 101#define FLOWCTL_WAIT_FOR(LINE) \ 102do { \ 103 while (!(GDBPORT_SERIAL_MSR & UART_MSR_##LINE)) {} \ 104} while (0) 105#define FLOWCTL_CLEAR(LINE) \ 106do { \ 107 GDBPORT_SERIAL_MCR &= ~UART_MCR_##LINE; \ 108} while (0) 109#define FLOWCTL_SET(LINE) \ 110do { \ 111 GDBPORT_SERIAL_MCR |= UART_MCR_##LINE; \ 112} while (0) 113#define FLOWCTL_QUERY(LINE) ({ GDBPORT_SERIAL_MSR & UART_MSR_##LINE; }) 114 115static inline void __debug_to_serial(const char *p, int n) 116{ 117 char ch; 118 119 FLOWCTL_SET(DTR); 120 121 for (; n > 0; n--) { 122 LSR_WAIT_FOR(THRE); 123 FLOWCTL_WAIT_FOR(CTS); 124 125 ch = *p++; 126 if (ch == 0x0a) { 127 GDBPORT_SERIAL_TX = 0x0d; 128 LSR_WAIT_FOR(THRE); 129 FLOWCTL_WAIT_FOR(CTS); 130 } 131 GDBPORT_SERIAL_TX = ch; 132 } 133 134 FLOWCTL_CLEAR(DTR); 135} 136 137#endif /* !__ASSEMBLY__ */ 138 139#endif /* CONFIG_GDBSTUB_ON_TTYSx */ 140 141#endif /* _ASM_UNIT_SERIAL_H */ 142