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