[BACK]Return to pxa2x0_apm.c CVS log [TXT][DIR] Up to [local] / sys / arch / arm / xscale

Annotation of sys/arch/arm/xscale/pxa2x0_apm.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: pxa2x0_apm.c,v 1.28 2007/03/29 18:42:38 uwe Exp $     */
                      2:
                      3: /*-
                      4:  * Copyright (c) 2001 Alexander Guy.  All rights reserved.
                      5:  * Copyright (c) 1998-2001 Michael Shalayeff. All rights reserved.
                      6:  * Copyright (c) 1995 John T. Kohl.  All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *     This product includes software developed by the University of
                     19:  *     California, Berkeley and its contributors.
                     20:  * 4. Neither the name of the University nor the names of its contributors
                     21:  *    may be used to endorse or promote products derived from this software
                     22:  *    without specific prior written permission.
                     23:  *
                     24:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     26:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     27:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     28:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     29:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     30:  * OR SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     32:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     33:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     34:  * SUCH DAMAGE.
                     35:  *
                     36:  */
                     37:
                     38: #include <sys/param.h>
                     39: #include <sys/systm.h>
                     40: #include <sys/kernel.h>
                     41: #include <sys/kthread.h>
                     42: #include <sys/lock.h>
                     43: #include <sys/mount.h>         /* for vfs_syncwait() */
                     44: #include <sys/proc.h>
                     45: #include <sys/device.h>
                     46: #include <sys/fcntl.h>
                     47: #include <sys/ioctl.h>
                     48: #include <sys/event.h>
                     49:
                     50: #include <machine/conf.h>
                     51: #include <machine/cpu.h>
                     52: #include <machine/apmvar.h>
                     53:
                     54: #include <arm/xscale/pxa2x0reg.h>
                     55: #include <arm/xscale/pxa2x0var.h>
                     56: #include <arm/xscale/pxa2x0_apm.h>
                     57: #include <arm/xscale/pxa2x0_gpio.h>
                     58:
                     59: #if defined(APMDEBUG)
                     60: #define DPRINTF(x)     printf x
                     61: #else
                     62: #define        DPRINTF(x)      /**/
                     63: #endif
                     64:
                     65: #define APM_LOCK(sc)    lockmgr(&(sc)->sc_lock, LK_EXCLUSIVE, NULL)
                     66: #define APM_UNLOCK(sc)  lockmgr(&(sc)->sc_lock, LK_RELEASE, NULL)
                     67:
                     68: struct cfdriver apm_cd = {
                     69:        NULL, "apm", DV_DULL
                     70: };
                     71:
                     72: #define        APMUNIT(dev)    (minor(dev)&0xf0)
                     73: #define        APMDEV(dev)     (minor(dev)&0x0f)
                     74: #define APMDEV_NORMAL  0
                     75: #define APMDEV_CTL     8
                     76:
                     77: int    apm_userstandbys;
                     78: int    apm_suspends;
                     79: int    apm_battlow;
                     80:
                     81: /* battery percentage at which we get verbose in our warnings.  This
                     82:    value can be changed using sysctl(8), value machdep.apmwarn.
                     83:    Setting it to zero kills all warnings */
                     84: int    cpu_apmwarn = 10;
                     85:
                     86: void   apm_power_print(struct pxa2x0_apm_softc *, struct apm_power_info *);
                     87: void   apm_power_info(struct pxa2x0_apm_softc *, struct apm_power_info *);
                     88: void   apm_suspend(struct pxa2x0_apm_softc *);
                     89: void   apm_resume(struct pxa2x0_apm_softc *);
                     90: int    apm_get_event(struct pxa2x0_apm_softc *, u_int *);
                     91: int    apm_handle_event(struct pxa2x0_apm_softc *, u_int);
                     92: void   apm_thread_create(void *);
                     93: void   apm_thread(void *);
                     94:
                     95: extern int perflevel;
                     96: int    freq;
                     97: void   pxa2x0_setperf(int speed);
                     98: int    pxa2x0_cpuspeed(int *speed);
                     99:
                    100: int    apm_record_event(struct pxa2x0_apm_softc *, u_int);
                    101: void   filt_apmrdetach(struct knote *kn);
                    102: int    filt_apmread(struct knote *kn, long hint);
                    103: int    apmkqfilter(dev_t dev, struct knote *kn);
                    104:
                    105: struct filterops apmread_filtops =
                    106:        { 1, NULL, filt_apmrdetach, filt_apmread};
                    107:
                    108: /*
                    109:  * Flags to control kernel display
                    110:  *     SCFLAG_NOPRINT:         do not output APM power messages due to
                    111:  *                             a power change event.
                    112:  *
                    113:  *     SCFLAG_PCTPRINT:        do not output APM power messages due to
                    114:  *                             to a power change event unless the battery
                    115:  *                             percentage changes.
                    116:  */
                    117:
                    118: #define SCFLAG_NOPRINT 0x0008000
                    119: #define SCFLAG_PCTPRINT        0x0004000
                    120: #define SCFLAG_PRINT   (SCFLAG_NOPRINT|SCFLAG_PCTPRINT)
                    121:
                    122: #define        SCFLAG_OREAD    (1 << 0)
                    123: #define        SCFLAG_OWRITE   (1 << 1)
                    124: #define        SCFLAG_OPEN     (SCFLAG_OREAD|SCFLAG_OWRITE)
                    125:
                    126: /* This structure must be kept in sync with pxa2x0_apm_asm.S. */
                    127: struct pxa2x0_memcfg {
                    128:        /* SDRAM refresh */
                    129:        u_int32_t mdrefr_high;          /* 0x00 */
                    130:        u_int32_t mdrefr_low;           /* 0x04 */
                    131:        u_int32_t mdrefr_low2;          /* 0x08 */
                    132:        /* Synchronous, static, or VLIO interfaces */
                    133:        u_int32_t msc_high[3];          /* 0x0c */
                    134:        u_int32_t msc_low[3];           /* 0x18 */
                    135:        /* XXX move up */
                    136:        u_int32_t mdrefr_91;            /* 0x24 */
                    137: };
                    138:
                    139: /* XXX */
                    140: #define MDREFR_C3000   (MDREFR_K0DB2 | MDREFR_E1PIN | MDREFR_K1RUN | \
                    141:                         MDREFR_K1DB2 | MDREFR_K2DB2 | MDREFR_APD)
                    142: #define MSC0_HIGH \
                    143:                ( 7 << MSC_RRR_SHIFT << 16) | \
                    144:                (15 << MSC_RDN_SHIFT << 16) | \
                    145:                (15 << MSC_RDF_SHIFT << 16) | \
                    146:                (MSC_RT_NONBURST     << 16) | \
                    147:                ( 2 << MSC_RRR_SHIFT)       | \
                    148:                (13 << MSC_RDN_SHIFT)       | \
                    149:                (13 << MSC_RDF_SHIFT)       | \
                    150:                MSC_RBW /* PXA271 */        | \
                    151:                MSC_RT_NONBURST
                    152: #define MSC1_HIGH \
                    153:                ( 7 << MSC_RRR_SHIFT << 16) | \
                    154:                (15 << MSC_RDN_SHIFT << 16) | \
                    155:                (15 << MSC_RDF_SHIFT << 16) | \
                    156:                (MSC_RT_VLIO         << 16) | \
                    157:                ( 3 << MSC_RRR_SHIFT)       | \
                    158:                ( 4 << MSC_RDN_SHIFT)       | \
                    159:                (13 << MSC_RDF_SHIFT)       | \
                    160:                MSC_RT_VLIO
                    161: #define MSC2_HIGH \
                    162:                ( 7 << MSC_RRR_SHIFT << 16) | \
                    163:                (15 << MSC_RDN_SHIFT << 16) | \
                    164:                (15 << MSC_RDF_SHIFT << 16) | \
                    165:                (MSC_RT_NONBURST     << 16) | \
                    166:                ( 3 << MSC_RRR_SHIFT)       | \
                    167:                ( 4 << MSC_RDN_SHIFT)       | \
                    168:                (13 << MSC_RDF_SHIFT)       | \
                    169:                MSC_RT_VLIO
                    170: #define MSC0_LOW \
                    171:                ( 7 << MSC_RRR_SHIFT << 16) | \
                    172:                (15 << MSC_RDN_SHIFT << 16) | \
                    173:                (15 << MSC_RDF_SHIFT << 16) | \
                    174:                (MSC_RT_NONBURST     << 16) | \
                    175:                ( 1 << MSC_RRR_SHIFT)       | \
                    176:                ( 8 << MSC_RDN_SHIFT)       | \
                    177:                ( 8 << MSC_RDF_SHIFT)       | \
                    178:                MSC_RBW /* PXA271 */        | \
                    179:                MSC_RT_NONBURST
                    180: #define MSC1_LOW \
                    181:                ( 7 << MSC_RRR_SHIFT << 16) | \
                    182:                (15 << MSC_RDN_SHIFT << 16) | \
                    183:                (15 << MSC_RDF_SHIFT << 16) | \
                    184:                (MSC_RT_VLIO         << 16) | \
                    185:                ( 1 << MSC_RRR_SHIFT)       | \
                    186:                ( 2 << MSC_RDN_SHIFT)       | \
                    187:                ( 6 << MSC_RDF_SHIFT)       | \
                    188:                MSC_RT_VLIO
                    189: #define MSC2_LOW \
                    190:                ( 7 << MSC_RRR_SHIFT << 16) | \
                    191:                (15 << MSC_RDN_SHIFT << 16) | \
                    192:                (15 << MSC_RDF_SHIFT << 16) | \
                    193:                (MSC_RT_NONBURST     << 16) | \
                    194:                ( 1 << MSC_RRR_SHIFT)       | \
                    195:                ( 2 << MSC_RDN_SHIFT)       | \
                    196:                ( 6 << MSC_RDF_SHIFT)       | \
                    197:                MSC_RT_VLIO
                    198: struct pxa2x0_memcfg pxa2x0_memcfg = {
                    199:        (MDREFR_C3000 | 0x030),
                    200:        (MDREFR_C3000 | 0x00b),
                    201:        (MDREFR_C3000 | 0x017),
                    202:        { MSC0_HIGH, MSC1_HIGH, MSC2_HIGH },
                    203:        { MSC1_LOW, MSC1_LOW, MSC2_LOW },
                    204:        (MDREFR_C3000 | 0x013)
                    205: };
                    206:
                    207: #define PI2C_RETRY_COUNT       10
                    208: /* XXX varies depending on voltage regulator IC. */
                    209: #define PI2C_VOLTAGE_LOW       0x13    /* 1.00V */
                    210: #define PI2C_VOLTAGE_HIGH      0x1a    /* 1.35V */
                    211:
                    212: void   pxa2x0_pi2c_open(bus_space_tag_t, bus_space_handle_t);
                    213: void   pxa2x0_pi2c_close(bus_space_tag_t, bus_space_handle_t);
                    214: int    pxa2x0_pi2c_read(bus_space_tag_t, bus_space_handle_t, u_char, u_char *);
                    215: int    pxa2x0_pi2c_write(bus_space_tag_t, bus_space_handle_t, u_char, u_char);
                    216: int    pxa2x0_pi2c_getvoltage(bus_space_tag_t, bus_space_handle_t, u_char *);
                    217: int    pxa2x0_pi2c_setvoltage(bus_space_tag_t, bus_space_handle_t, u_char);
                    218: #if 0
                    219: void   pxa2x0_pi2c_print(struct pxa2x0_apm_softc *);
                    220: #endif
                    221:
                    222: /* XXX used in pxa2x0_apm_asm.S */
                    223: bus_space_handle_t pxa2x0_gpio_ioh;
                    224: bus_space_handle_t pxa2x0_clkman_ioh;
                    225: bus_space_handle_t pxa2x0_memctl_ioh;
                    226:
                    227: /* pxa2x0_apm_asm.S */
                    228: void   pxa27x_run_mode(void);
                    229: void   pxa27x_fastbus_run_mode(int, u_int32_t);
                    230: void   pxa27x_frequency_change(int, int, struct pxa2x0_memcfg *);
                    231: void   pxa2x0_cpu_suspend(void);
                    232: void   pxa2x0_cpu_resume(void);
                    233: void   pxa27x_cpu_speed_high(void);
                    234: void   pxa27x_cpu_speed_low(void);
                    235: void   pxa27x_cpu_speed_91(void);
                    236: void   pxa27x_cpu_speed_208(void);
                    237:
                    238: void
                    239: apm_power_print(struct pxa2x0_apm_softc *sc, struct apm_power_info *powerp)
                    240: {
                    241:
                    242:        if (powerp->battery_life != APM_BATT_LIFE_UNKNOWN)
                    243:                printf("%s: battery life expectancy %d%%\n",
                    244:                    sc->sc_dev.dv_xname, powerp->battery_life);
                    245:
                    246:        printf("%s: AC ", sc->sc_dev.dv_xname);
                    247:        switch (powerp->ac_state) {
                    248:        case APM_AC_OFF:
                    249:                printf("off,");
                    250:                break;
                    251:        case APM_AC_ON:
                    252:                printf("on,");
                    253:                break;
                    254:        case APM_AC_BACKUP:
                    255:                printf("backup power,");
                    256:                break;
                    257:        default:
                    258:        case APM_AC_UNKNOWN:
                    259:                printf("unknown,");
                    260:                break;
                    261:        }
                    262:
                    263:        printf(" battery is ");
                    264:        switch (powerp->battery_state) {
                    265:        case APM_BATT_HIGH:
                    266:                printf("high");
                    267:                break;
                    268:        case APM_BATT_LOW:
                    269:                printf("low");
                    270:                break;
                    271:        case APM_BATT_CRITICAL:
                    272:                printf("CRITICAL");
                    273:                break;
                    274:        case APM_BATT_CHARGING:
                    275:                printf("charging");
                    276:                break;
                    277:        case APM_BATT_UNKNOWN:
                    278:                printf("unknown");
                    279:                break;
                    280:        default:
                    281:                printf("undecoded (%x)", powerp->battery_state);
                    282:                break;
                    283:        }
                    284:
                    285:        printf("\n");
                    286: }
                    287:
                    288: void
                    289: apm_power_info(struct pxa2x0_apm_softc *sc,
                    290:     struct apm_power_info *power)
                    291: {
                    292:
                    293:        power->ac_state = APM_AC_UNKNOWN;
                    294:        power->battery_state = APM_BATT_UNKNOWN;
                    295:        power->battery_life = 0 /* APM_BATT_LIFE_UNKNOWN */;
                    296:        power->minutes_left = 0;
                    297:
                    298:        if (sc->sc_power_info != NULL)
                    299:                sc->sc_power_info(sc, power);
                    300: }
                    301:
                    302: void
                    303: apm_suspend(struct pxa2x0_apm_softc *sc)
                    304: {
                    305:
                    306:        resettodr();
                    307:
                    308:        dopowerhooks(PWR_SUSPEND);
                    309:
                    310:        if (cold)
                    311:                vfs_syncwait(0);
                    312:
                    313:        if (sc->sc_suspend == NULL)
                    314:                pxa2x0_wakeup_config(PXA2X0_WAKEUP_ALL, 1);
                    315:        else
                    316:                sc->sc_suspend(sc);
                    317:
                    318:        pxa2x0_apm_sleep(sc);
                    319: }
                    320:
                    321: void
                    322: apm_resume(struct pxa2x0_apm_softc *sc)
                    323: {
                    324:
                    325:        dopowerhooks(PWR_RESUME);
                    326:
                    327:        inittodr(0);
                    328:
                    329:        /*
                    330:         * Clear the OTG Peripheral hold after running the pxaudc and pxaohci
                    331:         * powerhooks to re-enable their operation. See 3.8.1.2
                    332:         */
                    333:        /* XXX ifdef NPXAUDC > 0 */
                    334:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PSSR, PSSR_OTGPH);
                    335: }
                    336:
                    337: int
                    338: apm_get_event(struct pxa2x0_apm_softc *sc, u_int *typep)
                    339: {
                    340:
                    341:        if (sc->sc_get_event != NULL)
                    342:                return (sc->sc_get_event(sc, typep));
                    343:
                    344:        *typep = APM_NOEVENT;
                    345:        return (1);
                    346: }
                    347:
                    348: int
                    349: apm_handle_event(struct pxa2x0_apm_softc *sc, u_int type)
                    350: {
                    351:        struct  apm_power_info power;
                    352:        int     ret = 0;
                    353:
                    354:        switch (type) {
                    355:        case APM_NOEVENT:
                    356:                ret = 1;
                    357:                break;
                    358:        case APM_CRIT_SUSPEND_REQ:
                    359:                DPRINTF(("suspend required immediately\n"));
                    360: #if 0
                    361:                /* XXX apmd would make us suspend again after resume. */
                    362:                (void)apm_record_event(sc, type);
                    363: #endif
                    364:                /*
                    365:                 * We ignore APM_CRIT_RESUME and just suspend here as usual
                    366:                 * to simplify the actual apm_get_event() implementation.
                    367:                 */
                    368:                apm_suspends++;
                    369:                ret = 1;
                    370:                break;
                    371:        case APM_USER_SUSPEND_REQ:
                    372:        case APM_SUSPEND_REQ:
                    373:                DPRINTF(("suspend requested\n"));
                    374:                if (apm_record_event(sc, type)) {
                    375:                        DPRINTF(("suspend ourselves\n"));
                    376:                        apm_suspends++;
                    377:                }
                    378:                break;
                    379:        case APM_POWER_CHANGE:
                    380:                DPRINTF(("power status change\n"));
                    381:                apm_power_info(sc, &power);
                    382:                if (power.battery_life != APM_BATT_LIFE_UNKNOWN &&
                    383:                    power.battery_life < cpu_apmwarn &&
                    384:                    (sc->sc_flags & SCFLAG_PRINT) != SCFLAG_NOPRINT &&
                    385:                    ((sc->sc_flags & SCFLAG_PRINT) != SCFLAG_PCTPRINT ||
                    386:                    sc->sc_batt_life != power.battery_life)) {
                    387:                        sc->sc_batt_life = power.battery_life;
                    388:                        apm_power_print(sc, &power);
                    389:                }
                    390:                apm_record_event(sc, type);
                    391:                break;
                    392:        case APM_BATTERY_LOW:
                    393:                DPRINTF(("Battery low!\n"));
                    394:                apm_battlow++;
                    395:                apm_record_event(sc, type);
                    396:                break;
                    397:        default:
                    398:                DPRINTF(("apm_handle_event: unsupported event, code %d\n",
                    399:                    type));
                    400:        }
                    401:
                    402:        return (ret);
                    403: }
                    404:
                    405: void
                    406: apm_thread_create(void *v)
                    407: {
                    408:        struct pxa2x0_apm_softc *sc = v;
                    409:
                    410:        if (kthread_create(apm_thread, sc, &sc->sc_thread,
                    411:            "%s", sc->sc_dev.dv_xname)) {
                    412:                /* apm_disconnect(sc); */
                    413:                printf("%s: failed to create kernel thread, disabled",
                    414:                    sc->sc_dev.dv_xname);
                    415:        }
                    416: }
                    417:
                    418: void
                    419: apm_thread(void *v)
                    420: {
                    421:        struct pxa2x0_apm_softc *sc = v;
                    422:        u_int   type;
                    423:
                    424:        for (;;) {
                    425:                APM_LOCK(sc);
                    426:
                    427:                while (1) {
                    428:                        if (apm_get_event(sc, &type) != 0)
                    429:                                break;
                    430:                        if (apm_handle_event(sc, type) != 0)
                    431:                                break;
                    432:                }
                    433:                if (apm_suspends || apm_userstandbys /* || apm_battlow*/) {
                    434:                        apm_suspend(sc);
                    435:                        apm_resume(sc);
                    436:                }
                    437:                apm_battlow = apm_suspends = apm_userstandbys = 0;
                    438:
                    439:                APM_UNLOCK(sc);
                    440:                tsleep(&lbolt, PWAIT, "apmev", 0);
                    441:        }
                    442: }
                    443:
                    444: int
                    445: apmopen(dev_t dev, int flag, int mode, struct proc *p)
                    446: {
                    447:        struct pxa2x0_apm_softc *sc;
                    448:        int error = 0;
                    449:
                    450:        /* apm0 only */
                    451:        if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 ||
                    452:            !(sc = apm_cd.cd_devs[APMUNIT(dev)]))
                    453:                return (ENXIO);
                    454:
                    455:        DPRINTF(("apmopen: dev %d pid %d flag %x mode %x\n",
                    456:            APMDEV(dev), p->p_pid, flag, mode));
                    457:
                    458:        switch (APMDEV(dev)) {
                    459:        case APMDEV_CTL:
                    460:                if (!(flag & FWRITE)) {
                    461:                        error = EINVAL;
                    462:                        break;
                    463:                }
                    464:                if (sc->sc_flags & SCFLAG_OWRITE) {
                    465:                        error = EBUSY;
                    466:                        break;
                    467:                }
                    468:                sc->sc_flags |= SCFLAG_OWRITE;
                    469:                break;
                    470:        case APMDEV_NORMAL:
                    471:                if (!(flag & FREAD) || (flag & FWRITE)) {
                    472:                        error = EINVAL;
                    473:                        break;
                    474:                }
                    475:                sc->sc_flags |= SCFLAG_OREAD;
                    476:                break;
                    477:        default:
                    478:                error = ENXIO;
                    479:                break;
                    480:        }
                    481:        return (error);
                    482: }
                    483:
                    484: int
                    485: apmclose(dev_t dev, int flag, int mode, struct proc *p)
                    486: {
                    487:        struct pxa2x0_apm_softc *sc;
                    488:
                    489:        /* apm0 only */
                    490:        if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 ||
                    491:            !(sc = apm_cd.cd_devs[APMUNIT(dev)]))
                    492:                return (ENXIO);
                    493:
                    494:        DPRINTF(("apmclose: pid %d flag %x mode %x\n", p->p_pid, flag, mode));
                    495:
                    496:        switch (APMDEV(dev)) {
                    497:        case APMDEV_CTL:
                    498:                sc->sc_flags &= ~SCFLAG_OWRITE;
                    499:                break;
                    500:        case APMDEV_NORMAL:
                    501:                sc->sc_flags &= ~SCFLAG_OREAD;
                    502:                break;
                    503:        }
                    504:        return (0);
                    505: }
                    506:
                    507: int
                    508: apmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
                    509: {
                    510:        struct pxa2x0_apm_softc *sc;
                    511:        struct apm_power_info *power;
                    512:        int error = 0;
                    513:
                    514:        /* apm0 only */
                    515:        if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 ||
                    516:            !(sc = apm_cd.cd_devs[APMUNIT(dev)]))
                    517:                return (ENXIO);
                    518:
                    519:        switch (cmd) {
                    520:                /* some ioctl names from linux */
                    521:        case APM_IOC_STANDBY:
                    522:                if ((flag & FWRITE) == 0)
                    523:                        error = EBADF;
                    524:                else
                    525:                        apm_userstandbys++;
                    526:                break;
                    527:        case APM_IOC_SUSPEND:
                    528:                if ((flag & FWRITE) == 0)
                    529:                        error = EBADF;
                    530:                else
                    531:                        apm_suspends++; /* XXX */
                    532:                break;
                    533:        case APM_IOC_PRN_CTL:
                    534:                if ((flag & FWRITE) == 0)
                    535:                        error = EBADF;
                    536:                else {
                    537:                        int flag = *(int *)data;
                    538:                        DPRINTF(( "APM_IOC_PRN_CTL: %d\n", flag ));
                    539:                        switch (flag) {
                    540:                        case APM_PRINT_ON:      /* enable printing */
                    541:                                sc->sc_flags &= ~SCFLAG_PRINT;
                    542:                                break;
                    543:                        case APM_PRINT_OFF: /* disable printing */
                    544:                                sc->sc_flags &= ~SCFLAG_PRINT;
                    545:                                sc->sc_flags |= SCFLAG_NOPRINT;
                    546:                                break;
                    547:                        case APM_PRINT_PCT: /* disable some printing */
                    548:                                sc->sc_flags &= ~SCFLAG_PRINT;
                    549:                                sc->sc_flags |= SCFLAG_PCTPRINT;
                    550:                                break;
                    551:                        default:
                    552:                                error = EINVAL;
                    553:                                break;
                    554:                        }
                    555:                }
                    556:                break;
                    557:        case APM_IOC_DEV_CTL:
                    558:                if ((flag & FWRITE) == 0)
                    559:                        error = EBADF;
                    560:                break;
                    561:        case APM_IOC_GETPOWER:
                    562:                power = (struct apm_power_info *)data;
                    563:                apm_power_info(sc, power);
                    564:                break;
                    565:
                    566:        default:
                    567:                error = ENOTTY;
                    568:        }
                    569:
                    570:        return (error);
                    571: }
                    572:
                    573: int
                    574: apm_record_event(struct pxa2x0_apm_softc *sc, u_int type)
                    575: {
                    576:        static int apm_evindex;
                    577:
                    578:        /* skip if no user waiting */
                    579:        if ((sc->sc_flags & SCFLAG_OPEN) == 0)
                    580:                return (1);
                    581:
                    582:        apm_evindex++;
                    583:        KNOTE(&sc->sc_note, APM_EVENT_COMPOSE(type, apm_evindex));
                    584:
                    585:        return (0);
                    586: }
                    587:
                    588: void
                    589: filt_apmrdetach(struct knote *kn)
                    590: {
                    591:        struct pxa2x0_apm_softc *sc =
                    592:            (struct pxa2x0_apm_softc *)kn->kn_hook;
                    593:
                    594:        SLIST_REMOVE(&sc->sc_note, kn, knote, kn_selnext);
                    595: }
                    596:
                    597: int
                    598: filt_apmread(struct knote *kn, long hint)
                    599: {
                    600:        /* XXX weird kqueue_scan() semantics */
                    601:        if (hint && !kn->kn_data)
                    602:                kn->kn_data = (int)hint;
                    603:
                    604:        return (1);
                    605: }
                    606:
                    607: int
                    608: apmkqfilter(dev_t dev, struct knote *kn)
                    609: {
                    610:        struct pxa2x0_apm_softc *sc;
                    611:
                    612:        /* apm0 only */
                    613:        if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 ||
                    614:            !(sc = apm_cd.cd_devs[APMUNIT(dev)]))
                    615:                return (ENXIO);
                    616:
                    617:        switch (kn->kn_filter) {
                    618:        case EVFILT_READ:
                    619:                kn->kn_fop = &apmread_filtops;
                    620:                break;
                    621:        default:
                    622:                return (1);
                    623:        }
                    624:
                    625:        kn->kn_hook = (caddr_t)sc;
                    626:        SLIST_INSERT_HEAD(&sc->sc_note, kn, kn_selnext);
                    627:
                    628:        return (0);
                    629: }
                    630:
                    631: void
                    632: pxa2x0_apm_attach_sub(struct pxa2x0_apm_softc *sc)
                    633: {
                    634:
                    635:        sc->sc_iot = &pxa2x0_bs_tag;
                    636:
                    637:        if (bus_space_map(sc->sc_iot, PXA2X0_POWMAN_BASE,
                    638:            PXA2X0_POWMAN_SIZE, 0, &sc->sc_pm_ioh)) {
                    639:                printf("pxa2x0_apm_attach_sub: failed to map POWMAN\n");
                    640:                return;
                    641:        }
                    642:
                    643:        lockinit(&sc->sc_lock, PWAIT, "apmlk", 0, 0);
                    644:
                    645:        kthread_create_deferred(apm_thread_create, sc);
                    646:
                    647:        printf("\n");
                    648:
                    649:        if (bus_space_map(sc->sc_iot, PXA2X0_CLKMAN_BASE, PXA2X0_CLKMAN_SIZE,
                    650:            0, &pxa2x0_clkman_ioh)) {
                    651:                printf("%s: failed to map CLKMAN\n", sc->sc_dev.dv_xname);
                    652:                return;
                    653:        }
                    654:
                    655:        if (bus_space_map(sc->sc_iot, PXA2X0_MEMCTL_BASE, PXA2X0_MEMCTL_SIZE,
                    656:            0, &pxa2x0_memctl_ioh)) {
                    657:                printf("%s: failed to map MEMCTL\n", sc->sc_dev.dv_xname);
                    658:                return;
                    659:        }
                    660:        sc->sc_memctl_ioh = pxa2x0_memctl_ioh;
                    661:
                    662:        if (bus_space_map(sc->sc_iot, PXA2X0_GPIO_BASE, PXA2X0_GPIO_SIZE,
                    663:            0, &pxa2x0_gpio_ioh)) {
                    664:                printf("%s: can't map GPIO\n", sc->sc_dev.dv_xname);
                    665:                return;
                    666:        }
                    667:
                    668:        /* Clear all reset status flags. */
                    669:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_RCSR,
                    670:            RCSR_GPR | RCSR_SMR | RCSR_WDR | RCSR_HWR);
                    671: }
                    672:
                    673: void
                    674: pxa2x0_wakeup_config(u_int wsrc, int enable)
                    675: {
                    676:        struct pxa2x0_apm_softc *sc;
                    677:        u_int32_t prer;
                    678:        u_int32_t pfer;
                    679:        u_int32_t pkwr;
                    680:
                    681:        if (apm_cd.cd_ndevs < 1 || apm_cd.cd_devs[0] == NULL)
                    682:                return;
                    683:        sc = apm_cd.cd_devs[0];
                    684:
                    685:        prer = pfer = pkwr = 0;
                    686:
                    687:        if ((wsrc & PXA2X0_WAKEUP_POWERON) != 0) {
                    688:                prer |= (1<<0);
                    689:                pfer |= (1<<0);
                    690:                pkwr |= (1<<12); /* XXX */
                    691:        }
                    692:
                    693:        if ((wsrc & PXA2X0_WAKEUP_GPIORST) != 0)
                    694:                pfer |= (1<<1);
                    695:        if ((wsrc & PXA2X0_WAKEUP_SD) != 0)
                    696:                prer |= (1<<9);
                    697:        if ((wsrc & PXA2X0_WAKEUP_RC) != 0)
                    698:                prer |= (1<<13);
                    699:        if ((wsrc & PXA2X0_WAKEUP_SYNC) != 0)
                    700:                pkwr |= (1<<1);
                    701:        if ((wsrc & PXA2X0_WAKEUP_KEYNS0) != 0)
                    702:                prer |= (1<<12);
                    703:        if ((wsrc & PXA2X0_WAKEUP_KEYNS1) != 0)
                    704:                pkwr |= (1<<2);
                    705:        if ((wsrc & PXA2X0_WAKEUP_KEYNS2) != 0)
                    706:                pkwr |= (1<<9);
                    707:        if ((wsrc & PXA2X0_WAKEUP_KEYNS3) != 0)
                    708:                pkwr |= (1<<3);
                    709:        if ((wsrc & PXA2X0_WAKEUP_KEYNS4) != 0)
                    710:                pkwr |= (1<<4);
                    711:        if ((wsrc & PXA2X0_WAKEUP_KEYNS5) != 0)
                    712:                pkwr |= (1<<6);
                    713:        if ((wsrc & PXA2X0_WAKEUP_KEYNS6) != 0)
                    714:                pkwr |= (1<<7);
                    715:        if ((wsrc & PXA2X0_WAKEUP_CF0) != 0)
                    716:                pkwr |= (1<<11);
                    717:        if ((wsrc & PXA2X0_WAKEUP_CF1) != 0)
                    718:                pkwr |= (1<<10);
                    719:        if ((wsrc & PXA2X0_WAKEUP_USBD) != 0)
                    720:                prer |= (1<<24);
                    721:
                    722:        if ((wsrc & PXA2X0_WAKEUP_LOCKSW) != 0) {
                    723:                prer |= (1<<15);
                    724:                pfer |= (1<<15);
                    725:        }
                    726:
                    727:        if ((wsrc & PXA2X0_WAKEUP_JACKIN) != 0) {
                    728:                prer |= (1<<23);
                    729:                pfer |= (1<<23);
                    730:        }
                    731:
                    732:        if ((wsrc & PXA2X0_WAKEUP_CHRGFULL) != 0)
                    733:                pkwr |= (1<<18);
                    734:        if ((wsrc & PXA2X0_WAKEUP_RTC) != 0)
                    735:                prer |= (1<<31);
                    736:
                    737:        if (enable) {
                    738:                sc->sc_wakeon |= wsrc;
                    739:                prer |= bus_space_read_4(sc->sc_iot, sc->sc_pm_ioh,
                    740:                    POWMAN_PRER);
                    741:                pfer |= bus_space_read_4(sc->sc_iot, sc->sc_pm_ioh,
                    742:                    POWMAN_PFER);
                    743:                pkwr |= bus_space_read_4(sc->sc_iot, sc->sc_pm_ioh,
                    744:                    POWMAN_PKWR);
                    745:        } else {
                    746:                sc->sc_wakeon &= ~wsrc;
                    747:                prer = bus_space_read_4(sc->sc_iot, sc->sc_pm_ioh,
                    748:                    POWMAN_PRER) & ~prer;
                    749:                pfer = bus_space_read_4(sc->sc_iot, sc->sc_pm_ioh,
                    750:                    POWMAN_PFER) & ~pfer;
                    751:                pkwr = bus_space_read_4(sc->sc_iot, sc->sc_pm_ioh,
                    752:                    POWMAN_PKWR) & ~pkwr;
                    753:        }
                    754:
                    755:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PKWR, pkwr);
                    756:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PRER, prer);
                    757:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PFER, pfer);
                    758:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PWER,
                    759:            prer | pfer);
                    760: }
                    761:
                    762: u_int
                    763: pxa2x0_wakeup_status(void)
                    764: {
                    765:        struct pxa2x0_apm_softc *sc;
                    766:        u_int32_t rv;
                    767:        u_int   wsrc;
                    768:
                    769:        if (apm_cd.cd_ndevs < 1 || apm_cd.cd_devs[0] == NULL)
                    770:                return (0);
                    771:
                    772:        sc = apm_cd.cd_devs[0];
                    773:        wsrc = 0;
                    774:
                    775:        rv = bus_space_read_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PEDR);
                    776:        if ((rv & (1<<0)) != 0)
                    777:                wsrc |= PXA2X0_WAKEUP_POWERON;
                    778:        if ((rv & (1<<1)) != 0)
                    779:                wsrc |= PXA2X0_WAKEUP_GPIORST;
                    780:        if ((rv & (1<<9)) != 0)
                    781:                wsrc |= PXA2X0_WAKEUP_SD;
                    782:        if ((rv & (1<<12)) != 0)
                    783:                wsrc |= PXA2X0_WAKEUP_KEYNS0;
                    784:        if ((rv & (1<<13)) != 0)
                    785:                wsrc |= PXA2X0_WAKEUP_RC;
                    786:        if ((rv & (1<<15)) != 0)
                    787:                wsrc |= PXA2X0_WAKEUP_LOCKSW;
                    788:        if ((rv & (1<<23)) != 0)
                    789:                wsrc |= PXA2X0_WAKEUP_JACKIN;
                    790:        if ((rv & (1<<24)) != 0)
                    791:                wsrc |= PXA2X0_WAKEUP_USBD;
                    792:        if ((rv & (1<<31)) != 0)
                    793:                wsrc |= PXA2X0_WAKEUP_RTC;
                    794:
                    795:        rv = bus_space_read_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PKSR);
                    796:        if ((rv & (1<<1)) != 0)
                    797:                wsrc |= PXA2X0_WAKEUP_SYNC;
                    798:        if ((rv & (1<<2)) != 0)
                    799:                wsrc |= PXA2X0_WAKEUP_KEYNS1;
                    800:        if ((rv & (1<<9)) != 0)
                    801:                wsrc |= PXA2X0_WAKEUP_KEYNS2;
                    802:        if ((rv & (1<<3)) != 0)
                    803:                wsrc |= PXA2X0_WAKEUP_KEYNS3;
                    804:        if ((rv & (1<<4)) != 0)
                    805:                wsrc |= PXA2X0_WAKEUP_KEYNS4;
                    806:        if ((rv & (1<<6)) != 0)
                    807:                wsrc |= PXA2X0_WAKEUP_KEYNS5;
                    808:        if ((rv & (1<<7)) != 0)
                    809:                wsrc |= PXA2X0_WAKEUP_KEYNS6;
                    810:        if ((rv & (1<<10)) != 0)
                    811:                wsrc |= PXA2X0_WAKEUP_CF1;
                    812:        if ((rv & (1<<11)) != 0)
                    813:                wsrc |= PXA2X0_WAKEUP_CF0;
                    814:        if ((rv & (1<<12)) != 0)
                    815:                wsrc |= PXA2X0_WAKEUP_POWERON;
                    816:        if ((rv & (1<<18)) != 0)
                    817:                wsrc |= PXA2X0_WAKEUP_CHRGFULL;
                    818:
                    819:        return (wsrc);
                    820: }
                    821:
                    822: struct pxa2x0_sleep_data {
                    823:        /* OS timer registers */
                    824:        u_int32_t sd_osmr0, sd_osmr1, sd_osmr2, sd_osmr3;
                    825:        u_int32_t sd_oscr0;
                    826:        u_int32_t sd_osmr4, sd_osmr5;
                    827:        u_int32_t sd_oscr4;
                    828:        u_int32_t sd_omcr4, sd_omcr5;
                    829:        u_int32_t sd_oier;
                    830:        /* GPIO registers */
                    831:        u_int32_t sd_gpdr0, sd_gpdr1, sd_gpdr2, sd_gpdr3;
                    832:        u_int32_t sd_grer0, sd_grer1, sd_grer2, sd_grer3;
                    833:        u_int32_t sd_gfer0, sd_gfer1, sd_gfer2, sd_gfer3;
                    834:        u_int32_t sd_gafr0_l, sd_gafr1_l, sd_gafr2_l, sd_gafr3_l;
                    835:        u_int32_t sd_gafr0_u, sd_gafr1_u, sd_gafr2_u, sd_gafr3_u;
                    836:        u_int32_t sd_gplr0, sd_gplr1, sd_gplr2, sd_gplr3;
                    837:        /* Interrupt controller registers */
                    838:        u_int32_t sd_iclr;
                    839:        u_int32_t sd_icmr;
                    840:        u_int32_t sd_iccr;
                    841:        /* Memory controller registers */
                    842:        u_int32_t sd_mecr;
                    843:        u_int32_t sd_mcmem0, sd_mcmem1;
                    844:        u_int32_t sd_mcatt0, sd_mcatt1;
                    845:        u_int32_t sd_mcio0, sd_mcio1;
                    846:        /* Clocks manager registers */
                    847:        u_int32_t sd_cken;
                    848: };
                    849:
                    850: void
                    851: pxa2x0_apm_sleep(struct pxa2x0_apm_softc *sc)
                    852: {
                    853:        struct pxa2x0_sleep_data sd;
                    854:        bus_space_handle_t ost_ioh;
                    855:        int save;
                    856:        u_int32_t rv;
                    857:
                    858:        ost_ioh = (bus_space_handle_t)0;
                    859:        if (bus_space_map(sc->sc_iot, PXA2X0_OST_BASE, PXA2X0_OST_SIZE, 0,
                    860:            &ost_ioh)) {
                    861:                printf("pxa2x0_apm_sleep: can't map OST\n");
                    862:                goto out;
                    863:        }
                    864:
                    865:        save = disable_interrupts(I32_bit|F32_bit);
                    866:
                    867:        sd.sd_oscr0 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSCR0);
                    868:        sd.sd_oscr4 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSCR4);
                    869:        sd.sd_omcr4 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OMCR4);
                    870:        sd.sd_omcr5 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OMCR5);
                    871:        sd.sd_osmr0 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSMR0);
                    872:        sd.sd_osmr1 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSMR1);
                    873:        sd.sd_osmr2 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSMR2);
                    874:        sd.sd_osmr3 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSMR3);
                    875:        sd.sd_osmr4 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSMR4);
                    876:        sd.sd_osmr5 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSMR5);
                    877:        sd.sd_oier = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OIER);
                    878:
                    879:        /* Bring the PXA27x into 416MHz turbo mode. */
                    880:         if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X &&
                    881:            bus_space_read_4(sc->sc_iot, pxa2x0_clkman_ioh, CLKMAN_CCCR) !=
                    882:            (CCCR_A | CCCR_TURBO_X2 | CCCR_RUN_X16)) {
                    883: #if 0
                    884:                pxa27x_cpu_speed_high();
                    885: #else
                    886: #define CLKCFG_T               (1<<0)  /* turbo */
                    887: #define CLKCFG_F               (1<<1)  /* frequency change */
                    888: #define CLKCFG_B               (1<<3)  /* fast-bus */
                    889:                pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 |
                    890:                    CCCR_RUN_X16, CLKCFG_B | CLKCFG_F | CLKCFG_T,
                    891:                    &pxa2x0_memcfg);
                    892: #endif
                    893:                delay(500000); /* XXX */
                    894:        }
                    895:
                    896: suspend_again:
                    897:        /* Clear wake-up status. */
                    898:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PEDR,
                    899:            0xffffffff);
                    900:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PKSR,
                    901:            0xffffffff);
                    902:
                    903:        /* XXX control battery charging in sleep mode. */
                    904:
                    905:        /* XXX schedule RTC alarm to check the battery, or schedule
                    906:           XXX wake-up shortly before an already programmed alarm? */
                    907:
                    908:        pxa27x_run_mode();
                    909: #define MDREFR_LOW             (MDREFR_C3000 | 0x00b)
                    910:        pxa27x_fastbus_run_mode(0, MDREFR_LOW);
                    911:        delay(1);
                    912: #if 1
                    913:        pxa27x_cpu_speed_91();
                    914: #else
                    915:        pxa27x_frequency_change(CCCR_TURBO_X1 | CCCR_RUN_X7, CLKCFG_F,
                    916:            &pxa2x0_memcfg);
                    917: #endif
                    918:        pxa2x0_pi2c_setvoltage(sc->sc_iot, sc->sc_pm_ioh, PI2C_VOLTAGE_LOW);
                    919:
                    920:        sd.sd_gpdr0 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR0);
                    921:        sd.sd_gpdr1 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR1);
                    922:        sd.sd_gpdr2 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR2);
                    923:        sd.sd_gpdr3 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR3);
                    924:
                    925:        sd.sd_grer0 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER0);
                    926:        sd.sd_grer1 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER1);
                    927:        sd.sd_grer2 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER2);
                    928:        sd.sd_grer3 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER3);
                    929:
                    930:        sd.sd_gfer0 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER0);
                    931:        sd.sd_gfer1 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER1);
                    932:        sd.sd_gfer2 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER2);
                    933:        sd.sd_gfer3 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER3);
                    934:
                    935:        sd.sd_gafr0_l = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR0_L);
                    936:        sd.sd_gafr1_l = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR1_L);
                    937:        sd.sd_gafr2_l = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR2_L);
                    938:        sd.sd_gafr3_l = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR3_L);
                    939:
                    940:        sd.sd_gafr0_u = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR0_U);
                    941:        sd.sd_gafr1_u = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR1_U);
                    942:        sd.sd_gafr2_u = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR2_U);
                    943:        sd.sd_gafr3_u = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR3_U);
                    944:
                    945:        sd.sd_gplr0 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPLR0);
                    946:        sd.sd_gplr1 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPLR1);
                    947:        sd.sd_gplr2 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPLR2);
                    948:        sd.sd_gplr3 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPLR3);
                    949:
                    950:        sd.sd_iclr = read_icu(INTCTL_ICLR);
                    951:        sd.sd_icmr = read_icu(INTCTL_ICMR);
                    952:        sd.sd_iccr = read_icu(INTCTL_ICCR);
                    953:        write_icu(INTCTL_ICMR, 0);
                    954:
                    955:        sd.sd_mecr = bus_space_read_4(sc->sc_iot, pxa2x0_memctl_ioh,
                    956:            MEMCTL_MECR);
                    957:        sd.sd_mcmem0 = bus_space_read_4(sc->sc_iot, pxa2x0_memctl_ioh,
                    958:            MEMCTL_MCMEM(0));
                    959:        sd.sd_mcmem1 = bus_space_read_4(sc->sc_iot, pxa2x0_memctl_ioh,
                    960:            MEMCTL_MCMEM(1));
                    961:        sd.sd_mcatt0 = bus_space_read_4(sc->sc_iot, pxa2x0_memctl_ioh,
                    962:            MEMCTL_MCATT(0));
                    963:        sd.sd_mcatt1 = bus_space_read_4(sc->sc_iot, pxa2x0_memctl_ioh,
                    964:            MEMCTL_MCATT(1));
                    965:        sd.sd_mcio0 = bus_space_read_4(sc->sc_iot, pxa2x0_memctl_ioh,
                    966:            MEMCTL_MCIO(0));
                    967:        sd.sd_mcio1 = bus_space_read_4(sc->sc_iot, pxa2x0_memctl_ioh,
                    968:            MEMCTL_MCIO(1));
                    969:
                    970:        sd.sd_cken = bus_space_read_4(sc->sc_iot, pxa2x0_clkman_ioh,
                    971:            CLKMAN_CKEN);
                    972:
                    973:        /*
                    974:         * Stop clocks to all units except to the memory controller, and
                    975:         * to the keypad controller if it is enabled as a wake-up source.
                    976:         */
                    977:        rv = CKEN_MEM;
                    978:        if ((sc->sc_wakeon & PXA2X0_WAKEUP_KEYNS_ALL) != 0)
                    979:                rv |= CKEN_KEY;
                    980:        bus_space_write_4(sc->sc_iot, pxa2x0_clkman_ioh, CLKMAN_CKEN, rv);
                    981:
                    982:        /* Disable nRESET_OUT. */
                    983:        rv = bus_space_read_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PSLR);
                    984: #define  PSLR_SL_ROD   (1<<20)
                    985:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PSLR,
                    986:            rv | PSLR_SL_ROD);
                    987:
                    988:        /* Clear all reset status flags. */
                    989:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_RCSR,
                    990:            RCSR_GPR | RCSR_SMR | RCSR_WDR | RCSR_HWR);
                    991:
                    992:        /* Stop 3/13MHz oscillator; do not float PCMCIA and chip-selects. */
                    993:        rv = PCFR_OPDE;
                    994:         if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X)
                    995:                /* Enable nRESET_GPIO as a GPIO reset input. */
                    996:                rv |= PCFR_GPR_EN;
                    997:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PCFR, rv);
                    998:
                    999:        /* XXX C3000 */
                   1000: #define        GPIO_G0_STROBE_BIT              0x0f800000
                   1001: #define        GPIO_G1_STROBE_BIT              0x00100000
                   1002: #define        GPIO_G2_STROBE_BIT              0x01000000
                   1003: #define        GPIO_G3_STROBE_BIT              0x00041880
                   1004: #define        GPIO_KEY_STROBE0                88
                   1005:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR0,
                   1006:            0x00144018);
                   1007:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR1,
                   1008:            0x00ef0000);
                   1009:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR2,
                   1010:            0x0121c000);
                   1011:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR3,
                   1012:            0x00600000);
                   1013:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR0,
                   1014:            0x00144018 & ~GPIO_G0_STROBE_BIT);
                   1015:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR1,
                   1016:            0x00ef0000 & ~GPIO_G1_STROBE_BIT);
                   1017:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR2,
                   1018:            0x0121c000 & ~GPIO_G2_STROBE_BIT);
                   1019:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR3,
                   1020:            0x00600000 & ~GPIO_G3_STROBE_BIT);
                   1021:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR2,
                   1022:            (0x0121c000 & ~GPIO_G2_STROBE_BIT) |
                   1023:            GPIO_BIT(GPIO_KEY_STROBE0));
                   1024:
                   1025:        /* C3000 */
                   1026: #define GPIO_EXT_BUS_READY     18
                   1027:        pxa2x0_gpio_set_function(GPIO_EXT_BUS_READY, GPIO_SET | GPIO_OUT);
                   1028:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR0, 0xd01c4418);
                   1029:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR1, 0xfcefbd21);
                   1030:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR2, 0x13a5ffff);
                   1031:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR3, 0x01e3e10c);
                   1032:
                   1033:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PSPR,
                   1034:            (u_int32_t)&pxa2x0_cpu_resume - 0xc0200000 + 0xa0200000);
                   1035:
                   1036:        pxa2x0_cpu_suspend();
                   1037:
                   1038:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PSPR, 0);
                   1039:
                   1040:        pxa2x0_clkman_config(CKEN_SSP|CKEN_PWM0|CKEN_PWM1, 1);
                   1041:        pxa2x0_clkman_config(CKEN_KEY, 0);
                   1042:
                   1043: #if 1
                   1044:        /* Clear all GPIO interrupt sources. */
                   1045:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GEDR0, 0xffffffff);
                   1046:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GEDR1, 0xffffffff);
                   1047:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GEDR2, 0xffffffff);
                   1048: #endif
                   1049:
                   1050:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR0, sd.sd_gpdr0);
                   1051:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR1, sd.sd_gpdr1);
                   1052:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR2, sd.sd_gpdr2);
                   1053:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER0, sd.sd_grer0);
                   1054:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER1, sd.sd_grer1);
                   1055:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER2, sd.sd_grer2);
                   1056:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER0, sd.sd_gfer0);
                   1057:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER1, sd.sd_gfer1);
                   1058:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER2, sd.sd_gfer2);
                   1059:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR0_L, sd.sd_gafr0_l);
                   1060:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR1_L, sd.sd_gafr1_l);
                   1061:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR2_L, sd.sd_gafr2_l);
                   1062:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR0_U, sd.sd_gafr0_u);
                   1063:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR1_U, sd.sd_gafr1_u);
                   1064:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR2_U, sd.sd_gafr2_u);
                   1065:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPSR0, sd.sd_gplr0 &
                   1066:            sd.sd_gpdr0);
                   1067:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPSR1, sd.sd_gplr1 &
                   1068:            sd.sd_gpdr1);
                   1069:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPSR2, sd.sd_gplr2 &
                   1070:            sd.sd_gpdr2);
                   1071:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPCR0, ~sd.sd_gplr0 &
                   1072:            sd.sd_gpdr0);
                   1073:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPCR1, ~sd.sd_gplr1 &
                   1074:            sd.sd_gpdr1);
                   1075:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPCR2, ~sd.sd_gplr2 &
                   1076:            sd.sd_gpdr2);
                   1077:
                   1078:        /* PXA27x */
                   1079: #if 0
                   1080:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GEDR3, 0xffffffff);
                   1081: #endif
                   1082:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR3, sd.sd_gpdr3);
                   1083:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER3, sd.sd_grer3);
                   1084:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER3, sd.sd_gfer3);
                   1085:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR3_L, sd.sd_gafr3_l);
                   1086:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR3_U, sd.sd_gafr3_u);
                   1087:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPSR3, sd.sd_gplr3 &
                   1088:            sd.sd_gpdr3);
                   1089:        bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPCR3, ~sd.sd_gplr3 &
                   1090:            sd.sd_gpdr3);
                   1091:
                   1092:        bus_space_write_4(sc->sc_iot, pxa2x0_memctl_ioh, MEMCTL_MECR,
                   1093:            sd.sd_mecr);
                   1094:        bus_space_write_4(sc->sc_iot, pxa2x0_memctl_ioh, MEMCTL_MCMEM(0),
                   1095:            sd.sd_mcmem0);
                   1096:        bus_space_write_4(sc->sc_iot, pxa2x0_memctl_ioh, MEMCTL_MCMEM(1),
                   1097:            sd.sd_mcmem1);
                   1098:        bus_space_write_4(sc->sc_iot, pxa2x0_memctl_ioh, MEMCTL_MCATT(0),
                   1099:            sd.sd_mcatt0);
                   1100:        bus_space_write_4(sc->sc_iot, pxa2x0_memctl_ioh, MEMCTL_MCATT(1),
                   1101:            sd.sd_mcatt1);
                   1102:        bus_space_write_4(sc->sc_iot, pxa2x0_memctl_ioh, MEMCTL_MCIO(0),
                   1103:            sd.sd_mcio0);
                   1104:        bus_space_write_4(sc->sc_iot, pxa2x0_memctl_ioh, MEMCTL_MCIO(1),
                   1105:            sd.sd_mcio1);
                   1106:
                   1107:        bus_space_write_4(sc->sc_iot, pxa2x0_clkman_ioh, CLKMAN_CKEN,
                   1108:            sd.sd_cken);
                   1109:
                   1110:        write_icu(INTCTL_ICLR, sd.sd_iclr);
                   1111:        write_icu(INTCTL_ICCR, sd.sd_iccr);
                   1112:        write_icu(INTCTL_ICMR, sd.sd_icmr);
                   1113:
                   1114:        if ((read_icu(INTCTL_ICIP) & 0x1) != 0)
                   1115:                bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PEDR, 0x1);
                   1116:
                   1117:        bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSMR0, sd.sd_osmr0);
                   1118:        bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSMR1, sd.sd_osmr1);
                   1119:        bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSMR2, sd.sd_osmr2);
                   1120:        bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSMR3, sd.sd_osmr3);
                   1121:        bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSMR4, sd.sd_osmr4);
                   1122:        bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSMR5, sd.sd_osmr5);
                   1123:        bus_space_write_4(sc->sc_iot, ost_ioh, OST_OMCR4, sd.sd_omcr4);
                   1124:        bus_space_write_4(sc->sc_iot, ost_ioh, OST_OMCR5, sd.sd_omcr5);
                   1125:        bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSCR0, sd.sd_oscr0);
                   1126:        bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSCR4, sd.sd_oscr4);
                   1127:        bus_space_write_4(sc->sc_iot, ost_ioh, OST_OIER, sd.sd_oier);
                   1128:
                   1129:        pxa2x0_pi2c_setvoltage(sc->sc_iot, sc->sc_pm_ioh, PI2C_VOLTAGE_HIGH);
                   1130:
                   1131:        /* Change to 208MHz run mode with fast-bus still disabled. */
                   1132:        pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 | CCCR_RUN_X16,
                   1133:            CLKCFG_F, &pxa2x0_memcfg);
                   1134:        delay(1); /* XXX is the delay long enough, and necessary at all? */
                   1135:        pxa27x_fastbus_run_mode(1, pxa2x0_memcfg.mdrefr_high);
                   1136:
                   1137:        /* Change to 416MHz turbo mode with fast-bus enabled. */
                   1138:        pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 | CCCR_RUN_X16,
                   1139:            CLKCFG_B | CLKCFG_F | CLKCFG_T, &pxa2x0_memcfg);
                   1140:
                   1141:        if (sc->sc_resume != NULL) {
                   1142:                if (!sc->sc_resume(sc))
                   1143:                        goto suspend_again;
                   1144:        }
                   1145:
                   1146:        /*
                   1147:         * Allow immediate entry into deep-sleep mode if power fails.
                   1148:         * Resume from immediate deep-sleep is not implemented yet.
                   1149:         */
                   1150:        bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PMCR, 0);
                   1151:
                   1152:
                   1153:        restore_interrupts(save);
                   1154:
                   1155:        pxa2x0_setperf(perflevel);
                   1156:
                   1157:  out:
                   1158:        if (ost_ioh != (bus_space_handle_t)0)
                   1159:                bus_space_unmap(sc->sc_iot, ost_ioh, PXA2X0_OST_SIZE);
                   1160: }
                   1161:
                   1162: void
                   1163: pxa2x0_pi2c_open(bus_space_tag_t iot, bus_space_handle_t ioh)
                   1164: {
                   1165:        u_int32_t rv;
                   1166:
                   1167:        /* Enable the I2C unit, and disable automatic voltage change. */
                   1168:        rv = bus_space_read_4(iot, ioh, POWMAN_PCFR);
                   1169:        bus_space_write_4(iot, ioh, POWMAN_PCFR, rv | PCFR_PI2C_EN);
                   1170:        rv = bus_space_read_4(iot, ioh, POWMAN_PCFR);
                   1171:        bus_space_write_4(iot, ioh, POWMAN_PCFR, rv & ~PCFR_FVC);
                   1172:        delay(1);
                   1173:
                   1174:        /* Enable the clock to the power manager I2C unit. */
                   1175:        pxa2x0_clkman_config(CKEN_PI2C, 1);
                   1176:        delay(1);
                   1177: }
                   1178:
                   1179: void
                   1180: pxa2x0_pi2c_close(bus_space_tag_t iot, bus_space_handle_t ioh)
                   1181: {
                   1182:        u_int32_t rv;
                   1183:
                   1184:        bus_space_write_4(iot, ioh, POWMAN_PICR, PICR_UR);
                   1185:        bus_space_write_4(iot, ioh, POWMAN_PISAR, 0);
                   1186:        delay(1);
                   1187:
                   1188:        /* Disable the clock to the power manager I2C unit. */
                   1189:        pxa2x0_clkman_config(CKEN_PI2C, 0);
                   1190:        delay(1);
                   1191:
                   1192:        /* Disable the I2C unit, and disable automatic voltage change. */
                   1193:        rv = bus_space_read_4(iot, ioh, POWMAN_PCFR);
                   1194:        bus_space_write_4(iot, ioh, POWMAN_PCFR,
                   1195:            rv & ~(PCFR_PI2C_EN | PCFR_FVC));
                   1196:        delay(1);
                   1197: }
                   1198:
                   1199: int
                   1200: pxa2x0_pi2c_read(bus_space_tag_t iot, bus_space_handle_t ioh,
                   1201:     u_char slave, u_char *valuep)
                   1202: {
                   1203:        u_int32_t rv;
                   1204:        int timeout;
                   1205:        int tries = PI2C_RETRY_COUNT;
                   1206:
                   1207: retry:
                   1208:
                   1209:        bus_space_write_4(iot, ioh, POWMAN_PICR, PICR_UR);
                   1210:        bus_space_write_4(iot, ioh, POWMAN_PISAR, 0x00);
                   1211:        delay(1);
                   1212:        bus_space_write_4(iot, ioh, POWMAN_PICR, PICR_IUE | PICR_SCLE);
                   1213:
                   1214:        /* Write slave device address. */
                   1215:        bus_space_write_4(iot, ioh, POWMAN_PIDBR, (slave<<1) | 0x1);
                   1216:        rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
                   1217:        bus_space_write_4(iot, ioh, POWMAN_PICR, rv | PICR_START);
                   1218:        rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
                   1219:        bus_space_write_4(iot, ioh, POWMAN_PICR, rv & ~PICR_STOP);
                   1220:        rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
                   1221:        bus_space_write_4(iot, ioh, POWMAN_PICR, rv | PICR_TB);
                   1222:
                   1223:        timeout = 10000;
                   1224:        while ((bus_space_read_4(iot, ioh, POWMAN_PISR) & PISR_ITE) == 0) {
                   1225:                if (timeout-- == 0) {
                   1226:                        bus_space_write_4(iot, ioh, POWMAN_PISR, PISR_ITE);
                   1227:                        goto err;
                   1228:                }
                   1229:                delay(1);
                   1230:        }
                   1231:
                   1232:        bus_space_write_4(iot, ioh, POWMAN_PISR, PISR_ITE);
                   1233:
                   1234:        rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
                   1235:        bus_space_write_4(iot, ioh, POWMAN_PICR, rv & ~PICR_START);
                   1236:
                   1237:        /* Read data value. */
                   1238:        rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
                   1239:        bus_space_write_4(iot, ioh, POWMAN_PICR, rv |
                   1240:            (PICR_STOP | PICR_ACKNAK));
                   1241:        rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
                   1242:        bus_space_write_4(iot, ioh, POWMAN_PICR, rv | PICR_TB);
                   1243:
                   1244:        timeout = 10000;
                   1245:        while ((bus_space_read_4(iot, ioh, POWMAN_PISR) & PISR_IRF) == 0) {
                   1246:                if (timeout-- == 0) {
                   1247:                        bus_space_write_4(iot, ioh, POWMAN_PISR, PISR_IRF);
                   1248:                        goto err;
                   1249:                }
                   1250:                delay(1);
                   1251:        }
                   1252:
                   1253:        bus_space_write_4(iot, ioh, POWMAN_PISR, PISR_IRF);
                   1254:        rv = bus_space_read_4(iot, ioh, POWMAN_PIDBR);
                   1255:        *valuep = (u_char)rv;
                   1256:        rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
                   1257:        bus_space_write_4(iot, ioh, POWMAN_PICR, rv &
                   1258:            ~(PICR_STOP | PICR_ACKNAK));
                   1259:
                   1260:        return (0);
                   1261: err:
                   1262:        if (tries-- >= 0)
                   1263:                goto retry;
                   1264:
                   1265:        bus_space_write_4(iot, ioh, POWMAN_PICR, PICR_UR);
                   1266:        bus_space_write_4(iot, ioh, POWMAN_PISAR, 0x00);
                   1267:        bus_space_write_4(iot, ioh, POWMAN_PICR, PICR_IUE | PICR_SCLE);
                   1268:
                   1269:        return (-EIO);
                   1270: }
                   1271:
                   1272: int
                   1273: pxa2x0_pi2c_write(bus_space_tag_t iot, bus_space_handle_t ioh,
                   1274:     u_char slave, u_char value)
                   1275: {
                   1276:        u_int32_t rv;
                   1277:        int timeout;
                   1278:        int tries = PI2C_RETRY_COUNT;
                   1279:
                   1280: retry:
                   1281:
                   1282:        bus_space_write_4(iot, ioh, POWMAN_PICR, PICR_UR);
                   1283:        bus_space_write_4(iot, ioh, POWMAN_PISAR, 0x00);
                   1284:        delay(1);
                   1285:        bus_space_write_4(iot, ioh, POWMAN_PICR, PICR_IUE | PICR_SCLE);
                   1286:
                   1287:        /* Write slave device address. */
                   1288:        bus_space_write_4(iot, ioh, POWMAN_PIDBR, (slave<<1));
                   1289:        rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
                   1290:        bus_space_write_4(iot, ioh, POWMAN_PICR, rv | PICR_START);
                   1291:        rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
                   1292:        bus_space_write_4(iot, ioh, POWMAN_PICR, rv & ~PICR_STOP);
                   1293:        rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
                   1294:        bus_space_write_4(iot, ioh, POWMAN_PICR, rv | PICR_TB);
                   1295:
                   1296:        timeout = 10000;
                   1297:        while ((bus_space_read_4(iot, ioh, POWMAN_PISR) & PISR_ITE) == 0) {
                   1298:                if (timeout-- == 0) {
                   1299:                        bus_space_write_4(iot, ioh, POWMAN_PISR, PISR_ITE);
                   1300:                        goto err;
                   1301:                }
                   1302:                delay(1);
                   1303:        }
                   1304:        if ((bus_space_read_4(iot, ioh, POWMAN_PISR) & PISR_ACKNAK) != 0)
                   1305:                goto err;
                   1306:        bus_space_write_4(iot, ioh, POWMAN_PISR, PISR_ITE);
                   1307:
                   1308:        /* Write data. */
                   1309:        rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
                   1310:        bus_space_write_4(iot, ioh, POWMAN_PICR, rv & ~PICR_START);
                   1311:        rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
                   1312:        bus_space_write_4(iot, ioh, POWMAN_PICR, rv | PICR_STOP);
                   1313:        bus_space_write_4(iot, ioh, POWMAN_PIDBR, value);
                   1314:        rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
                   1315:        bus_space_write_4(iot, ioh, POWMAN_PICR, rv | PICR_TB);
                   1316:
                   1317:        timeout = 10000;
                   1318:        while ((bus_space_read_4(iot, ioh, POWMAN_PISR) & PISR_ITE) == 0) {
                   1319:                if (timeout-- == 0) {
                   1320: #if 0
                   1321:                        bus_space_write_4(iot, ioh, POWMAN_PISR, PISR_ITE);
                   1322: #endif
                   1323:                        goto err;
                   1324:                }
                   1325:                delay(1);
                   1326:        }
                   1327:        if ((bus_space_read_4(iot, ioh, POWMAN_PISR) & PISR_ACKNAK) != 0)
                   1328:                goto err;
                   1329:        bus_space_write_4(iot, ioh, POWMAN_PISR, PISR_ITE);
                   1330:
                   1331:        rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
                   1332:        bus_space_write_4(iot, ioh, POWMAN_PICR, rv & ~PICR_STOP);
                   1333:
                   1334:        return (0);
                   1335: err:
                   1336:        bus_space_write_4(iot, ioh, POWMAN_PISR, PISR_ITE);
                   1337:        if (tries-- >= 0)
                   1338:                goto retry;
                   1339:
                   1340:        bus_space_write_4(iot, ioh, POWMAN_PICR, PICR_UR);
                   1341:        bus_space_write_4(iot, ioh, POWMAN_PISAR, 0x00);
                   1342:        bus_space_write_4(iot, ioh, POWMAN_PICR, PICR_IUE | PICR_SCLE);
                   1343:
                   1344:        return (-EIO);
                   1345: }
                   1346:
                   1347: int
                   1348: pxa2x0_pi2c_getvoltage(bus_space_tag_t iot, bus_space_handle_t ioh,
                   1349:     u_char *valuep)
                   1350: {
                   1351:        int res;
                   1352:
                   1353:        pxa2x0_pi2c_open(iot, ioh);
                   1354:        res = pxa2x0_pi2c_read(iot, ioh, 0x0c, valuep);
                   1355:        pxa2x0_pi2c_close(iot, ioh);
                   1356:        return (res);
                   1357: }
                   1358:
                   1359: int
                   1360: pxa2x0_pi2c_setvoltage(bus_space_tag_t iot, bus_space_handle_t ioh,
                   1361:     u_char value)
                   1362: {
                   1363:        int res;
                   1364:
                   1365:        pxa2x0_pi2c_open(iot, ioh);
                   1366:        res = pxa2x0_pi2c_write(iot, ioh, 0x0c, value);
                   1367:        pxa2x0_pi2c_close(iot, ioh);
                   1368:        return (res);
                   1369: }
                   1370:
                   1371: #if 0
                   1372: void
                   1373: pxa2x0_pi2c_print(struct pxa2x0_apm_softc *sc)
                   1374: {
                   1375:        u_char value = 0;
                   1376:
                   1377:        (void)pxa2x0_pi2c_getvoltage(sc->sc_iot, sc->sc_pm_ioh, &value);
                   1378:        printf("xscale core voltage: %s\n", value == PI2C_VOLTAGE_HIGH ?
                   1379:            "high" : (value == PI2C_VOLTAGE_LOW ? "low" : "unknown"));
                   1380: }
                   1381: #endif
                   1382:
                   1383: struct {
                   1384:        int maxspeed;
                   1385:        int numspeeds;
                   1386:        int hz [6];
                   1387:        int rate [6]; /* could this be simplfied by not having 100% in table? */
                   1388: }
                   1389: speedtables[] = {
                   1390:        { 91, 1, { 91 }, { 100 }},
                   1391:        { 208, 2, { 91, 208}, {50, 100}},
                   1392:        { 416, 3, { 91, 208, 416}, {25, 50, 100}},
                   1393:        { 520, 4, { 91, 208, 416, 520}, {18, 40 ,80, 100}},
                   1394:        { 624, 5, { 91, 208, 416, 520, 624}, {15, 34, 67, 82, 100}},
                   1395:        { 0 }
                   1396: };
                   1397: int xscale_maxspeed = 416; /* XXX */
                   1398:
                   1399: int speed_to_freq(int speed);
                   1400:
                   1401: int
                   1402: speed_to_freq(int speed)
                   1403: {
                   1404:        int i, j;
                   1405:        int newspeed = 0;
                   1406:        int numspeeds;
                   1407:        for (i = 0; speedtables[i].maxspeed != 0; i++) {
                   1408:                if (speedtables[i].maxspeed != xscale_maxspeed)
                   1409:                        continue;
                   1410:
                   1411:                if (speed <= speedtables[i].rate[0]) {
                   1412:                        return speedtables[i].hz[0];
                   1413:
                   1414:                }
                   1415:                numspeeds = speedtables[i].numspeeds;
                   1416:                if (speed == speedtables[i].rate[numspeeds-1]) {
                   1417:                        return speedtables[i].hz[numspeeds-1];
                   1418:                }
                   1419:                for (j = 1; j < numspeeds; j++) {
                   1420:                        if (speed < speedtables[i].rate[j]) {
                   1421:                                return speedtables[i].hz[j-1];
                   1422:                        }
                   1423:                }
                   1424:        }
                   1425:        return newspeed;
                   1426: }
                   1427:
                   1428:
                   1429: void
                   1430: pxa2x0_setperf(int speed)
                   1431: {
                   1432:        struct pxa2x0_apm_softc *sc;
                   1433:        int s;
                   1434:        int newfreq;
                   1435:
                   1436:        sc = apm_cd.cd_devs[0];
                   1437:
                   1438:        newfreq = speed_to_freq(speed);
                   1439:
                   1440:        if (newfreq == 0) {
                   1441:                printf("bogus new frequency 0 for rate %d maxclock %d\n",
                   1442:                    speed, xscale_maxspeed);
                   1443:        }
                   1444:
                   1445:        DPRINTF(("setperf speed %d newfreq %d, maxfreq %d\n",
                   1446:            speed, newfreq, xscale_maxspeed));
                   1447:
                   1448:        s = disable_interrupts(I32_bit|F32_bit);
                   1449:
                   1450:        if (newfreq == 91) {
                   1451:                if (freq > 91) {
                   1452:                        pxa27x_run_mode();
                   1453:                        pxa27x_fastbus_run_mode(0, MDREFR_LOW);
                   1454:                        pxa27x_cpu_speed_91();
                   1455:                        pxa2x0_pi2c_setvoltage(sc->sc_iot, sc->sc_pm_ioh,
                   1456:                            PI2C_VOLTAGE_LOW);
                   1457:                        freq = 91;
                   1458:                }
                   1459:        } else if (newfreq == 208) {
                   1460:                if (freq < 208)
                   1461:                        pxa2x0_pi2c_setvoltage(sc->sc_iot, sc->sc_pm_ioh,
                   1462:                            PI2C_VOLTAGE_HIGH);
                   1463:                if (freq != 208) {
                   1464:                        pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 |
                   1465:                            CCCR_RUN_X16, CLKCFG_F, &pxa2x0_memcfg);
                   1466:                        pxa27x_fastbus_run_mode(1, pxa2x0_memcfg.mdrefr_high);
                   1467:                        freq = 208;
                   1468:                }
                   1469:        } else if (newfreq == 416) {
                   1470:                if (freq < 208) {
                   1471:                        pxa2x0_pi2c_setvoltage(sc->sc_iot, sc->sc_pm_ioh,
                   1472:                            PI2C_VOLTAGE_HIGH);
                   1473:                        pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 |
                   1474:                            CCCR_RUN_X16, CLKCFG_F, &pxa2x0_memcfg);
                   1475:                        pxa27x_fastbus_run_mode(1, pxa2x0_memcfg.mdrefr_high);
                   1476:                }
                   1477:                if (freq != 416) {
                   1478:                        pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 |
                   1479:                            CCCR_RUN_X16, CLKCFG_B | CLKCFG_F | CLKCFG_T,
                   1480:                            &pxa2x0_memcfg);
                   1481:                        freq = 416;
                   1482:                }
                   1483:        } else if (newfreq == 520) {
                   1484:                if (freq < 208) {
                   1485:                        pxa2x0_pi2c_setvoltage(sc->sc_iot, sc->sc_pm_ioh,
                   1486:                            PI2C_VOLTAGE_HIGH);
                   1487:                        pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 |
                   1488:                            CCCR_RUN_X16, CLKCFG_F, &pxa2x0_memcfg);
                   1489:                        pxa27x_fastbus_run_mode(1, pxa2x0_memcfg.mdrefr_high);
                   1490:                }
                   1491:                if (freq != 520) {
                   1492:                        pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X25 |
                   1493:                            CCCR_RUN_X16, CLKCFG_B | CLKCFG_F | CLKCFG_T,
                   1494:                            &pxa2x0_memcfg);
                   1495:                        freq = 520;
                   1496:                }
                   1497:        } else if (newfreq == 624) {
                   1498:                if (freq < 208) {
                   1499:                        pxa2x0_pi2c_setvoltage(sc->sc_iot, sc->sc_pm_ioh,
                   1500:                            PI2C_VOLTAGE_HIGH);
                   1501:                        pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 |
                   1502:                            CCCR_RUN_X16, CLKCFG_F, &pxa2x0_memcfg);
                   1503:                        pxa27x_fastbus_run_mode(1, pxa2x0_memcfg.mdrefr_high);
                   1504:                }
                   1505:                if (freq != 624) {
                   1506:                        pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X3 |
                   1507:                            CCCR_RUN_X16, CLKCFG_B | CLKCFG_F | CLKCFG_T,
                   1508:                            &pxa2x0_memcfg);
                   1509:                        freq = 624;
                   1510:                }
                   1511:        }
                   1512:
                   1513:        restore_interrupts(s);
                   1514: }
                   1515:
                   1516: int
                   1517: pxa2x0_cpuspeed(int *freqp)
                   1518: {
                   1519:        *freqp = freq;
                   1520:        return 0;
                   1521: }
                   1522:
                   1523: void pxa2x0_maxspeed(int *speedp);
                   1524:
                   1525: void
                   1526: pxa2x0_maxspeed(int *speedp)
                   1527: {
                   1528:        /* XXX assumes a pxa270 */
                   1529:
                   1530:        if (*speedp < 207) {
                   1531:                *speedp = 91;
                   1532:        } else if (*speedp < 415) {
                   1533:                *speedp = 208;
                   1534:        } else if (*speedp < 519) {
                   1535:                *speedp = 416;
                   1536:        } else if (*speedp < 624) {
                   1537:                *speedp = 520;
                   1538: #if 0
                   1539:        } else if (*speedp < 651) {
                   1540:                *speedp = 624;
                   1541: #endif
                   1542:        } else {
                   1543:                *speedp = 520; /* hope this is safe. */
                   1544:        }
                   1545:        xscale_maxspeed = *speedp;
                   1546:        pxa2x0_setperf(perflevel);
                   1547: }

CVSweb