1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2002, 2003, 06, 07 Ralf Baechle (ralf@linux-mips.org)
* Copyright (C) 2007 MIPS Technologies, Inc.
* written by Ralf Baechle (ralf@linux-mips.org)
*/
#include <linux/console.h>
#include <linux/init.h>
#include <asm/setup.h>
#ifdef CONFIG_SERIAL_SC16IS7X0_CONSOLE
extern int __init early_sc16is7x0_init_i2c_and_check( void );
extern int __init early_sc16is7x0_setup(struct console * console, char * option);
static int early_sc16is7x0_workable = -1;
#endif
#include "bspchip.h"
//extern void prom_putchar(char);
int prom_putchar(char c)
{
#ifdef CONFIG_SERIAL_SC16IS7X0_CONSOLE
extern unsigned int sc16is7x0_serial_out_i2c(int offset, int value);
extern unsigned int sc16is7x0_serial_in_i2c(int offset);
#endif
#define UART0_BASE 0xB8002000
#define UART0_THR (UART0_BASE + 0x000)
#define UART0_FCR (UART0_BASE + 0x008)
#define UART0_LSR (UART0_BASE + 0x014)
#define TXRST 0x04
#define CHAR_TRIGGER_14 0xC0
#define LSR_THRE 0x20
#define TxCHAR_AVAIL 0x00
#define TxCHAR_EMPTY 0x20
unsigned int busy_cnt = 0;
#ifndef CONFIG_SERIAL_SC16IS7X0_CONSOLE
do
{
/* Prevent Hanging */
if (busy_cnt++ >= 30000)
{
/* Reset Tx FIFO */
REG8(UART0_FCR) = TXRST | CHAR_TRIGGER_14;
return 0;
}
} while ((REG8(UART0_LSR) & LSR_THRE) == TxCHAR_AVAIL);
/* Send Character */
REG8(UART0_THR) = c;
#endif
// -------------------------------------------------------
#ifdef CONFIG_SERIAL_SC16IS7X0_CONSOLE
if( early_sc16is7x0_workable < 0 )
return 0;
#define MEM2REG( x ) ( ( x - UART0_BASE ) / 4 )
do
{
/* Prevent Hanging */
if (busy_cnt++ >= 30000)
{
/* Reset Tx FIFO */
sc16is7x0_serial_out_i2c( MEM2REG(UART0_FCR), TXRST | CHAR_TRIGGER_14 );
return 0;
}
} while ((sc16is7x0_serial_in_i2c( MEM2REG(UART0_LSR) ) & LSR_THRE) == TxCHAR_AVAIL);
/* Send Character */
sc16is7x0_serial_out_i2c( MEM2REG(UART0_THR), c );
#undef MEM2REG
#endif
return 1;
}
static void __init
early_console_write(struct console *con, const char *s, unsigned n)
{
while (n-- && *s) {
if (*s == '\n')
prom_putchar('\r');
prom_putchar(*s);
s++;
}
}
static struct console early_console __initdata = {
.name = "early",
.write = early_console_write,
.flags = CON_PRINTBUFFER | CON_BOOT,
.index = -1
};
static int early_console_initialized __initdata;
void __init setup_early_printk(void)
{
if (early_console_initialized)
return;
early_console_initialized = 1;
#ifdef CONFIG_SERIAL_SC16IS7X0_CONSOLE
early_sc16is7x0_workable = early_sc16is7x0_setup( NULL, NULL );
#endif
register_console(&early_console);
}
|