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