~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/drivers/serial/serial_sh.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * SuperH SCIF device driver.
 
3
 * Copyright (C) 2013  Renesas Electronics Corporation
 
4
 * Copyright (C) 2007,2008,2010 Nobuhiro Iwamatsu
 
5
 * Copyright (C) 2002 - 2008  Paul Mundt
 
6
 *
 
7
 * SPDX-License-Identifier:     GPL-2.0+
 
8
 */
 
9
 
 
10
#include <common.h>
 
11
#include <asm/io.h>
 
12
#include <asm/processor.h>
 
13
#include "serial_sh.h"
 
14
#include <serial.h>
 
15
#include <linux/compiler.h>
 
16
 
 
17
#if defined(CONFIG_CONS_SCIF0)
 
18
# define SCIF_BASE      SCIF0_BASE
 
19
#elif defined(CONFIG_CONS_SCIF1)
 
20
# define SCIF_BASE      SCIF1_BASE
 
21
#elif defined(CONFIG_CONS_SCIF2)
 
22
# define SCIF_BASE      SCIF2_BASE
 
23
#elif defined(CONFIG_CONS_SCIF3)
 
24
# define SCIF_BASE      SCIF3_BASE
 
25
#elif defined(CONFIG_CONS_SCIF4)
 
26
# define SCIF_BASE      SCIF4_BASE
 
27
#elif defined(CONFIG_CONS_SCIF5)
 
28
# define SCIF_BASE      SCIF5_BASE
 
29
#elif defined(CONFIG_CONS_SCIF6)
 
30
# define SCIF_BASE      SCIF6_BASE
 
31
#elif defined(CONFIG_CONS_SCIF7)
 
32
# define SCIF_BASE      SCIF7_BASE
 
33
#else
 
34
# error "Default SCIF doesn't set....."
 
35
#endif
 
36
 
 
37
#if defined(CONFIG_SCIF_A)
 
38
        #define SCIF_BASE_PORT  PORT_SCIFA
 
39
#else
 
40
        #define SCIF_BASE_PORT  PORT_SCIF
 
41
#endif
 
42
 
 
43
static struct uart_port sh_sci = {
 
44
        .membase        = (unsigned char*)SCIF_BASE,
 
45
        .mapbase        = SCIF_BASE,
 
46
        .type           = SCIF_BASE_PORT,
 
47
};
 
48
 
 
49
static void sh_serial_setbrg(void)
 
50
{
 
51
        DECLARE_GLOBAL_DATA_PTR;
 
52
 
 
53
        sci_out(&sh_sci, SCBRR,
 
54
                SCBRR_VALUE(gd->baudrate, CONFIG_SH_SCIF_CLK_FREQ));
 
55
}
 
56
 
 
57
static int sh_serial_init(void)
 
58
{
 
59
        sci_out(&sh_sci, SCSCR , SCSCR_INIT(&sh_sci));
 
60
        sci_out(&sh_sci, SCSCR , SCSCR_INIT(&sh_sci));
 
61
        sci_out(&sh_sci, SCSMR, 0);
 
62
        sci_out(&sh_sci, SCSMR, 0);
 
63
        sci_out(&sh_sci, SCFCR, SCFCR_RFRST|SCFCR_TFRST);
 
64
        sci_in(&sh_sci, SCFCR);
 
65
        sci_out(&sh_sci, SCFCR, 0);
 
66
 
 
67
        serial_setbrg();
 
68
        return 0;
 
69
}
 
70
 
 
71
#if defined(CONFIG_CPU_SH7760) || \
 
72
        defined(CONFIG_CPU_SH7780) || \
 
73
        defined(CONFIG_CPU_SH7785) || \
 
74
        defined(CONFIG_CPU_SH7786)
 
75
static int scif_rxfill(struct uart_port *port)
 
76
{
 
77
        return sci_in(port, SCRFDR) & 0xff;
 
78
}
 
79
#elif defined(CONFIG_CPU_SH7763)
 
80
static int scif_rxfill(struct uart_port *port)
 
81
{
 
82
        if ((port->mapbase == 0xffe00000) ||
 
83
                (port->mapbase == 0xffe08000)) {
 
84
                /* SCIF0/1*/
 
85
                return sci_in(port, SCRFDR) & 0xff;
 
86
        } else {
 
87
                /* SCIF2 */
 
88
                return sci_in(port, SCFDR) & SCIF2_RFDC_MASK;
 
89
        }
 
90
}
 
