Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/arm/freescale/imx/imx_console.c
39536 views
1
/*-
2
* Copyright (c) 2012, 2013 The FreeBSD Foundation
3
*
4
* This software was developed by Oleksandr Rybalko under sponsorship
5
* from the FreeBSD Foundation.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
* SUCH DAMAGE.
27
*/
28
29
/* Simple UART console driver for Freescale i.MX515 */
30
31
#include <sys/types.h>
32
#include <sys/param.h>
33
#include <sys/systm.h>
34
#include <sys/cons.h>
35
#include <sys/consio.h>
36
#include <sys/kernel.h>
37
38
/* Allow it to be predefined, to be able to use another UART for console */
39
#ifndef IMX_UART_BASE
40
#define IMX_UART_BASE 0xe3fbc000 /* imx51 UART1 */
41
#endif
42
43
#define IMX_RXD 0x00
44
#define IMX_TXD 0x40
45
46
#define IMX_UFCR 0x90
47
#define IMX_USR1 0x94
48
#define IMX_USR1_TRDY (1 << 13)
49
50
#define IMX_USR2 0x98
51
#define IMX_USR2_RDR (1 << 0)
52
#define IMX_USR2_TXFE (1 << 14)
53
#define IMX_USR2_TXDC (1 << 3)
54
55
#define IMX_UTS 0xb4
56
#define IMX_UTS_TXFULL (1 << 4)
57
58
/*
59
* The base address of the uart registers.
60
*
61
* This is global so that it can be changed on the fly from the outside. For
62
* example, set imx_uart_base=physaddr and then call cninit() as the first two
63
* lines of initarm() and enjoy printf() availability through the tricky bits of
64
* startup. After initarm() switches from physical to virtual addressing, just
65
* set imx_uart_base=virtaddr and printf keeps working.
66
*/
67
uint32_t imx_uart_base = IMX_UART_BASE;
68
69
/*
70
* uart related funcs
71
*/
72
static uint32_t
73
ub_getreg(uint32_t off)
74
{
75
76
return *((volatile uint32_t *)(imx_uart_base + off));
77
}
78
79
static void
80
ub_setreg(uint32_t off, uint32_t val)
81
{
82
83
*((volatile uint32_t *)(imx_uart_base + off)) = val;
84
}
85
86
static int
87
ub_tstc(void)
88
{
89
90
return ((ub_getreg(IMX_USR2) & IMX_USR2_RDR) ? 1 : 0);
91
}
92
93
static int
94
ub_getc(void)
95
{
96
97
while (!ub_tstc());
98
__asm __volatile("nop");
99
100
return (ub_getreg(IMX_RXD) & 0xff);
101
}
102
103
static void
104
ub_putc(unsigned char c)
105
{
106
107
if (c == '\n')
108
ub_putc('\r');
109
110
while (ub_getreg(IMX_UTS) & IMX_UTS_TXFULL)
111
__asm __volatile("nop");
112
113
ub_setreg(IMX_TXD, c);
114
}
115
116
static cn_probe_t uart_cnprobe;
117
static cn_init_t uart_cninit;
118
static cn_term_t uart_cnterm;
119
static cn_getc_t uart_cngetc;
120
static cn_putc_t uart_cnputc;
121
static cn_grab_t uart_cngrab;
122
static cn_ungrab_t uart_cnungrab;
123
124
static void
125
uart_cngrab(struct consdev *cp)
126
{
127
128
}
129
130
static void
131
uart_cnungrab(struct consdev *cp)
132
{
133
134
}
135
136
static void
137
uart_cnprobe(struct consdev *cp)
138
{
139
140
sprintf(cp->cn_name, "uart");
141
cp->cn_pri = CN_NORMAL;
142
}
143
144
static void
145
uart_cninit(struct consdev *cp)
146
{
147
148
/* Init fifo trigger levels to 32 bytes, refclock div to 2. */
149
ub_setreg(IMX_UFCR, 0x00004210);
150
}
151
152
static void
153
uart_cnputc(struct consdev *cp, int c)
154
{
155
156
ub_putc(c);
157
}
158
159
static int
160
uart_cngetc(struct consdev * cp)
161
{
162
163
return ub_getc();
164
}
165
166
static void
167
uart_cnterm(struct consdev * cp)
168
{
169
170
}
171
172
CONSOLE_DRIVER(uart);
173
174