Lines Matching +full:power +full:- +full:up +full:- +full:delay +full:- +full:ms
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2000-2001 Jonathan Chen All rights reserved.
5 * Copyright (c) 2002-2004 M. Warner Losh <imp@FreeBSD.org>
30 /*-
65 * http://www-s.ti.com/cgi-bin/sc/generic2.cgi?family=PCI+CARDBUS+CONTROLLERS
137 "Starting ioport for 16-bit cards");
142 "Starting ioport for 32-bit cards");
178 SLIST_FOREACH(rle, &sc->rl, link) { in cbb_remove_res()
179 if (rle->res == res) { in cbb_remove_res()
180 SLIST_REMOVE(&sc->rl, rle, cbb_reslist, link); in cbb_remove_res()
192 SLIST_FOREACH(rle, &sc->rl, link) in cbb_find_res()
193 if (SYS_RES_MEMORY == rle->type && rid == rle->rid) in cbb_find_res()
194 return (rle->res); in cbb_find_res()
211 rle->res = res; in cbb_insert_res()
212 rle->type = type; in cbb_insert_res()
213 rle->rid = rid; in cbb_insert_res()
214 SLIST_INSERT_HEAD(&sc->rl, rle, link); in cbb_insert_res()
222 while ((rle = SLIST_FIRST(&sc->rl)) != NULL) { in cbb_destroy_res()
223 device_printf(sc->dev, "Danger Will Robinson: Resource " in cbb_destroy_res()
225 "(rid=%x, type=%d, addr=%jx)\n", rle->rid, rle->type, in cbb_destroy_res()
226 rman_get_start(rle->res)); in cbb_destroy_res()
227 SLIST_REMOVE_HEAD(&sc->rl, link); in cbb_destroy_res()
249 reg = (exca_getb(&sc->exca, EXCA_INTR) & ~EXCA_INTR_IRQ_MASK) | in cbb_disable_func_intr()
251 exca_putb(&sc->exca, EXCA_INTR, reg); in cbb_disable_func_intr()
267 reg = (exca_getb(&sc->exca, EXCA_INTR) & ~EXCA_INTR_IRQ_MASK) | in cbb_enable_func_intr()
269 PCI_MASK_CONFIG(sc->dev, CBBR_BRIDGECTRL, in cbb_enable_func_intr()
271 exca_putb(&sc->exca, EXCA_INTR, reg); in cbb_enable_func_intr()
287 /* reset 16-bit pcmcia bus */ in cbb_detach()
288 exca_clrb(&sc->exca, EXCA_INTR, EXCA_INTR_RESET); in cbb_detach()
290 /* turn off power */ in cbb_detach()
304 bus_teardown_intr(brdev, sc->irq_res, sc->intrhand); in cbb_detach()
305 mtx_lock(&sc->mtx); in cbb_detach()
306 sc->flags |= CBB_KTHREAD_DONE; in cbb_detach()
307 while (sc->flags & CBB_KTHREAD_RUNNING) { in cbb_detach()
308 DEVPRINTF((sc->dev, "Waiting for thread to die\n")); in cbb_detach()
309 wakeup(&sc->intrhand); in cbb_detach()
310 msleep(sc->event_thread, &sc->mtx, PWAIT, "cbbun", 0); in cbb_detach()
312 mtx_unlock(&sc->mtx); in cbb_detach()
314 bus_release_resource(brdev, SYS_RES_IRQ, 0, sc->irq_res); in cbb_detach()
316 sc->base_res); in cbb_detach()
317 mtx_destroy(&sc->mtx); in cbb_detach()
336 ih->filt = filt; in cbb_setup_intr()
337 ih->intr = intr; in cbb_setup_intr()
338 ih->arg = arg; in cbb_setup_intr()
339 ih->sc = sc; in cbb_setup_intr()
346 &ih->cookie); in cbb_setup_intr()
352 sc->cardok = 1; in cbb_setup_intr()
366 ih->cookie); in cbb_teardown_intr()
398 wakeup(&sc->intrhand); in cbb_driver_added()
407 if (child != sc->cbdev && child != sc->exca.pccarddev) in cbb_child_detached()
425 * We need to act as a power sequencer on startup. Delay 2s/channel in cbb_event_thread()
426 * to ensure the other channels have had a chance to come up. We likely in cbb_event_thread()
427 * should add a lock that's shared on a per-slot basis so that only in cbb_event_thread()
428 * one power event can happen per slot at a time. in cbb_event_thread()
430 pause("cbbstart", hz * device_get_unit(sc->dev) * 2); in cbb_event_thread()
431 mtx_lock(&sc->mtx); in cbb_event_thread()
432 sc->flags |= CBB_KTHREAD_RUNNING; in cbb_event_thread()
433 while ((sc->flags & CBB_KTHREAD_DONE) == 0) { in cbb_event_thread()
434 mtx_unlock(&sc->mtx); in cbb_event_thread()
442 * Up to 10 times, try to rescan the card when we see in cbb_event_thread()
449 DEVPRINTF((sc->dev, in cbb_event_thread()
453 device_printf(sc->dev, in cbb_event_thread()
465 if (sc->sc_root_token) { in cbb_event_thread()
466 root_mount_rel(sc->sc_root_token); in cbb_event_thread()
467 sc->sc_root_token = NULL; in cbb_event_thread()
471 * Wait until it has been 250ms since the last time we in cbb_event_thread()
474 * ISR, we signal sc->cv from the detach path after we've in cbb_event_thread()
476 * 250ms sleep here. in cbb_event_thread()
484 mtx_lock(&sc->mtx); in cbb_event_thread()
486 msleep(&sc->intrhand, &sc->mtx, 0, "-", 0); in cbb_event_thread()
489 (sc->flags & CBB_KTHREAD_DONE) == 0) in cbb_event_thread()
490 err = msleep(&sc->intrhand, &sc->mtx, 0, "-", hz / 5); in cbb_event_thread()
492 DEVPRINTF((sc->dev, "Thread terminating\n")); in cbb_event_thread()
493 sc->flags &= ~CBB_KTHREAD_RUNNING; in cbb_event_thread()
494 mtx_unlock(&sc->mtx); in cbb_event_thread()
510 DEVPRINTF((sc->dev, "card inserted: event=0x%08x, state=%08x\n", in cbb_insert()
514 if (device_is_attached(sc->exca.pccarddev)) { in cbb_insert()
515 sc->flags |= CBB_16BIT_CARD; in cbb_insert()
516 exca_insert(&sc->exca); in cbb_insert()
518 device_printf(sc->dev, in cbb_insert()
519 "16-bit card inserted, but no pccard bus.\n"); in cbb_insert()
522 if (device_is_attached(sc->cbdev)) { in cbb_insert()
523 sc->flags &= ~CBB_16BIT_CARD; in cbb_insert()
524 CARD_ATTACH_CARD(sc->cbdev); in cbb_insert()
526 device_printf(sc->dev, in cbb_insert()
531 * We should power the card down, and try again a couple of in cbb_insert()
534 device_printf(sc->dev, "Unsupported card type detected\n"); in cbb_insert()
541 sc->cardok = 0; in cbb_removal()
542 if (sc->flags & CBB_16BIT_CARD) { in cbb_removal()
543 exca_removal(&sc->exca); in cbb_removal()
545 if (device_is_attached(sc->cbdev)) in cbb_removal()
546 CARD_DETACH_CARD(sc->cbdev); in cbb_removal()
559 struct cbb_softc *sc = ih->sc; in cbb_func_filt()
564 if (!sc->cardok) in cbb_func_filt()
567 sc->cardok = 0; in cbb_func_filt()
571 return ((*ih->filt)(ih->arg)); in cbb_func_filt()
578 struct cbb_softc *sc = ih->sc; in cbb_func_intr()
593 if (ih->filt == NULL) { in cbb_func_intr()
594 if (!sc->cardok) in cbb_func_intr()
597 sc->cardok = 0; in cbb_func_intr()
602 ih->intr(ih->arg); in cbb_func_intr()
606 /* Generic Power functions */
654 * (select IRQ1), of the slot, before turning on slot power. in cbb_o2micro_power_hack()
664 reg = exca_getb(&sc->exca, EXCA_INTR); in cbb_o2micro_power_hack()
665 exca_putb(&sc->exca, EXCA_INTR, (reg & 0xf0) | 1); in cbb_o2micro_power_hack()
671 * we don't have an interrupt storm on power on. This has the effect of
677 exca_putb(&sc->exca, EXCA_INTR, reg); in cbb_o2micro_power_hack2()
713 return (0); /* power NEVER changed */ in cbb_power()
722 DEVPRINTF((sc->dev, "cbb_power: %dV\n", volts)); in cbb_power()
723 if (volts != 0 && sc->chipset == CB_O2MICRO) in cbb_power()
728 * messing with the power. It is allowed to bounce while we're in cbb_power()
729 * messing with power as things settle down. In addition, we mask off in cbb_power()
731 * bit generally only affects 16-bit cards. Some bridges allow one to in cbb_power()
732 * set another bit to have it also affect 32-bit cards. Since 32-bit in cbb_power()
737 * EXCA CSC register for 16-bit cards, and disable the CD bit? in cbb_power()
747 mtx_lock(&sc->mtx); in cbb_power()
748 cnt = sc->powerintr; in cbb_power()
750 * We have a shortish timeout of 500ms here. Some bridges do in cbb_power()
751 * not generate a POWER_CYCLE event for 16-bit cards. In in cbb_power()
753 * only a short delay is better than the alternatives. Others in cbb_power()
754 * raise the power cycle a smidge before it is really ready. in cbb_power()
759 cnt == sc->powerintr && sane-- > 0) in cbb_power()
760 msleep(&sc->powerintr, &sc->mtx, 0, "-", hz / 20); in cbb_power()
761 mtx_unlock(&sc->mtx); in cbb_power()
764 * Relax for 100ms. Some bridges appear to assert this signal in cbb_power()
766 * cards need need more time to cope up reliabily. in cbb_power()
775 * act together, so delay for an additional 100ms. Also as in cbb_power()
779 if (sc->chipset == CB_TOPIC95) in cbb_power()
782 device_printf(sc->dev, "power timeout, doom?\n"); in cbb_power()
786 * After the power is good, we can turn off the power interrupt. in cbb_power()
787 * However, the PC Card standard says that we must delay turning the in cbb_power()
788 * CD bit back on for a bit to allow for bouncyness on power down in cbb_power()
789 * (recall that we don't wait above for a power down, since we don't in cbb_power()
796 * NB: Topic95B doesn't set the power cycle bit. we assume that in cbb_power()
801 if (on && sc->chipset != CB_TOPIC95) { in cbb_power()
803 device_printf(sc->dev, "Power not on?\n"); in cbb_power()
806 device_printf(sc->dev, "Bad Vcc requested\n"); in cbb_power()
808 * Turn off the power, and try again. Retrigger other in cbb_power()
821 if (sc->chipset == CB_TOPIC97) { in cbb_power()
822 reg_ctrl = pci_read_config(sc->dev, TOPIC_REG_CTRL, 4); in cbb_power()
828 pci_write_config(sc->dev, TOPIC_REG_CTRL, reg_ctrl, 4); in cbb_power()
832 if (volts != 0 && sc->chipset == CB_O2MICRO) in cbb_power()
858 * detect the voltage for the card, and set it. Since the power
860 * and what Windows does (and what Microsoft prefers). The MS paper
862 * to be done elsewhere. We also optimize power sequencing here
863 * and don't change things if we're already powered up at a supported
866 * In addition, we power up with OE disabled. We'll set it later
867 * in the power up sequence.
876 /* Don't enable OE (output enable) until power stable */ in cbb_do_power()
877 exca_clrb(&sc->exca, EXCA_PWRCTL, EXCA_PWRCTL_OE); in cbb_do_power()
902 /* CardBus power functions */
910 int delay, count, zero_seen, func; in cbb_cardbus_reset_power() local
913 * Asserting reset for 20ms is necessary for most bridges. For some in cbb_cardbus_reset_power()
914 * reason, the Ricoh RF5C47x bridges need it asserted for 400ms. The in cbb_cardbus_reset_power()
917 delay = sc->chipset == CB_RF5C47X ? 400 : 20; in cbb_cardbus_reset_power()
919 pause("cbbP3", hz * delay / 1000); in cbb_cardbus_reset_power()
923 * After clearing reset, wait up to 1.1s for the first configuration in cbb_cardbus_reset_power()
926 * says that when powering up the card, the PCI Spec v2.1 must be in cbb_cardbus_reset_power()
927 * followed. In PCI spec v2.2 Table 4-6, Trhfa (Reset High to first in cbb_cardbus_reset_power()
946 0xfffffffful && --count >= 0); in cbb_cardbus_reset_power()
953 * multi-function cards, but have nonsense for some of the in cbb_cardbus_reset_power()
1001 pause("cbbErr1", hz / 10); /* wait 100ms */ in cbb_cardbus_power_enable_socket()
1003 } while (err != 0 && count-- > 0); in cbb_cardbus_power_enable_socket()
1082 SLIST_FOREACH(rle, &sc->rl, link) { in cbb_cardbus_auto_open()
1083 if (rle->type != type) in cbb_cardbus_auto_open()
1085 if (rle->res == NULL) in cbb_cardbus_auto_open()
1087 if (!(rman_get_flags(rle->res) & RF_ACTIVE)) in cbb_cardbus_auto_open()
1089 if (rman_get_flags(rle->res) & RF_PREFETCHABLE) in cbb_cardbus_auto_open()
1093 if (rman_get_start(rle->res) < starts[i]) in cbb_cardbus_auto_open()
1094 starts[i] = rman_get_start(rle->res); in cbb_cardbus_auto_open()
1095 if (rman_get_end(rle->res) > ends[i]) in cbb_cardbus_auto_open()
1096 ends[i] = rman_get_end(rle->res); in cbb_cardbus_auto_open()
1101 starts[i] &= ~(align - 1); in cbb_cardbus_auto_open()
1102 ends[i] = roundup2(ends[i], align) - 1; in cbb_cardbus_auto_open()
1107 device_printf(sc->dev, "Overlapping ranges" in cbb_cardbus_auto_open()
1108 " for prefetch and non-prefetch memory\n"); in cbb_cardbus_auto_open()
1113 device_printf(sc->dev, "Overlapping ranges" in cbb_cardbus_auto_open()
1114 " for prefetch and non-prefetch memory\n"); in cbb_cardbus_auto_open()
1121 cbb_cardbus_mem_open(sc->dev, 0, starts[0], ends[0]); in cbb_cardbus_auto_open()
1122 cbb_cardbus_mem_open(sc->dev, 1, starts[1], ends[1]); in cbb_cardbus_auto_open()
1123 reg = pci_read_config(sc->dev, CBBR_BRIDGECTRL, 2); in cbb_cardbus_auto_open()
1128 pci_write_config(sc->dev, CBBR_BRIDGECTRL, reg, 2); in cbb_cardbus_auto_open()
1130 device_printf(sc->dev, "Opening memory:\n"); in cbb_cardbus_auto_open()
1132 device_printf(sc->dev, "Normal: %#x-%#x\n", in cbb_cardbus_auto_open()
1135 device_printf(sc->dev, "Prefetch: %#x-%#x\n", in cbb_cardbus_auto_open()
1139 cbb_cardbus_io_open(sc->dev, 0, starts[0], ends[0]); in cbb_cardbus_auto_open()
1140 cbb_cardbus_io_open(sc->dev, 1, starts[1], ends[1]); in cbb_cardbus_auto_open()
1142 device_printf(sc->dev, "Opening I/O: %#x-%#x\n", in cbb_cardbus_auto_open()
1186 tmp = rman_get_start(sc->irq_res); in cbb_cardbus_alloc_resource()
1188 device_printf(child, "requested interrupt %jd-%jd," in cbb_cardbus_alloc_resource()
1253 /* PC Card Power Functions */
1264 /* power down/up the socket to reset */ in cbb_pcic_power_enable_socket()
1268 exca_reset(&sc->exca, child); in cbb_pcic_power_enable_socket()
1280 /* Turn off the card's interrupt and leave it in reset, wait 10ms */ in cbb_pcic_power_disable_socket()
1281 exca_putb(&sc->exca, EXCA_INTR, 0); in cbb_pcic_power_disable_socket()
1284 /* power down the socket */ in cbb_pcic_power_disable_socket()
1286 exca_putb(&sc->exca, EXCA_PWRCTL, 0); in cbb_pcic_power_disable_socket()
1288 /* wait 300ms until power fails (Tpf). */ in cbb_pcic_power_disable_socket()
1292 exca_putb(&sc->exca, EXCA_INTR, EXCA_INTR_ENABLE); in cbb_pcic_power_disable_socket()
1297 /* POWER methods */
1305 if (sc->flags & CBB_16BIT_CARD) in cbb_power_enable_socket()
1314 if (sc->flags & CBB_16BIT_CARD) in cbb_power_disable_socket()
1326 error = exca_activate_resource(&sc->exca, child, res); in cbb_pcic_activate_resource()
1337 return (exca_deactivate_resource(&sc->exca, child, res)); in cbb_pcic_deactivate_resource()
1370 tmp = rman_get_start(sc->irq_res); in cbb_pcic_alloc_resource()
1372 device_printf(child, "requested interrupt %jd-%jd," in cbb_pcic_alloc_resource()
1378 start = end = rman_get_start(sc->irq_res); in cbb_pcic_alloc_resource()
1432 return (exca_mem_set_flags(&sc->exca, res, flags)); in cbb_pcic_set_res_flags()
1448 return (exca_mem_set_offset(&sc->exca, res, cardaddr, deltap)); in cbb_pcic_set_memory_offset()
1460 if (sc->flags & CBB_16BIT_CARD) in cbb_activate_resource()
1471 if (sc->flags & CBB_16BIT_CARD) in cbb_deactivate_resource()
1483 if (sc->flags & CBB_16BIT_CARD) in cbb_alloc_resource()
1496 if (sc->flags & CBB_16BIT_CARD) in cbb_release_resource()
1509 *result = sc->domain; in cbb_read_ivar()
1512 *result = sc->bus.sec; in cbb_read_ivar()
1543 return (CBB_CARD_PRESENT(sockstate) && sc->cardok); in cbb_child_present()