1/* Unit-specific 8250 serial ports 2 * 3 * Copyright (C) 2005 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 License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, 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 <unit/fpga-regs.h> 18#include <linux/serial_reg.h> 19 20#define SERIAL_PORT0_BASE_ADDRESS 0xA8200000 21 22#define SERIAL_IRQ XIRQ1 /* single serial (TL16C550C) (Lo) */ 23 24/* 25 * The ASB2364 has an 12.288 MHz clock 26 * for your UART. 27 * 28 * It'd be nice if someone built a serial card with a 24.576 MHz 29 * clock, since the 16550A is capable of handling a top speed of 1.5 30 * megabits/second; but this requires the faster clock. 31 */ 32#define BASE_BAUD (12288000 / 16) 33 34/* 35 * dispose of the /dev/ttyS0 and /dev/ttyS1 serial ports 36 */ 37#ifndef CONFIG_GDBSTUB_ON_TTYSx 38 39#define SERIAL_PORT_DFNS \ 40 { \ 41 .baud_base = BASE_BAUD, \ 42 .irq = SERIAL_IRQ, \ 43 .flags = STD_COM_FLAGS, \ 44 .iomem_base = (u8 *) SERIAL_PORT0_BASE_ADDRESS, \ 45 .iomem_reg_shift = 1, \ 46 .io_type = SERIAL_IO_MEM, \ 47 }, 48 49#ifndef __ASSEMBLY__ 50 51static inline void __debug_to_serial(const char *p, int n) 52{ 53} 54 55#endif /* !__ASSEMBLY__ */ 56 57#else /* CONFIG_GDBSTUB_ON_TTYSx */ 58 59#define SERIAL_PORT_DFNS /* stolen by gdb-stub */ 60 61#if defined(CONFIG_GDBSTUB_ON_TTYS0) 62#define GDBPORT_SERIAL_RX __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_RX * 2, u8) 63#define GDBPORT_SERIAL_TX __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_TX * 2, u8) 64#define GDBPORT_SERIAL_DLL __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_DLL * 2, u8) 65#define GDBPORT_SERIAL_DLM __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_DLM * 2, u8) 66#define GDBPORT_SERIAL_IER __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_IER * 2, u8) 67#define GDBPORT_SERIAL_IIR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_IIR * 2, u8) 68#define GDBPORT_SERIAL_FCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_FCR * 2, u8) 69#define GDBPORT_SERIAL_LCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LCR * 2, u8) 70#define GDBPORT_SERIAL_MCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MCR * 2, u8) 71#define GDBPORT_SERIAL_LSR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LSR * 2, u8) 72#define GDBPORT_SERIAL_MSR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MSR * 2, u8) 73#define GDBPORT_SERIAL_SCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_SCR * 2, u8) 74#define GDBPORT_SERIAL_IRQ SERIAL_IRQ 75 76#elif defined(CONFIG_GDBSTUB_ON_TTYS1) 77#error The ASB2364 does not have a /dev/ttyS1 78#endif 79 80#ifndef __ASSEMBLY__ 81 82static inline void __debug_to_serial(const char *p, int n) 83{ 84 char ch; 85 86#define LSR_WAIT_FOR(STATE) \ 87 do {} while (!(GDBPORT_SERIAL_LSR & UART_LSR_##STATE)) 88#define FLOWCTL_QUERY(LINE) \ 89 ({ GDBPORT_SERIAL_MSR & UART_MSR_##LINE; }) 90#define FLOWCTL_WAIT_FOR(LINE) \ 91 do {} while (!(GDBPORT_SERIAL_MSR & UART_MSR_##LINE)) 92#define FLOWCTL_CLEAR(LINE) \ 93 do { GDBPORT_SERIAL_MCR &= ~UART_MCR_##LINE; } while (0) 94#define FLOWCTL_SET(LINE) \ 95 do { GDBPORT_SERIAL_MCR |= UART_MCR_##LINE; } while (0) 96 97 FLOWCTL_SET(DTR); 98 99 for (; n > 0; n--) { 100 LSR_WAIT_FOR(THRE); 101 FLOWCTL_WAIT_FOR(CTS); 102 103 ch = *p++; 104 if (ch == 0x0a) { 105 GDBPORT_SERIAL_TX = 0x0d; 106 LSR_WAIT_FOR(THRE); 107 FLOWCTL_WAIT_FOR(CTS); 108 } 109 GDBPORT_SERIAL_TX = ch; 110 } 111 112 FLOWCTL_CLEAR(DTR); 113} 114 115#endif /* !__ASSEMBLY__ */ 116 117#endif /* CONFIG_GDBSTUB_ON_TTYSx */ 118 119#define SERIAL_INITIALIZE \ 120do { \ 121 /* release reset */ \ 122 ASB2364_FPGA_REG_RESET_UART = 0x0001; \ 123 SyncExBus(); \ 124} while (0) 125 126#define SERIAL_CHECK_INTERRUPT \ 127do { \ 128 if ((ASB2364_FPGA_REG_IRQ_UART & 0x0001) == 0x0001) { \ 129 return IRQ_NONE; \ 130 } \ 131} while (0) 132 133#define SERIAL_CLEAR_INTERRUPT \ 134do { \ 135 ASB2364_FPGA_REG_IRQ_UART = 0x0001; \ 136 SyncExBus(); \ 137} while (0) 138 139#define SERIAL_SET_INT_MASK \ 140do { \ 141 ASB2364_FPGA_REG_MASK_UART = 0x0001; \ 142 SyncExBus(); \ 143} while (0) 144 145#define SERIAL_CLEAR_INT_MASK \ 146do { \ 147 ASB2364_FPGA_REG_MASK_UART = 0x0000; \ 148 SyncExBus(); \ 149} while (0) 150 151#endif /* _ASM_UNIT_SERIAL_H */ 152