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