1/* ASB2305-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#ifndef _ASM_UNIT_SERIAL_H 12#define _ASM_UNIT_SERIAL_H 13 14#include <asm/cpu-regs.h> 15#include <proc/irq.h> 16#include <linux/serial_reg.h> 17 18#define SERIAL_PORT0_BASE_ADDRESS 0xA6FB0000 19#define ASB2305_DEBUG_MCR __SYSREG(0xA6FB0000 + UART_MCR * 2, u8) 20 21#define SERIAL_IRQ XIRQ0 /* Dual serial (PC16552) (Hi) */ 22 23/* 24 * The ASB2305 has an 18.432 MHz clock the UART 25 */ 26#define BASE_BAUD (18432000 / 16) 27 28/* 29 * dispose of the /dev/ttyS0 serial port 30 */ 31#ifndef CONFIG_GDBSTUB_ON_TTYSx 32 33#define SERIAL_PORT_DFNS \ 34 { \ 35 .baud_base = BASE_BAUD, \ 36 .irq = SERIAL_IRQ, \ 37 .flags = STD_COM_FLAGS, \ 38 .iomem_base = (u8 *) SERIAL_PORT0_BASE_ADDRESS, \ 39 .iomem_reg_shift = 2, \ 40 .io_type = SERIAL_IO_MEM, \ 41 }, 42 43#ifndef __ASSEMBLY__ 44 45static inline void __debug_to_serial(const char *p, int n) 46{ 47} 48 49#endif /* !__ASSEMBLY__ */ 50 51#else /* CONFIG_GDBSTUB_ON_TTYSx */ 52 53#define SERIAL_PORT_DFNS /* stolen by gdb-stub */ 54 55#if defined(CONFIG_GDBSTUB_ON_TTYS0) 56#define GDBPORT_SERIAL_RX __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_RX * 4, u8) 57#define GDBPORT_SERIAL_TX __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_TX * 4, u8) 58#define GDBPORT_SERIAL_DLL __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_DLL * 4, u8) 59#define GDBPORT_SERIAL_DLM __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_DLM * 4, u8) 60#define GDBPORT_SERIAL_IER __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_IER * 4, u8) 61#define GDBPORT_SERIAL_IIR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_IIR * 4, u8) 62#define GDBPORT_SERIAL_FCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_FCR * 4, u8) 63#define GDBPORT_SERIAL_LCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LCR * 4, u8) 64#define GDBPORT_SERIAL_MCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MCR * 4, u8) 65#define GDBPORT_SERIAL_LSR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LSR * 4, u8) 66#define GDBPORT_SERIAL_MSR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MSR * 4, u8) 67#define GDBPORT_SERIAL_SCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_SCR * 4, u8) 68#define GDBPORT_SERIAL_IRQ SERIAL_IRQ 69 70#elif defined(CONFIG_GDBSTUB_ON_TTYS1) 71#error The ASB2305 doesnt have a /dev/ttyS1 72#endif 73 74#ifndef __ASSEMBLY__ 75 76#define TTYS0_TX __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_TX * 4, u8) 77#define TTYS0_MCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MCR * 4, u8) 78#define TTYS0_LSR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LSR * 4, u8) 79#define TTYS0_MSR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MSR * 4, u8) 80 81#define LSR_WAIT_FOR(STATE) \ 82do { \ 83 while (!(TTYS0_LSR & UART_LSR_##STATE)) {} \ 84} while (0) 85#define FLOWCTL_WAIT_FOR(LINE) \ 86do { \ 87 while (!(TTYS0_MSR & UART_MSR_##LINE)) {} \ 88} while (0) 89#define FLOWCTL_CLEAR(LINE) \ 90do { \ 91 TTYS0_MCR &= ~UART_MCR_##LINE; \ 92} while (0) 93#define FLOWCTL_SET(LINE) \ 94do { \ 95 TTYS0_MCR |= UART_MCR_##LINE; \ 96} while (0) 97#define FLOWCTL_QUERY(LINE) ({ TTYS0_MSR & UART_MSR_##LINE; }) 98 99static inline void __debug_to_serial(const char *p, int n) 100{ 101 char ch; 102 103 FLOWCTL_SET(DTR); 104 105 for (; n > 0; n--) { 106 LSR_WAIT_FOR(THRE); 107 FLOWCTL_WAIT_FOR(CTS); 108 109 ch = *p++; 110 if (ch == 0x0a) { 111 TTYS0_TX = 0x0d; 112 LSR_WAIT_FOR(THRE); 113 FLOWCTL_WAIT_FOR(CTS); 114 } 115 TTYS0_TX = ch; 116 } 117 118 FLOWCTL_CLEAR(DTR); 119} 120 121#endif /* !__ASSEMBLY__ */ 122 123#endif /* CONFIG_GDBSTUB_ON_TTYSx */ 124 125#endif /* _ASM_UNIT_SERIAL_H */ 126