sscom.c revision 1.3.4.4 1 1.3.4.4 skrll /* $NetBSD: sscom.c,v 1.3.4.4 2004/09/21 13:14:53 skrll Exp $ */
2 1.3.4.2 skrll
3 1.3.4.2 skrll
4 1.3.4.2 skrll /*
5 1.3.4.2 skrll * Copyright (c) 2002, 2003 Fujitsu Component Limited
6 1.3.4.2 skrll * Copyright (c) 2002, 2003 Genetec Corporation
7 1.3.4.2 skrll * All rights reserved.
8 1.3.4.2 skrll *
9 1.3.4.2 skrll * Redistribution and use in source and binary forms, with or without
10 1.3.4.2 skrll * modification, are permitted provided that the following conditions
11 1.3.4.2 skrll * are met:
12 1.3.4.2 skrll * 1. Redistributions of source code must retain the above copyright
13 1.3.4.2 skrll * notice, this list of conditions and the following disclaimer.
14 1.3.4.2 skrll * 2. Redistributions in binary form must reproduce the above copyright
15 1.3.4.2 skrll * notice, this list of conditions and the following disclaimer in the
16 1.3.4.2 skrll * documentation and/or other materials provided with the distribution.
17 1.3.4.2 skrll * 3. Neither the name of The Fujitsu Component Limited nor the name of
18 1.3.4.2 skrll * Genetec corporation may not be used to endorse or promote products
19 1.3.4.2 skrll * derived from this software without specific prior written permission.
20 1.3.4.2 skrll *
21 1.3.4.2 skrll * THIS SOFTWARE IS PROVIDED BY FUJITSU COMPONENT LIMITED AND GENETEC
22 1.3.4.2 skrll * CORPORATION ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
23 1.3.4.2 skrll * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 1.3.4.2 skrll * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 1.3.4.2 skrll * DISCLAIMED. IN NO EVENT SHALL FUJITSU COMPONENT LIMITED OR GENETEC
26 1.3.4.2 skrll * CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 1.3.4.2 skrll * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 1.3.4.2 skrll * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
29 1.3.4.2 skrll * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 1.3.4.2 skrll * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31 1.3.4.2 skrll * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 1.3.4.2 skrll * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 1.3.4.2 skrll * SUCH DAMAGE.
34 1.3.4.2 skrll */
35 1.3.4.2 skrll /* derived from ns16550.c */
36 1.3.4.2 skrll /*
37 1.3.4.2 skrll * Copyright (c) 2002 Wasabi Systems, Inc.
38 1.3.4.2 skrll * All rights reserved.
39 1.3.4.2 skrll *
40 1.3.4.2 skrll * Written by Jason R. Thorpe for Wasabi Systems, Inc.
41 1.3.4.2 skrll *
42 1.3.4.2 skrll * Redistribution and use in source and binary forms, with or without
43 1.3.4.2 skrll * modification, are permitted provided that the following conditions
44 1.3.4.2 skrll * are met:
45 1.3.4.2 skrll * 1. Redistributions of source code must retain the above copyright
46 1.3.4.2 skrll * notice, this list of conditions and the following disclaimer.
47 1.3.4.2 skrll * 2. Redistributions in binary form must reproduce the above copyright
48 1.3.4.2 skrll * notice, this list of conditions and the following disclaimer in the
49 1.3.4.2 skrll * documentation and/or other materials provided with the distribution.
50 1.3.4.2 skrll * 3. All advertising materials mentioning features or use of this software
51 1.3.4.2 skrll * must display the following acknowledgement:
52 1.3.4.2 skrll * This product includes software developed for the NetBSD Project by
53 1.3.4.2 skrll * Wasabi Systems, Inc.
54 1.3.4.2 skrll * 4. The name of Wasabi Systems, Inc. may not be used to endorse
55 1.3.4.2 skrll * or promote products derived from this software without specific prior
56 1.3.4.2 skrll * written permission.
57 1.3.4.2 skrll *
58 1.3.4.2 skrll * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
59 1.3.4.2 skrll * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
60 1.3.4.2 skrll * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
61 1.3.4.2 skrll * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
62 1.3.4.2 skrll * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
63 1.3.4.2 skrll * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
64 1.3.4.2 skrll * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
65 1.3.4.2 skrll * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
66 1.3.4.2 skrll * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
67 1.3.4.2 skrll * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
68 1.3.4.2 skrll * POSSIBILITY OF SUCH DAMAGE.
69 1.3.4.2 skrll */
70 1.3.4.2 skrll /*
71 1.3.4.2 skrll * This file provides the cons_init() function and console I/O routines
72 1.3.4.2 skrll * for boards that use built-in UART of Samsung's S3C2xx0 CPUs.
73 1.3.4.2 skrll */
74 1.3.4.2 skrll
75 1.3.4.2 skrll #include <sys/types.h>
76 1.3.4.2 skrll #include <arch/arm/s3c2xx0/s3c2xx0reg.h>
77 1.3.4.2 skrll #ifdef CPU_S3C2410
78 1.3.4.2 skrll #include <arch/arm/s3c2xx0/s3c2410reg.h>
79 1.3.4.2 skrll #endif
80 1.3.4.2 skrll #ifdef CPU_S3C2800
81 1.3.4.2 skrll #include <arch/arm/s3c2xx0/s3c2800reg.h>
82 1.3.4.2 skrll #endif
83 1.3.4.2 skrll #include <lib/libsa/stand.h>
84 1.3.4.2 skrll
85 1.3.4.2 skrll #include "board.h"
86 1.3.4.2 skrll
87 1.3.4.2 skrll #ifndef SSCOM_TOLERANCE
88 1.3.4.2 skrll #define SSCOM_TOLERANCE 30 /* XXX: baud rate tolerance, in 0.1% units */
89 1.3.4.2 skrll #endif
90 1.3.4.2 skrll
91 1.3.4.2 skrll #define INB(x) *((__volatile uint8_t *) ((CONADDR) + (x)))
92 1.3.4.2 skrll #define INW(x) *((__volatile uint32_t *) ((CONADDR) + (x)))
93 1.3.4.2 skrll #define OUTB(x, v) (*((__volatile uint8_t *) ((CONADDR) + (x))) = (v))
94 1.3.4.2 skrll #define OUTW(x, v) (*((__volatile uint32_t *) ((CONADDR) + (x))) = (v))
95 1.3.4.2 skrll
96 1.3.4.2 skrll #define ISSET(t,f) ((t) & (f))
97 1.3.4.2 skrll
98 1.3.4.2 skrll static long get_com_freq(void);
99 1.3.4.2 skrll
100 1.3.4.2 skrll static int
101 1.3.4.2 skrll sscomspeed(long speed)
102 1.3.4.2 skrll {
103 1.3.4.2 skrll #define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */
104 1.3.4.2 skrll
105 1.3.4.2 skrll int x, err;
106 1.3.4.2 skrll long pclk = get_com_freq();
107 1.3.4.2 skrll
108 1.3.4.2 skrll if (speed <= 0)
109 1.3.4.2 skrll return -1;
110 1.3.4.2 skrll x = divrnd(pclk / 16, speed);
111 1.3.4.2 skrll if (x <= 0)
112 1.3.4.2 skrll return -1;
113 1.3.4.2 skrll err = divrnd(((quad_t)pclk) * 1000 / 16, speed * x) - 1000;
114 1.3.4.2 skrll if (err < 0)
115 1.3.4.2 skrll err = -err;
116 1.3.4.2 skrll if (err > SSCOM_TOLERANCE)
117 1.3.4.2 skrll return -1;
118 1.3.4.2 skrll return x-1;
119 1.3.4.2 skrll
120 1.3.4.2 skrll #undef divrnd
121 1.3.4.2 skrll }
122 1.3.4.2 skrll
123 1.3.4.2 skrll void
124 1.3.4.2 skrll cons_init(void)
125 1.3.4.2 skrll {
126 1.3.4.2 skrll int rate;
127 1.3.4.2 skrll
128 1.3.4.2 skrll OUTW(SSCOM_UCON, 0);
129 1.3.4.2 skrll OUTB(SSCOM_UFCON, UFCON_TXTRIGGER_8 | UFCON_RXTRIGGER_8 |
130 1.3.4.2 skrll UFCON_TXFIFO_RESET | UFCON_RXFIFO_RESET |
131 1.3.4.2 skrll UFCON_FIFO_ENABLE);
132 1.3.4.2 skrll
133 1.3.4.2 skrll rate = sscomspeed(CONSPEED);
134 1.3.4.2 skrll OUTW(SSCOM_UBRDIV, rate);
135 1.3.4.2 skrll OUTW(SSCOM_ULCON, ULCON_PARITY_NONE|ULCON_LENGTH_8);
136 1.3.4.2 skrll
137 1.3.4.2 skrll /* enable UART */
138 1.3.4.2 skrll OUTW(SSCOM_UCON, UCON_TXMODE_INT|UCON_RXMODE_INT);
139 1.3.4.2 skrll OUTW(SSCOM_UMCON, UMCON_RTS);
140 1.3.4.2 skrll }
141 1.3.4.2 skrll
142 1.3.4.2 skrll #define sscom_rxrdy() (INB(SSCOM_UTRSTAT) & UTRSTAT_RXREADY)
143 1.3.4.2 skrll
144 1.3.4.2 skrll int
145 1.3.4.2 skrll getchar(void)
146 1.3.4.2 skrll {
147 1.3.4.2 skrll uint8_t stat;
148 1.3.4.2 skrll int c;
149 1.3.4.2 skrll
150 1.3.4.2 skrll while (!sscom_rxrdy())
151 1.3.4.2 skrll /* spin */ ;
152 1.3.4.2 skrll c = INB(SSCOM_URXH);
153 1.3.4.2 skrll stat = INB(SSCOM_UERSTAT); /* XXX */
154 1.3.4.2 skrll
155 1.3.4.2 skrll return c;
156 1.3.4.2 skrll }
157 1.3.4.2 skrll
158 1.3.4.2 skrll static void
159 1.3.4.2 skrll iputchar(int c)
160 1.3.4.2 skrll {
161 1.3.4.2 skrll uint32_t stat;
162 1.3.4.2 skrll int timo;
163 1.3.4.2 skrll
164 1.3.4.2 skrll /* Wait for any pending transmission to finish. */
165 1.3.4.2 skrll timo = 50000;
166 1.3.4.2 skrll while (ISSET(stat = INW(SSCOM_UFSTAT), UFSTAT_TXFULL) && --timo)
167 1.3.4.2 skrll /* spin */ ;
168 1.3.4.2 skrll
169 1.3.4.2 skrll OUTB(SSCOM_UTXH, c);
170 1.3.4.2 skrll
171 1.3.4.2 skrll #if 0
172 1.3.4.2 skrll /* Wait for this transmission to complete. */
173 1.3.4.2 skrll timo = 1500000;
174 1.3.4.2 skrll while (!ISSET(stat = INW(SSCOM_UFSTAT), UFSTAT_TXFULL) && --timo)
175 1.3.4.2 skrll /* spin */ ;
176 1.3.4.2 skrll #endif
177 1.3.4.2 skrll }
178 1.3.4.2 skrll
179 1.3.4.2 skrll void
180 1.3.4.2 skrll putchar(int c)
181 1.3.4.2 skrll {
182 1.3.4.2 skrll
183 1.3.4.2 skrll if (c == '\n')
184 1.3.4.2 skrll iputchar('\r');
185 1.3.4.2 skrll iputchar(c);
186 1.3.4.2 skrll }
187 1.3.4.2 skrll
188 1.3.4.2 skrll
189 1.3.4.2 skrll #define read_reg(addr) (*(volatile uint32_t *)(addr))
190 1.3.4.2 skrll
191 1.3.4.2 skrll static long
192 1.3.4.2 skrll get_com_freq(void)
193 1.3.4.2 skrll {
194 1.3.4.2 skrll long clk;
195 1.3.4.2 skrll #ifdef CPU_S3C2800
196 1.3.4.2 skrll uint32_t pllcon = read_reg(S3C2800_CLKMAN_BASE+CLKMAN_PLLCON);
197 1.3.4.2 skrll uint32_t div = read_reg(S3C2800_CLKMAN_BASE+CLKMAN_CLKCON);
198 1.3.4.2 skrll #define HDIV CLKCON_HCLK
199 1.3.4.2 skrll #define PDIV CLKCON_PCLK
200 1.3.4.2 skrll #endif
201 1.3.4.2 skrll #ifdef CPU_S3C2410
202 1.3.4.2 skrll uint32_t pllcon = read_reg(S3C2410_CLKMAN_BASE+CLKMAN_MPLLCON);
203 1.3.4.2 skrll uint32_t div = read_reg(S3C2410_CLKMAN_BASE+CLKMAN_CLKDIVN);
204 1.3.4.2 skrll #define HDIV CLKDIVN_HDIVN
205 1.3.4.2 skrll #define PDIV CLKDIVN_PDIVN
206 1.3.4.2 skrll #endif
207 1.3.4.2 skrll
208 1.3.4.2 skrll int mdiv = (pllcon & PLLCON_MDIV_MASK) >> PLLCON_MDIV_SHIFT;
209 1.3.4.2 skrll int pdiv = (pllcon & PLLCON_PDIV_MASK) >> PLLCON_PDIV_SHIFT;
210 1.3.4.2 skrll int sdiv = (pllcon & PLLCON_SDIV_MASK) >> PLLCON_SDIV_SHIFT;
211 1.3.4.2 skrll
212 1.3.4.2 skrll #if XTAL_CLK < 1000 /* in MHz */
213 1.3.4.2 skrll clk = (XTAL_CLK * 1000000 * (8 + mdiv)) / ((pdiv + 2) << sdiv);
214 1.3.4.2 skrll #else /* in Hz */
215 1.3.4.2 skrll clk = (XTAL_CLK * (8 + mdiv)) / ((pdiv + 2) << sdiv);
216 1.3.4.2 skrll #endif
217 1.3.4.2 skrll
218 1.3.4.2 skrll /*printf( "M=%d P=%d S=%d\n", mdiv, pdiv, sdiv);*/
219 1.3.4.2 skrll
220 1.3.4.2 skrll if (div & HDIV)
221 1.3.4.2 skrll clk /= 2;
222 1.3.4.2 skrll if (div & PDIV)
223 1.3.4.2 skrll clk /= 2;
224 1.3.4.2 skrll
225 1.3.4.2 skrll return clk;
226 1.3.4.2 skrll }
227