1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *  * Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 *  * Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in
12 *    the documentation and/or other materials provided with the
13 *    distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29/* omap44x0 serial driver */
30
31#include <aboot/aboot.h>
32#include <aboot/io.h>
33#include <omap4/hw.h>
34
35#define OFF_RBR		0x00
36#define OFF_THR		0x00
37#define OFF_DLL		0x00
38#define OFF_IER		0x04
39#define OFF_DLM		0x04
40#define OFF_FCR		0x08
41#define OFF_IIR		0x08
42#define OFF_LCR		0x0C
43#define OFF_MCR		0x10
44#define OFF_LSR		0x14
45#define OFF_MSR		0x18
46#define OFF_SCR		0x1C
47#define OFF_MDR1	0x20
48
49#define WR(val, addr) writeb(val, cfg_uart_base + OFF_##addr)
50#define RD(addr) readb(cfg_uart_base + OFF_##addr)
51
52unsigned cfg_uart_base = CONFIG_SERIAL_BASE;
53
54void serial_init(void)
55{
56	unsigned divisor = CONFIG_SERIAL_CLK_HZ / 16 / CONFIG_BAUDRATE;
57
58	WR(0x00, IER);
59	WR(0x07, MDR1); /* reset */
60	WR(0x83, LCR);  /* 8N1 + banksel */
61	WR(divisor & 0xFF, DLL);
62	WR(divisor >> 8, DLM);
63	WR(0x03, LCR);  /* 8N1 */
64	WR(0x03, MCR);  /* DTR, RTS */
65	WR(0x07, FCR);  /* reset and enable FIFO */
66	WR(0x00, MDR1); /* run */
67}
68
69static inline void _serial_putc(char c)
70{
71	while (!(RD(LSR) & 0x20)) ;
72	WR(c, THR);
73}
74
75void serial_putc(char c)
76{
77	if (c == '\n')
78		_serial_putc('\r');
79	_serial_putc(c);
80}
81
82void serial_puts(const char *s)
83{
84	while (*s)
85		serial_putc(*s++);
86}
87
88