Home | History | Annotate | Line # | Download | only in common
      1 /*	$NetBSD: iris_zs.c,v 1.2 2024/05/03 21:38:15 andvar Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2018 Naruaki Etomi
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 /*-
     29  * Copyright (c) 1996, 2000 The NetBSD Foundation, Inc.
     30  * All rights reserved.
     31  *
     32  * This code is derived from software contributed to The NetBSD Foundation
     33  * by Gordon W. Ross and Wayne Knowles
     34  *
     35  * Redistribution and use in source and binary forms, with or without
     36  * modification, are permitted provided that the following conditions
     37  * are met:
     38  * 1. Redistributions of source code must retain the above copyright
     39  *    notice, this list of conditions and the following disclaimer.
     40  * 2. Redistributions in binary form must reproduce the above copyright
     41  *    notice, this list of conditions and the following disclaimer in the
     42  *    documentation and/or other materials provided with the distribution.
     43  *
     44  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     45  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     46  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     47  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     48  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     49  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     50  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     51  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     52  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     53  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     54  * POSSIBILITY OF SUCH DAMAGE.
     55  */
     56 
     57 /*
     58  * Silicon Graphics "IRIS" series MIPS processors machine bootloader.
     59  * Zilog Z8530 Dual UART driver.
     60  * Most of the following was adapted from /sys/arch/sgimips/dev/zs.c.
     61  *	NetBSD: zs.c,v 1.39 2015/02/18 16:47:58 macallan Exp
     62  */
     63 
     64 #include <lib/libsa/stand.h>
     65 #include <lib/libkern/libkern.h>
     66 
     67 #include <dev/ic/z8530reg.h>
     68 
     69 #include <mips/cpuregs.h>
     70 #include <machine/cpu.h>
     71 
     72 #include "iris_machdep.h"
     73 #include "iris_zs.h"
     74 
     75 #define ZSCLOCK		3672000	 /* PCLK pin input clock rate */
     76 #define ZS_DELAY()	DELAY(3)
     77 #define ZS_DEFSPEED	9600
     78 
     79 static void zs_write(void *, uint8_t);
     80 static void zs_write_reg(void *, uint8_t, uint8_t);
     81 static void zs_reset(void *);
     82 static struct zschan *zs_get_chan_addr(int zs_unit, int channel);
     83 int	zs_getc(void *);
     84 void	zs_putc(void *, int);
     85 int	zs_scan(void *);
     86 
     87 static int cons_port;
     88 
     89 static void
     90 zs_write(void *dev, uint8_t val)
     91 {
     92 	struct zschan *zc = dev;
     93 
     94 	zc->zc_csr = val;
     95 	ZS_DELAY();
     96 }
     97 
     98 static void
     99 zs_write_reg(void *dev, uint8_t reg, uint8_t val)
    100 {
    101 
    102 	zs_write(dev, reg);
    103 	zs_write(dev, val);
    104 }
    105 
    106 static void
    107 zs_reset(void *dev)
    108 {
    109 
    110 	/* clear errors */
    111 	zs_write_reg(dev,  9, 0);
    112 	/* hardware reset */
    113 	zs_write_reg(dev,  9, ZSWR9_HARD_RESET);
    114 	DELAY(1000);
    115 
    116 	/* disable all interrupts */
    117 	zs_write_reg(dev,  1, 0);
    118 
    119 	/* set TX/RX misc parameters and modes */
    120 	zs_write_reg(dev,  4, ZSWR4_CLK_X16 | ZSWR4_ONESB | ZSWR4_EVENP);
    121 	zs_write_reg(dev, 10, ZSWR10_NRZ);
    122 	zs_write_reg(dev,  3, ZSWR3_RX_8);
    123 	zs_write_reg(dev,  5, ZSWR5_TX_8 | ZSWR5_DTR | ZSWR5_RTS);
    124 
    125 	/* sync registers unused */
    126 	zs_write_reg(dev,  6, 0);
    127 	zs_write_reg(dev,  7, 0);
    128 
    129 	/* set clock mode */
    130 	zs_write_reg(dev, 11,
    131 	    ZSWR11_RXCLK_BAUD | ZSWR11_TXCLK_BAUD | ZSWR11_TRXC_OUT_ENA);
    132 
    133 	/* set baud rate constant */
    134 	zs_write_reg(dev, 12, BPS_TO_TCONST(ZSCLOCK / 16, ZS_DEFSPEED));
    135 	zs_write_reg(dev, 13, 0);
    136 
    137 	/* enable baud rate generator */
    138 	zs_write_reg(dev, 14, ZSWR14_BAUD_ENA);
    139 
    140 	/* disable all external interrupts */
    141 	zs_write_reg(dev, 15, 0);
    142 
    143 	/* reset external status twice (see src/sys/dev/ic/z8530sc.c) */
    144 	zs_write(dev, ZSWR0_RESET_STATUS);
    145 	zs_write(dev, ZSWR0_RESET_STATUS);
    146 
    147 	/* enable TX and RX */
    148 	zs_write_reg(dev,  3, ZSWR3_RX_8 | ZSWR3_RX_ENABLE);
    149 	zs_write_reg(dev,  5,
    150 	    ZSWR5_TX_8 | ZSWR5_DTR | ZSWR5_RTS | ZSWR5_TX_ENABLE);
    151 }
    152 
    153 static struct zschan *
    154 zs_get_chan_addr(int zs_unit, int channel)
    155 {
    156 	struct zsdevice *addr;
    157 	struct zschan *zc;
    158 
    159 	addr = (struct zsdevice *)MIPS_PHYS_TO_KSEG1(ZS_ADDR);
    160 
    161 	zc = &addr->zs_chan_b;
    162 
    163 	return zc;
    164 }
    165 
    166 void *
    167 zs_init(int addr, int speed)
    168 {
    169 	struct zschan *zs;
    170 	cons_port = 0;
    171 
    172 	zs = zs_get_chan_addr(1, cons_port);
    173 
    174 	zs_reset(zs);
    175 
    176 	return zs;
    177 }
    178 
    179 void
    180 zscnputc(void *dev, int c)
    181 {
    182 	struct zschan *zs;
    183 
    184 	zs = zs_get_chan_addr(1, cons_port);
    185 
    186 	zs_putc(zs, c);
    187 }
    188 
    189 void
    190 zs_putc(void *arg, int c)
    191 {
    192 	register volatile struct zschan *zc = arg;
    193 	register int rr0;
    194 
    195 	/* Wait for transmitter to become ready. */
    196 	do {
    197 		rr0 = zc->zc_csr;
    198 		ZS_DELAY();
    199 	} while ((rr0 & ZSRR0_TX_READY) == 0);
    200 
    201 	zc->zc_data = c;
    202 	ZS_DELAY();
    203 }
    204 
    205 int
    206 zscngetc(void *dev)
    207 {
    208 	struct zschan *zs;
    209 
    210 	zs = zs_get_chan_addr(1, cons_port);
    211 
    212 	return zs_getc(zs);
    213 }
    214 
    215 int
    216 zs_getc(void *arg)
    217 {
    218 	struct zschan *zc = arg;
    219 	int c, rr0;
    220 
    221 	/* Wait for a character to arrive. */
    222 	do {
    223 		rr0 = zc->zc_csr;
    224 		ZS_DELAY();
    225 	} while ((rr0 & ZSRR0_RX_READY) == 0);
    226 
    227 	c = zc->zc_data;
    228 	ZS_DELAY();
    229 
    230 	return c;
    231 }
    232 
    233 int
    234 zscnscanc(void *dev)
    235 {
    236 	struct zschan *zs;
    237 
    238 	zs = zs_get_chan_addr(1, cons_port);
    239 
    240 	return zs_scan(zs);
    241 }
    242 
    243 int
    244 zs_scan(void *arg)
    245 {
    246 	struct zschan *zc = arg;
    247 	int c, rr0;
    248 
    249 	/* Wait for a character to arrive. */
    250 	rr0 = zc->zc_csr;
    251 	ZS_DELAY();
    252 
    253 	if ((rr0 & ZSRR0_RX_READY) == 0) {
    254 		return -1;
    255 	}
    256 
    257 	c = zc->zc_data;
    258 	ZS_DELAY();
    259 
    260 	return c;
    261 }
    262