hd64461uart.c revision 1.2.2.2 1 1.2.2.2 bouyer /* $NetBSD: hd64461uart.c,v 1.2.2.2 2001/03/27 15:30:58 bouyer Exp $ */
2 1.2.2.2 bouyer
3 1.2.2.2 bouyer /*-
4 1.2.2.2 bouyer * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 1.2.2.2 bouyer * All rights reserved.
6 1.2.2.2 bouyer *
7 1.2.2.2 bouyer * Redistribution and use in source and binary forms, with or without
8 1.2.2.2 bouyer * modification, are permitted provided that the following conditions
9 1.2.2.2 bouyer * are met:
10 1.2.2.2 bouyer * 1. Redistributions of source code must retain the above copyright
11 1.2.2.2 bouyer * notice, this list of conditions and the following disclaimer.
12 1.2.2.2 bouyer * 2. Redistributions in binary form must reproduce the above copyright
13 1.2.2.2 bouyer * notice, this list of conditions and the following disclaimer in the
14 1.2.2.2 bouyer * documentation and/or other materials provided with the distribution.
15 1.2.2.2 bouyer * 3. All advertising materials mentioning features or use of this software
16 1.2.2.2 bouyer * must display the following acknowledgement:
17 1.2.2.2 bouyer * This product includes software developed by the NetBSD
18 1.2.2.2 bouyer * Foundation, Inc. and its contributors.
19 1.2.2.2 bouyer * 4. Neither the name of The NetBSD Foundation nor the names of its
20 1.2.2.2 bouyer * contributors may be used to endorse or promote products derived
21 1.2.2.2 bouyer * from this software without specific prior written permission.
22 1.2.2.2 bouyer *
23 1.2.2.2 bouyer * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
24 1.2.2.2 bouyer * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25 1.2.2.2 bouyer * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 1.2.2.2 bouyer * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
27 1.2.2.2 bouyer * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 1.2.2.2 bouyer * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 1.2.2.2 bouyer * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 1.2.2.2 bouyer * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 1.2.2.2 bouyer * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 1.2.2.2 bouyer * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 1.2.2.2 bouyer * POSSIBILITY OF SUCH DAMAGE.
34 1.2.2.2 bouyer */
35 1.2.2.2 bouyer
36 1.2.2.2 bouyer #include <sys/param.h>
37 1.2.2.2 bouyer #include <sys/systm.h>
38 1.2.2.2 bouyer #include <sys/reboot.h>
39 1.2.2.2 bouyer #include <sys/malloc.h>
40 1.2.2.2 bouyer #include <sys/device.h>
41 1.2.2.2 bouyer
42 1.2.2.2 bouyer #include <sys/termios.h>
43 1.2.2.2 bouyer #include <dev/cons.h>
44 1.2.2.2 bouyer #include <sys/conf.h>
45 1.2.2.2 bouyer
46 1.2.2.2 bouyer #include <machine/bus.h>
47 1.2.2.2 bouyer #include <machine/intr.h>
48 1.2.2.2 bouyer
49 1.2.2.2 bouyer #include <dev/ic/comvar.h>
50 1.2.2.2 bouyer #include <dev/ic/comreg.h>
51 1.2.2.2 bouyer
52 1.2.2.2 bouyer #ifdef DEBUG
53 1.2.2.2 bouyer #include <hpcsh/hpcsh/debug.h>
54 1.2.2.2 bouyer #endif
55 1.2.2.2 bouyer
56 1.2.2.2 bouyer #include <hpcsh/dev/hd64461/hd64461var.h>
57 1.2.2.2 bouyer #include <hpcsh/dev/hd64461/hd64461reg.h>
58 1.2.2.2 bouyer #include <hpcsh/dev/hd64461/hd64461intcvar.h>
59 1.2.2.2 bouyer
60 1.2.2.2 bouyer static struct hd64461uart_chip {
61 1.2.2.2 bouyer struct hpcsh_bus_space __tag_body;
62 1.2.2.2 bouyer bus_space_tag_t io_tag;
63 1.2.2.2 bouyer int console;
64 1.2.2.2 bouyer } hd64461uart_chip;
65 1.2.2.2 bouyer
66 1.2.2.2 bouyer struct hd64461uart_softc {
67 1.2.2.2 bouyer struct com_softc sc_com;
68 1.2.2.2 bouyer
69 1.2.2.2 bouyer struct hd64461uart_chip *sc_chip;
70 1.2.2.2 bouyer enum hd64461_module_id sc_module_id;
71 1.2.2.2 bouyer };
72 1.2.2.2 bouyer
73 1.2.2.2 bouyer /* boot console */
74 1.2.2.2 bouyer cdev_decl(com);
75 1.2.2.2 bouyer void comcnprobe(struct consdev *);
76 1.2.2.2 bouyer void comcninit(struct consdev *);
77 1.2.2.2 bouyer
78 1.2.2.2 bouyer static int hd64461uart_match(struct device *, struct cfdata *, void *);
79 1.2.2.2 bouyer static void hd64461uart_attach(struct device *, struct device *, void *);
80 1.2.2.2 bouyer
81 1.2.2.2 bouyer struct cfattach hd64461uart_ca = {
82 1.2.2.2 bouyer sizeof(struct hd64461uart_softc), hd64461uart_match,
83 1.2.2.2 bouyer hd64461uart_attach
84 1.2.2.2 bouyer };
85 1.2.2.2 bouyer
86 1.2.2.2 bouyer static void hd64461uart_init(void);
87 1.2.2.2 bouyer static u_int8_t hd64461uart_read_1(void *, bus_space_handle_t, bus_size_t);
88 1.2.2.2 bouyer static void hd64461uart_write_1(void *, bus_space_handle_t, bus_size_t,
89 1.2.2.2 bouyer u_int8_t);
90 1.2.2.2 bouyer
91 1.2.2.2 bouyer #ifdef DEBUG
92 1.2.2.2 bouyer static void hd64461uart_info(struct hd64461uart_softc *);
93 1.2.2.2 bouyer #endif
94 1.2.2.2 bouyer
95 1.2.2.2 bouyer #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
96 1.2.2.2 bouyer #ifndef COMCN_SPEED
97 1.2.2.2 bouyer #define COMCN_SPEED 19200
98 1.2.2.2 bouyer #endif
99 1.2.2.2 bouyer
100 1.2.2.2 bouyer void
101 1.2.2.2 bouyer comcnprobe(struct consdev *cp)
102 1.2.2.2 bouyer {
103 1.2.2.2 bouyer int maj;
104 1.2.2.2 bouyer
105 1.2.2.2 bouyer /* locate the major number */
106 1.2.2.2 bouyer for (maj = 0; maj < nchrdev; maj++)
107 1.2.2.2 bouyer if (cdevsw[maj].d_open == comopen)
108 1.2.2.2 bouyer break;
109 1.2.2.2 bouyer
110 1.2.2.2 bouyer /* Initialize required fields. */
111 1.2.2.2 bouyer cp->cn_dev = makedev(maj, 0);
112 1.2.2.2 bouyer cp->cn_pri = CN_NORMAL;
113 1.2.2.2 bouyer }
114 1.2.2.2 bouyer
115 1.2.2.2 bouyer void
116 1.2.2.2 bouyer comcninit(struct consdev *cp)
117 1.2.2.2 bouyer {
118 1.2.2.2 bouyer hd64461uart_init();
119 1.2.2.2 bouyer
120 1.2.2.2 bouyer comcnattach(hd64461uart_chip.io_tag, 0x0, COMCN_SPEED, COM_FREQ,
121 1.2.2.2 bouyer CONMODE);
122 1.2.2.2 bouyer
123 1.2.2.2 bouyer hd64461uart_chip.console = 1;
124 1.2.2.2 bouyer }
125 1.2.2.2 bouyer
126 1.2.2.2 bouyer static int
127 1.2.2.2 bouyer hd64461uart_match(struct device *parent, struct cfdata *cf, void *aux)
128 1.2.2.2 bouyer {
129 1.2.2.2 bouyer struct hd64461_attach_args *ha = aux;
130 1.2.2.2 bouyer
131 1.2.2.2 bouyer return (ha->ha_module_id == HD64461_MODULE_UART);
132 1.2.2.2 bouyer }
133 1.2.2.2 bouyer
134 1.2.2.2 bouyer static void
135 1.2.2.2 bouyer hd64461uart_attach(struct device *parent, struct device *self, void *aux)
136 1.2.2.2 bouyer {
137 1.2.2.2 bouyer struct hd64461_attach_args *ha = aux;
138 1.2.2.2 bouyer struct hd64461uart_softc *sc = (struct hd64461uart_softc *)self;
139 1.2.2.2 bouyer struct com_softc *csc = &sc->sc_com;
140 1.2.2.2 bouyer u_int16_t r16;
141 1.2.2.2 bouyer
142 1.2.2.2 bouyer sc->sc_chip = &hd64461uart_chip;
143 1.2.2.2 bouyer
144 1.2.2.2 bouyer sc->sc_module_id = ha->ha_module_id;
145 1.2.2.2 bouyer
146 1.2.2.2 bouyer hd64461uart_init();
147 1.2.2.2 bouyer
148 1.2.2.2 bouyer csc->sc_iot = sc->sc_chip->io_tag;
149 1.2.2.2 bouyer bus_space_map(csc->sc_iot, 0, 8, 0, &csc->sc_ioh);
150 1.2.2.2 bouyer csc->sc_iobase = 0;
151 1.2.2.2 bouyer csc->sc_frequency = COM_FREQ;
152 1.2.2.2 bouyer
153 1.2.2.2 bouyer /* switch port to UART */
154 1.2.2.2 bouyer
155 1.2.2.2 bouyer /* supply clock */
156 1.2.2.2 bouyer r16 = hd64461_reg_read_2(HD64461_SYSSTBCR_REG16);
157 1.2.2.2 bouyer r16 &= ~HD64461_SYSSTBCR_SURTSD;
158 1.2.2.2 bouyer hd64461_reg_write_2(HD64461_SYSSTBCR_REG16, r16);
159 1.2.2.2 bouyer
160 1.2.2.2 bouyer #ifdef DEBUG
161 1.2.2.2 bouyer if (bootverbose)
162 1.2.2.2 bouyer hd64461uart_info(sc);
163 1.2.2.2 bouyer #endif
164 1.2.2.2 bouyer /* sanity check */
165 1.2.2.2 bouyer if (!comprobe1(csc->sc_iot, csc->sc_ioh)) {
166 1.2.2.2 bouyer printf(": device problem. don't attach.\n");
167 1.2.2.2 bouyer
168 1.2.2.2 bouyer /* stop clock */
169 1.2.2.2 bouyer r16 |= HD64461_SYSSTBCR_SURTSD;
170 1.2.2.2 bouyer hd64461_reg_write_2(HD64461_SYSSTBCR_REG16, r16);
171 1.2.2.2 bouyer return;
172 1.2.2.2 bouyer }
173 1.2.2.2 bouyer
174 1.2.2.2 bouyer com_attach_subr(csc);
175 1.2.2.2 bouyer
176 1.2.2.2 bouyer hd64461_intr_establish(HD64461_IRQ_UART, IST_LEVEL, IPL_TTY,
177 1.2.2.2 bouyer comintr, self);
178 1.2.2.2 bouyer }
179 1.2.2.2 bouyer
180 1.2.2.2 bouyer static void
181 1.2.2.2 bouyer hd64461uart_init()
182 1.2.2.2 bouyer {
183 1.2.2.2 bouyer if (hd64461uart_chip.io_tag)
184 1.2.2.2 bouyer return;
185 1.2.2.2 bouyer
186 1.2.2.2 bouyer hd64461uart_chip.io_tag = bus_space_create(
187 1.2.2.2 bouyer &hd64461uart_chip.__tag_body, "HD64461 UART I/O",
188 1.2.2.2 bouyer HD64461_UART_REGBASE, 0); /* no extent */
189 1.2.2.2 bouyer
190 1.2.2.2 bouyer /* override bus_space_read_1, bus_space_write_1 */
191 1.2.2.2 bouyer hd64461uart_chip.io_tag->hbs_r_1 = hd64461uart_read_1;
192 1.2.2.2 bouyer hd64461uart_chip.io_tag->hbs_w_1 = hd64461uart_write_1;
193 1.2.2.2 bouyer }
194 1.2.2.2 bouyer
195 1.2.2.2 bouyer static u_int8_t
196 1.2.2.2 bouyer hd64461uart_read_1(void *t, bus_space_handle_t h, bus_size_t ofs)
197 1.2.2.2 bouyer {
198 1.2.2.2 bouyer return *(volatile u_int8_t *)(h + (ofs << 1));
199 1.2.2.2 bouyer }
200 1.2.2.2 bouyer
201 1.2.2.2 bouyer static void
202 1.2.2.2 bouyer hd64461uart_write_1(void *t, bus_space_handle_t h, bus_size_t ofs,
203 1.2.2.2 bouyer u_int8_t val)
204 1.2.2.2 bouyer {
205 1.2.2.2 bouyer
206 1.2.2.2 bouyer *(volatile u_int8_t *)(h + (ofs << 1)) = val;
207 1.2.2.2 bouyer }
208 1.2.2.2 bouyer
209 1.2.2.2 bouyer #ifdef DEBUG
210 1.2.2.2 bouyer static void
211 1.2.2.2 bouyer hd64461uart_info(struct hd64461uart_softc *sc)
212 1.2.2.2 bouyer {
213 1.2.2.2 bouyer const char name[] = __FUNCTION__;
214 1.2.2.2 bouyer
215 1.2.2.2 bouyer dbg_banner_start(name, sizeof name);
216 1.2.2.2 bouyer dbg_banner_end();
217 1.2.2.2 bouyer }
218 1.2.2.2 bouyer #endif /* DEBUG */
219