1248557Sray/*-
2250357Sray * Copyright (c) 2012, 2013 The FreeBSD Foundation
3248557Sray * All rights reserved.
4248557Sray *
5248557Sray * This software was developed by Oleksandr Rybalko under sponsorship
6248557Sray * from the FreeBSD Foundation.
7248557Sray *
8248557Sray * Redistribution and use in source and binary forms, with or without
9248557Sray * modification, are permitted provided that the following conditions
10248557Sray * are met:
11248557Sray * 1.	Redistributions of source code must retain the above copyright
12248557Sray *	notice, this list of conditions and the following disclaimer.
13248557Sray * 2.	Redistributions in binary form must reproduce the above copyright
14248557Sray *	notice, this list of conditions and the following disclaimer in the
15248557Sray *	documentation and/or other materials provided with the distribution.
16248557Sray *
17248557Sray * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18248557Sray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19248557Sray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20248557Sray * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21248557Sray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22248557Sray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23248557Sray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24248557Sray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25248557Sray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26248557Sray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27248557Sray * SUCH DAMAGE.
28248557Sray */
29248557Sray
30248557Sray/* Simple UART console driver for Freescale i.MX515 */
31248557Sray
32248557Sray#include <sys/cdefs.h>
33248557Sray__FBSDID("$FreeBSD: releng/10.3/sys/arm/freescale/imx/console.c 253914 2013-08-03 13:31:10Z ian $");
34248557Sray
35248557Sray#include <sys/types.h>
36248557Sray#include <sys/param.h>
37248557Sray#include <sys/systm.h>
38248557Sray#include <sys/cons.h>
39248557Sray#include <sys/consio.h>
40248557Sray#include <sys/kernel.h>
41248557Sray
42248557Sray/* Allow it to be predefined, to be able to use another UART for console */
43248557Sray#ifndef	IMX_UART_BASE
44253914Sian#define	IMX_UART_BASE	0xe3fbc000 /* imx51 UART1 */
45248557Sray#endif
46248557Sray
47253914Sian#define	IMX_RXD			0x00
48253914Sian#define	IMX_TXD			0x40
49248557Sray
50253914Sian#define	IMX_UFCR		0x90
51253914Sian#define	IMX_USR1		0x94
52248557Sray#define	IMX_USR1_TRDY		(1 << 13)
53248557Sray
54253914Sian#define	IMX_USR2		0x98
55248557Sray#define	IMX_USR2_RDR		(1 << 0)
56248557Sray#define	IMX_USR2_TXFE		(1 << 14)
57248557Sray#define	IMX_USR2_TXDC		(1 << 3)
58248557Sray
59253914Sian#define	IMX_UTS			0xb4
60248557Sray#define	IMX_UTS_TXFULL		(1 << 4)
61248557Sray
62248557Sray/*
63253914Sian * The base address of the uart registers.
64253914Sian *
65253914Sian * This is global so that it can be changed on the fly from the outside.  For
66253914Sian * example, set imx_uart_base=physaddr and then call cninit() as the first two
67253914Sian * lines of initarm() and enjoy printf() availability through the tricky bits of
68253914Sian * startup.  After initarm() switches from physical to virtual addressing, just
69253914Sian * set imx_uart_base=virtaddr and printf keeps working.
70253914Sian */
71253914Sianuint32_t imx_uart_base = IMX_UART_BASE;
72253914Sian
73253914Sian/*
74248557Sray * uart related funcs
75248557Sray */
76253914Sianstatic uint32_t
77253914Sianub_getreg(uint32_t off)
78248557Sray{
79248557Sray
80253914Sian	return *((volatile uint32_t *)(imx_uart_base + off));
81248557Sray}
82248557Sray
83248557Sraystatic void
84253914Sianub_setreg(uint32_t off, uint32_t val)
85248557Sray{
86248557Sray
87253914Sian	*((volatile uint32_t *)(imx_uart_base + off)) = val;
88248557Sray}
89248557Sray
90248557Sraystatic int
91248557Srayub_tstc(void)
92248557Sray{
93248557Sray
94253914Sian	return ((ub_getreg(IMX_USR2) & IMX_USR2_RDR) ? 1 : 0);
95248557Sray}
96248557Sray
97248557Sraystatic int
98248557Srayub_getc(void)
99248557Sray{
100248557Sray
101248557Sray	while (!ub_tstc());
102248557Sray		__asm __volatile("nop");
103248557Sray
104253914Sian	return (ub_getreg(IMX_RXD) & 0xff);
105248557Sray}
106248557Sray
107248557Sraystatic void
108248557Srayub_putc(unsigned char c)
109248557Sray{
110248557Sray
111248557Sray	if (c == '\n')
112248557Sray		ub_putc('\r');
113248557Sray
114253914Sian	while (ub_getreg(IMX_UTS) & IMX_UTS_TXFULL)
115248557Sray		__asm __volatile("nop");
116248557Sray
117253914Sian	ub_setreg(IMX_TXD, c);
118248557Sray}
119248557Sray
120248557Sraystatic cn_probe_t	uart_cnprobe;
121248557Sraystatic cn_init_t	uart_cninit;
122248557Sraystatic cn_term_t	uart_cnterm;
123248557Sraystatic cn_getc_t	uart_cngetc;
124248557Sraystatic cn_putc_t	uart_cnputc;
125248557Sraystatic cn_grab_t	uart_cngrab;
126248557Sraystatic cn_ungrab_t	uart_cnungrab;
127248557Sray
128248557Sraystatic void
129248557Srayuart_cngrab(struct consdev *cp)
130248557Sray{
131248557Sray
132248557Sray}
133248557Sray
134248557Sraystatic void
135248557Srayuart_cnungrab(struct consdev *cp)
136248557Sray{
137248557Sray
138248557Sray}
139248557Sray
140248557Sray
141248557Sraystatic void
142248557Srayuart_cnprobe(struct consdev *cp)
143248557Sray{
144248557Sray
145248557Sray        sprintf(cp->cn_name, "uart");
146248557Sray        cp->cn_pri = CN_NORMAL;
147248557Sray}
148248557Sray
149248557Sraystatic void
150248557Srayuart_cninit(struct consdev *cp)
151248557Sray{
152253914Sian
153253914Sian        /* Init fifo trigger levels to 32 bytes, refclock div to 2. */
154253914Sian	ub_setreg(IMX_UFCR, 0x00004210);
155248557Sray}
156248557Sray
157253914Sianstatic void
158248557Srayuart_cnputc(struct consdev *cp, int c)
159248557Sray{
160248557Sray
161248557Sray	ub_putc(c);
162248557Sray}
163248557Sray
164253914Sianstatic int
165248557Srayuart_cngetc(struct consdev * cp)
166248557Sray{
167248557Sray
168248557Sray	return ub_getc();
169248557Sray}
170248557Sray
171248557Sraystatic void
172248557Srayuart_cnterm(struct consdev * cp)
173248557Sray{
174248557Sray
175248557Sray}
176248557Sray
177248557SrayCONSOLE_DRIVER(uart);
178