sscom.c revision 1.7 1 1.7 tsutsui /* $NetBSD: sscom.c,v 1.7 2022/09/05 14:14:42 tsutsui 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.3 bsh #ifdef CPU_S3C2410
78 1.2 mycroft #include <arch/arm/s3c2xx0/s3c2410reg.h>
79 1.3 bsh #endif
80 1.3 bsh #ifdef CPU_S3C2800
81 1.3 bsh #include <arch/arm/s3c2xx0/s3c2800reg.h>
82 1.3 bsh #endif
83 1.1 bsh #include <lib/libsa/stand.h>
84 1.1 bsh
85 1.1 bsh #include "board.h"
86 1.1 bsh
87 1.1 bsh #ifndef SSCOM_TOLERANCE
88 1.1 bsh #define SSCOM_TOLERANCE 30 /* XXX: baud rate tolerance, in 0.1% units */
89 1.1 bsh #endif
90 1.1 bsh
91 1.5 perry #define INB(x) *((volatile uint8_t *) ((CONADDR) + (x)))
92 1.5 perry #define INW(x) *((volatile uint32_t *) ((CONADDR) + (x)))
93 1.5 perry #define OUTB(x, v) (*((volatile uint8_t *) ((CONADDR) + (x))) = (v))
94 1.5 perry #define OUTW(x, v) (*((volatile uint32_t *) ((CONADDR) + (x))) = (v))
95 1.1 bsh
96 1.3 bsh static long get_com_freq(void);
97 1.1 bsh
98 1.1 bsh static int
99 1.1 bsh sscomspeed(long speed)
100 1.1 bsh {
101 1.1 bsh #define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */
102 1.1 bsh
103 1.1 bsh int x, err;
104 1.1 bsh long pclk = get_com_freq();
105 1.1 bsh
106 1.1 bsh if (speed <= 0)
107 1.1 bsh return -1;
108 1.1 bsh x = divrnd(pclk / 16, speed);
109 1.1 bsh if (x <= 0)
110 1.1 bsh return -1;
111 1.1 bsh err = divrnd(((quad_t)pclk) * 1000 / 16, speed * x) - 1000;
112 1.1 bsh if (err < 0)
113 1.1 bsh err = -err;
114 1.1 bsh if (err > SSCOM_TOLERANCE)
115 1.1 bsh return -1;
116 1.1 bsh return x-1;
117 1.1 bsh
118 1.1 bsh #undef divrnd
119 1.1 bsh }
120 1.1 bsh
121 1.1 bsh void
122 1.1 bsh cons_init(void)
123 1.1 bsh {
124 1.1 bsh int rate;
125 1.1 bsh
126 1.1 bsh OUTW(SSCOM_UCON, 0);
127 1.1 bsh OUTB(SSCOM_UFCON, UFCON_TXTRIGGER_8 | UFCON_RXTRIGGER_8 |
128 1.1 bsh UFCON_TXFIFO_RESET | UFCON_RXFIFO_RESET |
129 1.1 bsh UFCON_FIFO_ENABLE);
130 1.1 bsh
131 1.1 bsh rate = sscomspeed(CONSPEED);
132 1.1 bsh OUTW(SSCOM_UBRDIV, rate);
133 1.1 bsh OUTW(SSCOM_ULCON, ULCON_PARITY_NONE|ULCON_LENGTH_8);
134 1.1 bsh
135 1.1 bsh /* enable UART */
136 1.1 bsh OUTW(SSCOM_UCON, UCON_TXMODE_INT|UCON_RXMODE_INT);
137 1.1 bsh OUTW(SSCOM_UMCON, UMCON_RTS);
138 1.1 bsh }
139 1.1 bsh
140 1.1 bsh #define sscom_rxrdy() (INB(SSCOM_UTRSTAT) & UTRSTAT_RXREADY)
141 1.1 bsh
142 1.1 bsh int
143 1.1 bsh getchar(void)
144 1.1 bsh {
145 1.6 christos uint8_t stat __unused;
146 1.1 bsh int c;
147 1.1 bsh
148 1.1 bsh while (!sscom_rxrdy())
149 1.1 bsh /* spin */ ;
150 1.1 bsh c = INB(SSCOM_URXH);
151 1.1 bsh stat = INB(SSCOM_UERSTAT); /* XXX */
152 1.1 bsh
153 1.1 bsh return c;
154 1.1 bsh }
155 1.1 bsh
156 1.1 bsh static void
157 1.1 bsh iputchar(int c)
158 1.1 bsh {
159 1.2 mycroft uint32_t stat;
160 1.1 bsh int timo;
161 1.1 bsh
162 1.1 bsh /* Wait for any pending transmission to finish. */
163 1.1 bsh timo = 50000;
164 1.1 bsh while (ISSET(stat = INW(SSCOM_UFSTAT), UFSTAT_TXFULL) && --timo)
165 1.1 bsh /* spin */ ;
166 1.1 bsh
167 1.1 bsh OUTB(SSCOM_UTXH, c);
168 1.1 bsh
169 1.1 bsh #if 0
170 1.1 bsh /* Wait for this transmission to complete. */
171 1.1 bsh timo = 1500000;
172 1.1 bsh while (!ISSET(stat = INW(SSCOM_UFSTAT), UFSTAT_TXFULL) && --timo)
173 1.1 bsh /* spin */ ;
174 1.1 bsh #endif
175 1.1 bsh }
176 1.1 bsh
177 1.1 bsh void
178 1.1 bsh putchar(int c)
179 1.1 bsh {
180 1.1 bsh
181 1.1 bsh if (c == '\n')
182 1.1 bsh iputchar('\r');
183 1.1 bsh iputchar(c);
184 1.3 bsh }
185 1.3 bsh
186 1.3 bsh
187 1.3 bsh #define read_reg(addr) (*(volatile uint32_t *)(addr))
188 1.3 bsh
189 1.3 bsh static long
190 1.3 bsh get_com_freq(void)
191 1.3 bsh {
192 1.3 bsh long clk;
193 1.3 bsh #ifdef CPU_S3C2800
194 1.3 bsh uint32_t pllcon = read_reg(S3C2800_CLKMAN_BASE+CLKMAN_PLLCON);
195 1.3 bsh uint32_t div = read_reg(S3C2800_CLKMAN_BASE+CLKMAN_CLKCON);
196 1.3 bsh #define HDIV CLKCON_HCLK
197 1.3 bsh #define PDIV CLKCON_PCLK
198 1.3 bsh #endif
199 1.3 bsh #ifdef CPU_S3C2410
200 1.3 bsh uint32_t pllcon = read_reg(S3C2410_CLKMAN_BASE+CLKMAN_MPLLCON);
201 1.3 bsh uint32_t div = read_reg(S3C2410_CLKMAN_BASE+CLKMAN_CLKDIVN);
202 1.3 bsh #define HDIV CLKDIVN_HDIVN
203 1.3 bsh #define PDIV CLKDIVN_PDIVN
204 1.3 bsh #endif
205 1.3 bsh
206 1.3 bsh int mdiv = (pllcon & PLLCON_MDIV_MASK) >> PLLCON_MDIV_SHIFT;
207 1.3 bsh int pdiv = (pllcon & PLLCON_PDIV_MASK) >> PLLCON_PDIV_SHIFT;
208 1.3 bsh int sdiv = (pllcon & PLLCON_SDIV_MASK) >> PLLCON_SDIV_SHIFT;
209 1.3 bsh
210 1.3 bsh #if XTAL_CLK < 1000 /* in MHz */
211 1.3 bsh clk = (XTAL_CLK * 1000000 * (8 + mdiv)) / ((pdiv + 2) << sdiv);
212 1.3 bsh #else /* in Hz */
213 1.3 bsh clk = (XTAL_CLK * (8 + mdiv)) / ((pdiv + 2) << sdiv);
214 1.3 bsh #endif
215 1.3 bsh
216 1.3 bsh /*printf( "M=%d P=%d S=%d\n", mdiv, pdiv, sdiv);*/
217 1.3 bsh
218 1.3 bsh if (div & HDIV)
219 1.3 bsh clk /= 2;
220 1.3 bsh if (div & PDIV)
221 1.3 bsh clk /= 2;
222 1.3 bsh
223 1.3 bsh return clk;
224 1.1 bsh }
225