xref: /netbsd-src/sys/arch/hpcmips/dev/plumpower.c (revision 3b01aba77a7a698587faaae455bbfe740923c1f5)
1 /*	$NetBSD: plumpower.c,v 1.5 2000/10/04 13:53:55 uch Exp $ */
2 
3 /*-
4  * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by UCHIYAMA Yasushi.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *        This product includes software developed by the NetBSD
21  *        Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 #undef PLUMPOWERDEBUG
40 #include "opt_tx39_debug.h"
41 
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/device.h>
45 #include <sys/malloc.h>
46 
47 #include <machine/bus.h>
48 #include <machine/intr.h>
49 
50 #include <hpcmips/tx/tx39var.h>
51 #include <hpcmips/dev/plumvar.h>
52 #include <hpcmips/dev/plumpowervar.h>
53 #include <hpcmips/dev/plumpowerreg.h>
54 
55 #ifdef PLUMPOWERDEBUG
56 int	plumpower_debug = 1;
57 #define	DPRINTF(arg) if (plumpower_debug) printf arg;
58 #define	DPRINTFN(n, arg) if (plumpower_debug > (n)) printf arg;
59 #else
60 #define	DPRINTF(arg)
61 #define DPRINTFN(n, arg)
62 #endif
63 
64 int	plumpower_match(struct device *, struct cfdata *, void *);
65 void	plumpower_attach(struct device *, struct device *, void *);
66 
67 struct plumpower_softc {
68 	struct	device		sc_dev;
69 	plum_chipset_tag_t	sc_pc;
70 	bus_space_tag_t		sc_regt;
71 	bus_space_handle_t	sc_regh;
72 };
73 
74 struct cfattach plumpower_ca = {
75 	sizeof(struct plumpower_softc), plumpower_match, plumpower_attach
76 };
77 
78 #ifdef PLUMPOWERDEBUG
79 static void	plumpower_dump(struct plumpower_softc *);
80 #endif
81 
82 int
83 plumpower_match(struct device *parent, struct cfdata *cf, void *aux)
84 {
85 	return 2; /* 1st attach group */
86 }
87 
88 void
89 plumpower_attach(struct device *parent, struct device *self, void *aux)
90 {
91 	struct plum_attach_args *pa = aux;
92 	struct plumpower_softc *sc = (void*)self;
93 
94 	printf("\n");
95 	sc->sc_pc	= pa->pa_pc;
96 	sc->sc_regt	= pa->pa_regt;
97 
98 	if (bus_space_map(sc->sc_regt, PLUM_POWER_REGBASE,
99 			  PLUM_POWER_REGSIZE, 0, &sc->sc_regh)) {
100 		printf(": register map failed\n");
101 		return;
102 	}
103 	plum_conf_register_power(sc->sc_pc, (void*)sc);
104 #ifdef PLUMPOWERDEBUG
105 	plumpower_dump(sc);
106 #endif
107 	/* disable all power/clock */
108 	plum_conf_write(sc->sc_regt, sc->sc_regh,
109 			PLUM_POWER_PWRCONT_REG, 0);
110 	plum_conf_write(sc->sc_regt, sc->sc_regh,
111 			PLUM_POWER_CLKCONT_REG, 0);
112 
113 	/* enable MCS interface from TX3922 */
114 	plum_conf_write(sc->sc_regt, sc->sc_regh, PLUM_POWER_INPENA_REG,
115 			PLUM_POWER_INPENA);
116 }
117 
118 void
119 plum_power_ioreset(plum_chipset_tag_t pc)
120 {
121 	struct plumpower_softc *sc = pc->pc_powert;
122 	bus_space_tag_t regt = sc->sc_regt;
123 	bus_space_handle_t regh = sc->sc_regh;
124 
125 	plum_conf_write(regt, regh, PLUM_POWER_RESETC_REG,
126 			PLUM_POWER_RESETC_IO5CL1 |
127 			PLUM_POWER_RESETC_IO5CL1);
128 	plum_conf_write(regt, regh, PLUM_POWER_RESETC_REG, 0);
129 }
130 
131 void*
132 plum_power_establish(plum_chipset_tag_t pc, int src)
133 {
134 	struct plumpower_softc *sc = pc->pc_powert;
135 	bus_space_tag_t regt = sc->sc_regt;
136 	bus_space_handle_t regh = sc->sc_regh;
137 	plumreg_t pwrreg, clkreg;
138 
139 	pwrreg = plum_conf_read(regt, regh, PLUM_POWER_PWRCONT_REG);
140 	clkreg = plum_conf_read(regt, regh, PLUM_POWER_CLKCONT_REG);
141 
142 	switch(src) {
143 	default:
144 		panic("plum_power_establish: unknown power source");
145 	case PLUM_PWR_LCD:
146 		pwrreg |= PLUM_POWER_PWRCONT_LCDPWR;
147 		plum_conf_write(regt, regh, PLUM_POWER_PWRCONT_REG, pwrreg);
148 		pwrreg |= PLUM_POWER_PWRCONT_LCDDSP;
149 		plum_conf_write(regt, regh, PLUM_POWER_PWRCONT_REG, pwrreg);
150 		pwrreg |= PLUM_POWER_PWRCONT_LCDOE;
151 		break;
152 	case PLUM_PWR_BKL:
153 		pwrreg |= PLUM_POWER_PWRCONT_BKLIGHT;
154 		break;
155 	case PLUM_PWR_IO5:
156 		/* reset I/O bus (High/Low) */
157 		plum_power_ioreset(pc);
158 
159 		/* supply power */
160 		pwrreg |= PLUM_POWER_PWRCONT_IO5PWR;
161 		plum_conf_write(regt, regh, PLUM_POWER_PWRCONT_REG, pwrreg);
162 
163 		/* output enable & supply clock */
164 		pwrreg |= PLUM_POWER_PWRCONT_IO5OE;
165 		clkreg |= PLUM_POWER_CLKCONT_IO5CLK;
166 		break;
167 	case PLUM_PWR_EXTPW0:
168 		pwrreg |= PLUM_POWER_PWRCONT_EXTPW0;
169 		break;
170 	case PLUM_PWR_EXTPW1:
171 		pwrreg |= PLUM_POWER_PWRCONT_EXTPW1;
172 		break;
173 	case PLUM_PWR_EXTPW2:
174 		pwrreg |= PLUM_POWER_PWRCONT_EXTPW2;
175 		break;
176 	case PLUM_PWR_USB:
177 		/* output enable */
178 		pwrreg |= PLUM_POWER_PWRCONT_USBEN;
179 		/* supply clock to the USB host controller */
180 		clkreg |= PLUM_POWER_CLKCONT_USBCLK1;
181 		/*
182 		 * clock supply is adaptively controlled by hardware
183 		 * (recommended)
184 		 */
185 		clkreg &= ~PLUM_POWER_CLKCONT_USBCLK2;
186 		break;
187 	case PLUM_PWR_SM:
188 		clkreg |= PLUM_POWER_CLKCONT_SMCLK;
189 		break;
190 	case PLUM_PWR_PCC1:
191 		clkreg |= PLUM_POWER_CLKCONT_PCCCLK1;
192 		break;
193 	case PLUM_PWR_PCC2:
194 		clkreg |= PLUM_POWER_CLKCONT_PCCCLK2;
195 		break;
196 	}
197 
198 	plum_conf_write(regt, regh, PLUM_POWER_PWRCONT_REG, pwrreg);
199 	plum_conf_write(regt, regh, PLUM_POWER_CLKCONT_REG, clkreg);
200 #ifdef PLUMPOWERDEBUG
201 	plumpower_dump(sc);
202 #endif
203 	return (void*)src;
204 }
205 
206 void
207 plum_power_disestablish(plum_chipset_tag_t pc, int ph)
208 {
209 	struct plumpower_softc *sc = pc->pc_powert;
210 	bus_space_tag_t regt = sc->sc_regt;
211 	bus_space_handle_t regh = sc->sc_regh;
212 	int src = (int)ph;
213 	plumreg_t pwrreg, clkreg;
214 
215 	pwrreg = plum_conf_read(regt, regh, PLUM_POWER_PWRCONT_REG);
216 	clkreg = plum_conf_read(regt, regh, PLUM_POWER_CLKCONT_REG);
217 
218 	switch(src) {
219 	default:
220 		panic("plum_power_disestablish: unknown power source");
221 	case PLUM_PWR_LCD:
222 		pwrreg &= ~PLUM_POWER_PWRCONT_LCDOE;
223 		plum_conf_write(regt, regh, PLUM_POWER_PWRCONT_REG, pwrreg);
224 		pwrreg &= ~PLUM_POWER_PWRCONT_LCDDSP;
225 		plum_conf_write(regt, regh, PLUM_POWER_PWRCONT_REG, pwrreg);
226 		pwrreg &= ~PLUM_POWER_PWRCONT_LCDPWR;
227 		break;
228 	case PLUM_PWR_BKL:
229 		pwrreg &= ~PLUM_POWER_PWRCONT_BKLIGHT;
230 		break;
231 	case PLUM_PWR_IO5:
232 		pwrreg &= ~(PLUM_POWER_PWRCONT_IO5PWR |
233 			   PLUM_POWER_PWRCONT_IO5OE);
234 		clkreg &= ~PLUM_POWER_CLKCONT_IO5CLK;
235 		break;
236 	case PLUM_PWR_EXTPW0:
237 		pwrreg &= ~PLUM_POWER_PWRCONT_EXTPW0;
238 		break;
239 	case PLUM_PWR_EXTPW1:
240 		pwrreg &= ~PLUM_POWER_PWRCONT_EXTPW1;
241 		break;
242 	case PLUM_PWR_EXTPW2:
243 		pwrreg &= ~PLUM_POWER_PWRCONT_EXTPW2;
244 		break;
245 	case PLUM_PWR_USB:
246 		pwrreg &= ~PLUM_POWER_PWRCONT_USBEN;
247 		clkreg &= ~(PLUM_POWER_CLKCONT_USBCLK1 |
248 			   PLUM_POWER_CLKCONT_USBCLK2);
249 		break;
250 	case PLUM_PWR_SM:
251 		clkreg &= ~PLUM_POWER_CLKCONT_SMCLK;
252 		break;
253 	case PLUM_PWR_PCC1:
254 		clkreg &= ~PLUM_POWER_CLKCONT_PCCCLK1;
255 		break;
256 	case PLUM_PWR_PCC2:
257 		clkreg &= ~PLUM_POWER_CLKCONT_PCCCLK2;
258 		break;
259 	}
260 
261 	plum_conf_write(regt, regh, PLUM_POWER_PWRCONT_REG, pwrreg);
262 	plum_conf_write(regt, regh, PLUM_POWER_CLKCONT_REG, clkreg);
263 #ifdef PLUMPOWERDEBUG
264 	plumpower_dump(sc);
265 #endif
266 }
267 
268 #ifdef PLUMPOWERDEBUG
269 #define ISPOWERSUPPLY(r, m) __is_set_print(r, PLUM_POWER_PWRCONT_##m, #m)
270 #define ISCLOCKSUPPLY(r, m) __is_set_print(r, PLUM_POWER_CLKCONT_##m, #m)
271 static void
272 plumpower_dump(struct plumpower_softc *sc)
273 {
274 	bus_space_tag_t regt = sc->sc_regt;
275 	bus_space_handle_t regh = sc->sc_regh;
276 	plumreg_t reg;
277 
278 	reg = plum_conf_read(regt, regh, PLUM_POWER_PWRCONT_REG);
279 	printf(" power:");
280 	ISPOWERSUPPLY(reg, USBEN);
281 	ISPOWERSUPPLY(reg, IO5OE);
282 	ISPOWERSUPPLY(reg, LCDOE);
283 	ISPOWERSUPPLY(reg, EXTPW2);
284 	ISPOWERSUPPLY(reg, EXTPW1);
285 	ISPOWERSUPPLY(reg, EXTPW0);
286 	ISPOWERSUPPLY(reg, IO5PWR);
287 	ISPOWERSUPPLY(reg, BKLIGHT);
288 	ISPOWERSUPPLY(reg, LCDPWR);
289 	ISPOWERSUPPLY(reg, LCDDSP);
290 	reg = plum_conf_read(regt, regh, PLUM_POWER_CLKCONT_REG);
291 	printf("\n clock:");
292 	ISCLOCKSUPPLY(reg, USBCLK2);
293 	ISCLOCKSUPPLY(reg, USBCLK1);
294 	ISCLOCKSUPPLY(reg, IO5CLK);
295 	ISCLOCKSUPPLY(reg, SMCLK);
296 	ISCLOCKSUPPLY(reg, PCCCLK2);
297 	ISCLOCKSUPPLY(reg, PCCCLK1);
298 	reg = plum_conf_read(regt, regh, PLUM_POWER_INPENA_REG);
299 	printf("\n MCS interface %sebled",
300 	       reg & PLUM_POWER_INPENA ? "en" : "dis");
301 	reg = plum_conf_read(regt, regh, PLUM_POWER_RESETC_REG);
302 	printf("\n IO5 reset:%s %s",
303 	       reg & PLUM_POWER_RESETC_IO5CL0 ? "CLRL" : "",
304 	       reg & PLUM_POWER_RESETC_IO5CL1 ? "CLRH" : "");
305 	printf("\n");
306 }
307 #endif /* PLUMPOWERDEBUG */
308 
309