~ubuntu-branches/ubuntu/maverick/u-boot-omap3/maverick

« back to all changes in this revision

Viewing changes to cpu/blackfin/serial.c

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2010-03-22 15:06:23 UTC
  • Revision ID: james.westby@ubuntu.com-20100322150623-i21g8rgiyl5dohag
Tags: upstream-2010.3git20100315
ImportĀ upstreamĀ versionĀ 2010.3git20100315

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * U-boot - serial.c Blackfin Serial Driver
 
3
 *
 
4
 * Copyright (c) 2005-2008 Analog Devices Inc.
 
5
 *
 
6
 * Copyright (c) 2003   Bas Vermeulen <bas@buyways.nl>,
 
7
 *                      BuyWays B.V. (www.buyways.nl)
 
8
 *
 
9
 * Based heavily on:
 
10
 * blkfinserial.c: Serial driver for BlackFin DSP internal USRTs.
 
11
 * Copyright(c) 2003    Metrowerks      <mwaddel@metrowerks.com>
 
12
 * Copyright(c) 2001    Tony Z. Kou     <tonyko@arcturusnetworks.com>
 
13
 * Copyright(c) 2001-2002 Arcturus Networks Inc. <www.arcturusnetworks.com>
 
14
 *
 
15
 * Based on code from 68328 version serial driver imlpementation which was:
 
16
 * Copyright (C) 1995       David S. Miller    <davem@caip.rutgers.edu>
 
17
 * Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
 
18
 * Copyright (C) 1998, 1999 D. Jeff Dionne     <jeff@uclinux.org>
 
19
 * Copyright (C) 1999       Vladimir Gurevich  <vgurevic@cisco.com>
 
20
 *
 
21
 * (C) Copyright 2000-2004
 
22
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
23
 *
 
24
 * Licensed under the GPL-2 or later.
 
25
 */
 
26
 
 
27
/* Anomaly notes:
 
28
 *  05000086 - we don't support autobaud
 
29
 *  05000099 - we only use DR bit, so losing others is not a problem
 
30
 *  05000100 - we don't use the UART_IIR register
 
31
 *  05000215 - we poll the uart (no dma/interrupts)
 
32
 *  05000225 - no workaround possible, but this shouldnt cause errors ...
 
33
 *  05000230 - we tweak the baud rate calculation slightly
 
34
 *  05000231 - we always use 1 stop bit
 
35
 *  05000309 - we always enable the uart before we modify it in anyway
 
36
 *  05000350 - we always enable the uart regardless of boot mode
 
37
 *  05000363 - we don't support break signals, so don't generate one
 
38
 */
 
39
 
 
40
#include <common.h>
 
41
#include <watchdog.h>
 
42
#include <asm/blackfin.h>
 
43
#include <asm/mach-common/bits/uart.h>
 
44
 
 
45
#ifdef CONFIG_UART_CONSOLE
 
46
 
 
47
#include "serial.h"
 
48
 
 
49
#ifdef CONFIG_DEBUG_SERIAL
 
50
uint16_t cached_lsr[256];
 
51
uint16_t cached_rbr[256];
 
52
size_t cache_count;
 
53
 
 
54
/* The LSR is read-to-clear on some parts, so we have to make sure status
 
55
 * bits aren't inadvertently lost when doing various tests.  This also
 
56
 * works around anomaly 05000099 at the same time by keeping a cumulative
 
57
 * tally of all the status bits.
 
58
 */
 
59
static uint16_t uart_lsr_save;
 
60
static uint16_t uart_lsr_read(void)
 
61
{
 
62
        uint16_t lsr = bfin_read16(&pUART->lsr);
 
63
        uart_lsr_save |= (lsr & (OE|PE|FE|BI));
 
64
        return lsr | uart_lsr_save;
 
65
}
 
66
/* Just do the clear for everyone since it can't hurt. */
 
67
static void uart_lsr_clear(void)
 
68
{
 
69
        uart_lsr_save = 0;
 
70
        bfin_write16(&pUART->lsr, bfin_read16(&pUART->lsr) | -1);
 
71
}
 
72
#else
 
73
/* When debugging is disabled, we only care about the DR bit, so if other
 
74
 * bits get set/cleared, we don't really care since we don't read them
 
75
 * anyways (and thus anomaly 05000099 is irrelevant).
 
76
 */
 
77
static uint16_t uart_lsr_read(void)
 
