xref: /netbsd/sys/arch/cobalt/stand/boot/zs.c (revision b87210fa)
1*b87210faStsutsui /*	$NetBSD: zs.c,v 1.3 2008/05/14 13:29:28 tsutsui Exp $	*/
249576266Stsutsui 
349576266Stsutsui /*-
4*b87210faStsutsui  * Copyright (c) 2008 Izumi Tsutsui. All rights reserved.
549576266Stsutsui  *
649576266Stsutsui  * Redistribution and use in source and binary forms, with or without
749576266Stsutsui  * modification, are permitted provided that the following conditions
849576266Stsutsui  * are met:
949576266Stsutsui  * 1. Redistributions of source code must retain the above copyright
1049576266Stsutsui  *    notice, this list of conditions and the following disclaimer.
1149576266Stsutsui  * 2. Redistributions in binary form must reproduce the above copyright
1249576266Stsutsui  *    notice, this list of conditions and the following disclaimer in the
1349576266Stsutsui  *    documentation and/or other materials provided with the distribution.
1449576266Stsutsui  *
1549576266Stsutsui  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1649576266Stsutsui  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1749576266Stsutsui  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1849576266Stsutsui  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1949576266Stsutsui  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2049576266Stsutsui  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2149576266Stsutsui  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2249576266Stsutsui  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23*b87210faStsutsui  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24*b87210faStsutsui  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2549576266Stsutsui  */
2649576266Stsutsui 
2749576266Stsutsui #ifdef CONS_ZS
2849576266Stsutsui /*
2949576266Stsutsui  * optional Z85C30 serial support for Qube 2700
3049576266Stsutsui  */
3149576266Stsutsui 
3249576266Stsutsui #include <lib/libsa/stand.h>
334f64b671Stsutsui #include <lib/libkern/libkern.h>
344f64b671Stsutsui 
3549576266Stsutsui #include <dev/ic/z8530reg.h>
3649576266Stsutsui 
374f64b671Stsutsui #include <machine/cpu.h>
384f64b671Stsutsui 
3949576266Stsutsui #include "boot.h"
4049576266Stsutsui #include "zs.h"
4149576266Stsutsui 
4249576266Stsutsui #define ZSCLOCK		11059200	/* 19200 * 576 */
4349576266Stsutsui 
4449576266Stsutsui #define ZS_DELAY()	delay(2)
4549576266Stsutsui 
4649576266Stsutsui static uint8_t zs_read(void *, uint8_t);
4749576266Stsutsui static void zs_write(void *, uint8_t, uint8_t);
4849576266Stsutsui static void zs_write_reg(void *, uint8_t, uint8_t);
4949576266Stsutsui static void zs_reset(void *);
5049576266Stsutsui 
5149576266Stsutsui static uint8_t
zs_read(void * dev,uint8_t reg)5249576266Stsutsui zs_read(void *dev, uint8_t reg)
5349576266Stsutsui {
5449576266Stsutsui 	volatile uint8_t *zs = dev;
5549576266Stsutsui 	uint8_t val;
5649576266Stsutsui 
5749576266Stsutsui 	val = *(volatile uint8_t *)(zs + reg);
5849576266Stsutsui 	ZS_DELAY();
5949576266Stsutsui 
6049576266Stsutsui 	return val;
6149576266Stsutsui }
6249576266Stsutsui 
6349576266Stsutsui static void
zs_write(void * dev,uint8_t reg,uint8_t val)6449576266Stsutsui zs_write(void *dev, uint8_t reg, uint8_t val)
6549576266Stsutsui {
6649576266Stsutsui 	volatile uint8_t *zs = dev;
6749576266Stsutsui 
6849576266Stsutsui         *(volatile uint8_t *)(zs + reg) = val;
6949576266Stsutsui 	ZS_DELAY();
7049576266Stsutsui }
7149576266Stsutsui 
7249576266Stsutsui static void
zs_write_reg(void * dev,uint8_t reg,uint8_t val)7349576266Stsutsui zs_write_reg(void *dev, uint8_t reg, uint8_t val)
7449576266Stsutsui {
7549576266Stsutsui 
7649576266Stsutsui 	zs_write(dev, ZS_CSR, reg);
7749576266Stsutsui 	zs_write(dev, ZS_CSR, val);
7849576266Stsutsui }
7949576266Stsutsui 
8049576266Stsutsui static void
zs_reset(void * dev)8149576266Stsutsui zs_reset(void *dev)
8249576266Stsutsui {
8349576266Stsutsui 
8449576266Stsutsui 	/* clear errors */
8549576266Stsutsui 	zs_write_reg(dev,  9, 0);
8649576266Stsutsui 	/* hardware reset */
8749576266Stsutsui 	zs_write_reg(dev,  9, ZSWR9_HARD_RESET);
8849576266Stsutsui 	delay(1000);
8949576266Stsutsui 
9049576266Stsutsui 	/* disable all inerttupts */
9149576266Stsutsui 	zs_write_reg(dev,  1, 0);
9249576266Stsutsui 
9349576266Stsutsui 	/* set TX/RX misc parameters and modes */
9449576266Stsutsui 	zs_write_reg(dev,  4, ZSWR4_CLK_X16 | ZSWR4_ONESB | ZSWR4_EVENP);
9549576266Stsutsui 	zs_write_reg(dev, 10, ZSWR10_NRZ);
9649576266Stsutsui 	zs_write_reg(dev,  3, ZSWR3_RX_8);
9749576266Stsutsui 	zs_write_reg(dev,  5, ZSWR5_TX_8 | ZSWR5_DTR | ZSWR5_RTS);
9849576266Stsutsui 
9949576266Stsutsui 	/* sync registers unused */
10049576266Stsutsui 	zs_write_reg(dev,  6, 0);
10149576266Stsutsui 	zs_write_reg(dev,  7, 0);
10249576266Stsutsui 
10349576266Stsutsui 	/* set baud rate generator mode */
10449576266Stsutsui 	zs_write_reg(dev, 14, ZSWR14_BAUD_FROM_PCLK);
10549576266Stsutsui 	/* set clock mode */
10649576266Stsutsui 	zs_write_reg(dev, 11, ZSWR11_RXCLK_BAUD | ZSWR11_TXCLK_BAUD);
10749576266Stsutsui 	/* set baud rate constant */
10849576266Stsutsui 	zs_write_reg(dev, 12, BPS_TO_TCONST(ZSCLOCK / 16, ZSSPEED));
10949576266Stsutsui 	zs_write_reg(dev, 13, 0);
11049576266Stsutsui 
11149576266Stsutsui 	/* enable baud rate generator */
11249576266Stsutsui 	zs_write_reg(dev, 14, ZSWR14_BAUD_FROM_PCLK | ZSWR14_BAUD_ENA);
11349576266Stsutsui 	/* disable all external interrupts */
11449576266Stsutsui 	zs_write_reg(dev, 15, 0);
11549576266Stsutsui 
11649576266Stsutsui 	/* reset external status twice (see src/sys/dev/ic/z8530sc.c) */
11749576266Stsutsui 	zs_write(dev, ZS_CSR, ZSWR0_RESET_STATUS);
11849576266Stsutsui 	zs_write(dev, ZS_CSR, ZSWR0_RESET_STATUS);
11949576266Stsutsui 
12049576266Stsutsui 	/* enable TX and RX */
12149576266Stsutsui 	zs_write_reg(dev,  3, ZSWR3_RX_8 | ZSWR3_RX_ENABLE);
12249576266Stsutsui 	zs_write_reg(dev,  5,
12349576266Stsutsui 	    ZSWR5_TX_8 | ZSWR5_DTR | ZSWR5_RTS | ZSWR5_TX_ENABLE);
12449576266Stsutsui }
12549576266Stsutsui 
12649576266Stsutsui void *
zs_init(int addr,int speed)12749576266Stsutsui zs_init(int addr, int speed)
12849576266Stsutsui {
12949576266Stsutsui 	void *zs;
13049576266Stsutsui 
1314f64b671Stsutsui 	zs = (void *)MIPS_PHYS_TO_KSEG1(ZS_BASE + addr);
13249576266Stsutsui 	zs_reset(zs);
13349576266Stsutsui 
13449576266Stsutsui 	return zs;
13549576266Stsutsui }
13649576266Stsutsui 
13749576266Stsutsui void
zs_putc(void * dev,int c)13849576266Stsutsui zs_putc(void *dev, int c)
13949576266Stsutsui {
14049576266Stsutsui 	uint8_t csr;
14149576266Stsutsui 
14249576266Stsutsui 	do {
14349576266Stsutsui 		csr = zs_read(dev, ZS_CSR);
14449576266Stsutsui 	} while ((csr & ZSRR0_TX_READY) == 0);
14549576266Stsutsui 
14649576266Stsutsui 	zs_write(dev, ZS_DATA, c);
14749576266Stsutsui }
14849576266Stsutsui 
14949576266Stsutsui int
zs_getc(void * dev)15049576266Stsutsui zs_getc(void *dev)
15149576266Stsutsui {
15249576266Stsutsui 	uint8_t csr, data;
15349576266Stsutsui 
15449576266Stsutsui 	do {
15549576266Stsutsui 		csr = zs_read(dev, ZS_CSR);
15649576266Stsutsui 	} while ((csr & ZSRR0_RX_READY) == 0);
15749576266Stsutsui 
15849576266Stsutsui 	data = zs_read(dev, ZS_DATA);
15949576266Stsutsui 	return data;
16049576266Stsutsui }
16149576266Stsutsui 
16249576266Stsutsui int
zs_scan(void * dev)16349576266Stsutsui zs_scan(void *dev)
16449576266Stsutsui {
16549576266Stsutsui 	uint8_t csr, data;
16649576266Stsutsui 
16749576266Stsutsui 	csr = zs_read(dev, ZS_CSR);
16849576266Stsutsui 	if ((csr & ZSRR0_RX_READY) == 0)
16949576266Stsutsui 		return -1;
17049576266Stsutsui 
17149576266Stsutsui 	data = zs_read(dev, ZS_DATA);
17249576266Stsutsui 	return data;
17349576266Stsutsui }
17449576266Stsutsui #endif /* CONS_ZS */
175