91
#elif defined(CONFIG_ARCH_SH7372)
 
92
static int scif_rxfill(struct uart_port *port)
 
93
{
 
94
        if (port->type == PORT_SCIFA)
 
95
                return sci_in(port, SCFDR) & SCIF_RFDC_MASK;
 
96
        else
 
97
                return sci_in(port, SCRFDR);
 
98
}
 
99
#else
 
100
static int scif_rxfill(struct uart_port *port)
 
101
{
 
102
        return sci_in(port, SCFDR) & SCIF_RFDC_MASK;
 
103
}
 
104
#endif
 
105
 
 
106
static int serial_rx_fifo_level(void)
 
107
{
 
108
        return scif_rxfill(&sh_sci);
 
109
}
 
110
 
 
111
static void handle_error(void)
 
112
{
 
113
        sci_in(&sh_sci, SCxSR);
 
114
        sci_out(&sh_sci, SCxSR, SCxSR_ERROR_CLEAR(&sh_sci));
 
115
        sci_in(&sh_sci, SCLSR);
 
116
        sci_out(&sh_sci, SCLSR, 0x00);
 
117
}
 
118
 
 
119
void serial_raw_putc(const char c)
 
120
{
 
121
        while (1) {
 
122
                /* Tx fifo is empty */
 
123
                if (sci_in(&sh_sci, SCxSR) & SCxSR_TEND(&sh_sci))
 
124
                        break;
 
125
        }
 
126
 
 
127
        sci_out(&sh_sci, SCxTDR, c);
 
128
        sci_out(&sh_sci, SCxSR, sci_in(&sh_sci, SCxSR) & ~SCxSR_TEND(&sh_sci));
 
129
}
 
130
 
 
131
static void sh_serial_putc(const char c)
 
132
{
 
133
        if (c == '\n')
 
134
                serial_raw_putc('\r');
 
135
        serial_raw_putc(c);
 
136
}
 
137
 
 
138
static int sh_serial_tstc(void)
 
139
{
 
140
        if (sci_in(&sh_sci, SCxSR) & SCIF_ERRORS) {
 
141
                handle_error();
 
142
                return 0;
 
143
        }
 
144
 
 
145
        return serial_rx_fifo_level() ? 1 : 0;
 
146
}
 
147
 
 
148
 
 
149
int serial_getc_check(void)
 
150
{
 
151
        unsigned short status;
 
152
 
 
153
        status = sci_in(&sh_sci, SCxSR);
 
154
 
 
155
        if (status & SCIF_ERRORS)
 
156
                handle_error();
 
157
        if (sci_in(&sh_sci, SCLSR) & SCxSR_ORER(&sh_sci))
 
158
                handle_error();
 
159
        return status & (SCIF_DR | SCxSR_RDxF(&sh_sci));
 
160
}
 
161
 
 
162
static int sh_serial_getc(void)
 
163
{
 
164
        unsigned short status;
 
165
        char ch;
 
166
 
 
167
        while (!serial_getc_check())
 
168
                ;
 
169
 
 
170
        ch = sci_in(&sh_sci, SCxRDR);
 
171
        status = sci_in(&sh_sci, SCxSR);
 
172
 
 
173
        sci_out(&sh_sci, SCxSR, SCxSR_RDxF_CLEAR(&sh_sci));
 
174
 
 
175
        if (status & SCIF_ERRORS)
 
176
                        handle_error();
 
177
 
 
178
        if (sci_in(&sh_sci, SCLSR) & SCxSR_ORER(&sh_sci))
 
179
                handle_error();
 
180
        return ch;
 
181
}
 
182
 
 
183
static struct serial_device sh_serial_drv = {
 
184
        .name   = "sh_serial",
 
185
        .start  = sh_serial_init,
 
186
        .stop   = NULL,
 
187
        .setbrg = sh_serial_setbrg,
 
188
        .putc   = sh_serial_putc,
 
189
        .puts   = default_serial_puts,
 
190
        .getc   = sh_serial_getc,
 
191
        .tstc   = sh_serial_tstc,
 
192
};
 
193
 
 
194
void sh_serial_initialize(void)
 
195
{
 
196
        serial_register(&sh_serial_drv);
 
197
}
 
198
 
 
199
__weak struct serial_device *default_serial_console(void)
 
200
{
 
201
        return &sh_serial_drv;
 
202
}