78
{
 
79
        return bfin_read16(&pUART->lsr);
 
80
}
 
81
static void uart_lsr_clear(void)
 
82
{
 
83
        bfin_write16(&pUART->lsr, bfin_read16(&pUART->lsr) | -1);
 
84
}
 
85
#endif
 
86
 
 
87
/* Symbol for our assembly to call. */
 
88
void serial_set_baud(uint32_t baud)
 
89
{
 
90
        serial_early_set_baud(baud);
 
91
}
 
92
 
 
93
/* Symbol for common u-boot code to call.
 
94
 * Setup the baudrate (brg: baudrate generator).
 
95
 */
 
96
void serial_setbrg(void)
 
97
{
 
98
        DECLARE_GLOBAL_DATA_PTR;
 
99
        serial_set_baud(gd->baudrate);
 
100
}
 
101
 
 
102
/* Symbol for our assembly to call. */
 
103
void serial_initialize(void)
 
104
{
 
105
        serial_early_init();
 
106
}
 
107
 
 
108
/* Symbol for common u-boot code to call. */
 
109
int serial_init(void)
 
110
{
 
111
        serial_initialize();
 
112
        serial_setbrg();
 
113
        uart_lsr_clear();
 
114
#ifdef CONFIG_DEBUG_SERIAL
 
115
        cache_count = 0;
 
116
        memset(cached_lsr, 0x00, sizeof(cached_lsr));
 
117
        memset(cached_rbr, 0x00, sizeof(cached_rbr));
 
118
#endif
 
119
        return 0;
 
120
}
 
121
 
 
122
void serial_putc(const char c)
 
123
{
 
124
        /* send a \r for compatibility */
 
125
        if (c == '\n')
 
126
                serial_putc('\r');
 
127
 
 
128
        WATCHDOG_RESET();
 
129
 
 
130
        /* wait for the hardware fifo to clear up */
 
131
        while (!(uart_lsr_read() & THRE))
 
132
                continue;
 
133
 
 
134
        /* queue the character for transmission */
 
135
        bfin_write16(&pUART->thr, c);
 
136
        SSYNC();
 
137
 
 
138
        WATCHDOG_RESET();
 
139
}
 
140
 
 
141
int serial_tstc(void)
 
142
{
 
143
        WATCHDOG_RESET();
 
144
        return (uart_lsr_read() & DR) ? 1 : 0;
 
145
}
 
146
 
 
147
int serial_getc(void)
 
148
{
 
149
        uint16_t uart_rbr_val;
 
150
 
 
151
        /* wait for data ! */
 
152
        while (!serial_tstc())
 
153
                continue;
 
154
 
 
155
        /* grab the new byte */
 
156
        uart_rbr_val = bfin_read16(&pUART->rbr);
 
157
 
 
158
#ifdef CONFIG_DEBUG_SERIAL
 
159
        /* grab & clear the LSR */
 
160
        uint16_t uart_lsr_val = uart_lsr_read();
 
161
 
 
162
        cached_lsr[cache_count] = uart_lsr_val;
 
163
        cached_rbr[cache_count] = uart_rbr_val;
 
164
        cache_count = (cache_count + 1) % ARRAY_SIZE(cached_lsr);
 
165
 
 
166
        if (uart_lsr_val & (OE|PE|FE|BI)) {
 
167
                uint16_t dll, dlh;
 
168
                printf("\n[SERIAL ERROR]\n");
 
169
                ACCESS_LATCH();
 
170
                dll = bfin_read16(&pUART->dll);
 
171
                dlh = bfin_read16(&pUART->dlh);
 
172
                ACCESS_PORT_IER();
 
173
                printf("\tDLL=0x%x DLH=0x%x\n", dll, dlh);
 
174
                do {
 
175
                        --cache_count;
 
176
                        printf("\t%3i: RBR=0x%02x LSR=0x%02x\n", cache_count,
 
177
                                cached_rbr[cache_count], cached_lsr[cache_count]);
 
178
                } while (cache_count > 0);
 
179
                return -1;
 
180
        }
 
181
#endif
 
182
        uart_lsr_clear();
 
183
 
 
184
        return uart_rbr_val;
 
185
}
 
186
 
 
187
void serial_puts(const char *s)
 
188
{
 
189
        while (*s)
 
190
                serial_putc(*s++);
 
191
}
 
192
 
 
193
#endif