pccbb.c (f86e60008bdf690b61af2c18e98ee791ca91433f) pccbb.c (7b9439d081b3a861ab6af2fc94e897c31c61d6ab)
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2000-2001 Jonathan Chen All rights reserved.
5 * Copyright (c) 2002-2004 M. Warner Losh <imp@FreeBSD.org>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 239 unchanged lines hidden (view full) ---

248 * XXX the south bridge. Disable it it for now.
249 */
250void
251cbb_disable_func_intr(struct cbb_softc *sc)
252{
253#if 0
254 uint8_t reg;
255
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2000-2001 Jonathan Chen All rights reserved.
5 * Copyright (c) 2002-2004 M. Warner Losh <imp@FreeBSD.org>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 239 unchanged lines hidden (view full) ---

248 * XXX the south bridge. Disable it it for now.
249 */
250void
251cbb_disable_func_intr(struct cbb_softc *sc)
252{
253#if 0
254 uint8_t reg;
255
256 reg = (exca_getb(&sc->exca[0], EXCA_INTR) & ~EXCA_INTR_IRQ_MASK) |
256 reg = (exca_getb(&sc->exca, EXCA_INTR) & ~EXCA_INTR_IRQ_MASK) |
257 EXCA_INTR_IRQ_RESERVED1;
257 EXCA_INTR_IRQ_RESERVED1;
258 exca_putb(&sc->exca[0], EXCA_INTR, reg);
258 exca_putb(&sc->exca, EXCA_INTR, reg);
259#endif
260}
261
262/*
263 * Enable function interrupts. We turn on function interrupts when the card
264 * requests an interrupt. The PCMCIA standard says that we should set
265 * the lower 4 bits to 0 to route via PCI. Note: we call this for both
266 * CardBus and R2 (PC Card) cases, but it should have no effect on CardBus
267 * cards.
268 */
269static void
270cbb_enable_func_intr(struct cbb_softc *sc)
271{
272 uint8_t reg;
273
259#endif
260}
261
262/*
263 * Enable function interrupts. We turn on function interrupts when the card
264 * requests an interrupt. The PCMCIA standard says that we should set
265 * the lower 4 bits to 0 to route via PCI. Note: we call this for both
266 * CardBus and R2 (PC Card) cases, but it should have no effect on CardBus
267 * cards.
268 */
269static void
270cbb_enable_func_intr(struct cbb_softc *sc)
271{
272 uint8_t reg;
273
274 reg = (exca_getb(&sc->exca[0], EXCA_INTR) & ~EXCA_INTR_IRQ_MASK) |
274 reg = (exca_getb(&sc->exca, EXCA_INTR) & ~EXCA_INTR_IRQ_MASK) |
275 EXCA_INTR_IRQ_NONE;
275 EXCA_INTR_IRQ_NONE;
276 exca_putb(&sc->exca[0], EXCA_INTR, reg);
277 PCI_MASK_CONFIG(sc->dev, CBBR_BRIDGECTRL,
278 & ~CBBM_BRIDGECTRL_INTR_IREQ_ISA_EN, 2);
276 exca_putb(&sc->exca, EXCA_INTR, reg);
279}
280
281int
282cbb_detach(device_t brdev)
283{
284 struct cbb_softc *sc = device_get_softc(brdev);
285 device_t *devlist;
286 int tmp, tries, error, numdevs;

--- 30 unchanged lines hidden (view full) ---

317 for (tmp = 0; tmp < numdevs; tmp++)
318 device_delete_child(brdev, devlist[tmp]);
319 free(devlist, M_TEMP);
320
321 /* Turn off the interrupts */
322 cbb_set(sc, CBB_SOCKET_MASK, 0);
323
324 /* reset 16-bit pcmcia bus */
277}
278
279int
280cbb_detach(device_t brdev)
281{
282 struct cbb_softc *sc = device_get_softc(brdev);
283 device_t *devlist;
284 int tmp, tries, error, numdevs;

--- 30 unchanged lines hidden (view full) ---

315 for (tmp = 0; tmp < numdevs; tmp++)
316 device_delete_child(brdev, devlist[tmp]);
317 free(devlist, M_TEMP);
318
319 /* Turn off the interrupts */
320 cbb_set(sc, CBB_SOCKET_MASK, 0);
321
322 /* reset 16-bit pcmcia bus */
325 exca_clrb(&sc->exca[0], EXCA_INTR, EXCA_INTR_RESET);
323 exca_clrb(&sc->exca, EXCA_INTR, EXCA_INTR_RESET);
326
327 /* turn off power */
328 cbb_power(brdev, CARD_OFF);
329
330 /* Ack the interrupt */
331 cbb_set(sc, CBB_SOCKET_EVENT, 0xffffffff);
332
333 /*

--- 103 unchanged lines hidden (view full) ---

437}
438
439void
440cbb_child_detached(device_t brdev, device_t child)
441{
442 struct cbb_softc *sc = device_get_softc(brdev);
443
444 /* I'm not sure we even need this */
324
325 /* turn off power */
326 cbb_power(brdev, CARD_OFF);
327
328 /* Ack the interrupt */
329 cbb_set(sc, CBB_SOCKET_EVENT, 0xffffffff);
330
331 /*

--- 103 unchanged lines hidden (view full) ---

435}
436
437void
438cbb_child_detached(device_t brdev, device_t child)
439{
440 struct cbb_softc *sc = device_get_softc(brdev);
441
442 /* I'm not sure we even need this */
445 if (child != sc->cbdev && child != sc->exca[0].pccarddev)
443 if (child != sc->cbdev && child != sc->exca.pccarddev)
446 device_printf(brdev, "Unknown child detached: %s\n",
447 device_get_nameunit(child));
448}
449
450/************************************************************************/
451/* Kthreads */
452/************************************************************************/
453

--- 90 unchanged lines hidden (view full) ---

544
545 sockevent = cbb_get(sc, CBB_SOCKET_EVENT);
546 sockstate = cbb_get(sc, CBB_SOCKET_STATE);
547
548 DEVPRINTF((sc->dev, "card inserted: event=0x%08x, state=%08x\n",
549 sockevent, sockstate));
550
551 if (sockstate & CBB_STATE_R2_CARD) {
444 device_printf(brdev, "Unknown child detached: %s\n",
445 device_get_nameunit(child));
446}
447
448/************************************************************************/
449/* Kthreads */
450/************************************************************************/
451

--- 90 unchanged lines hidden (view full) ---

542
543 sockevent = cbb_get(sc, CBB_SOCKET_EVENT);
544 sockstate = cbb_get(sc, CBB_SOCKET_STATE);
545
546 DEVPRINTF((sc->dev, "card inserted: event=0x%08x, state=%08x\n",
547 sockevent, sockstate));
548
549 if (sockstate & CBB_STATE_R2_CARD) {
552 if (device_is_attached(sc->exca[0].pccarddev)) {
550 if (device_is_attached(sc->exca.pccarddev)) {
553 sc->flags |= CBB_16BIT_CARD;
551 sc->flags |= CBB_16BIT_CARD;
554 exca_insert(&sc->exca[0]);
552 exca_insert(&sc->exca);
555 } else {
556 device_printf(sc->dev,
557 "16-bit card inserted, but no pccard bus.\n");
558 }
559 } else if (sockstate & CBB_STATE_CB_CARD) {
560 if (device_is_attached(sc->cbdev)) {
561 sc->flags &= ~CBB_16BIT_CARD;
562 CARD_ATTACH_CARD(sc->cbdev);

--- 10 unchanged lines hidden (view full) ---

573 }
574}
575
576static void
577cbb_removal(struct cbb_softc *sc)
578{
579 sc->cardok = 0;
580 if (sc->flags & CBB_16BIT_CARD) {
553 } else {
554 device_printf(sc->dev,
555 "16-bit card inserted, but no pccard bus.\n");
556 }
557 } else if (sockstate & CBB_STATE_CB_CARD) {
558 if (device_is_attached(sc->cbdev)) {
559 sc->flags &= ~CBB_16BIT_CARD;
560 CARD_ATTACH_CARD(sc->cbdev);

--- 10 unchanged lines hidden (view full) ---

571 }
572}
573
574static void
575cbb_removal(struct cbb_softc *sc)
576{
577 sc->cardok = 0;
578 if (sc->flags & CBB_16BIT_CARD) {
581 exca_removal(&sc->exca[0]);
579 exca_removal(&sc->exca);
582 } else {
583 if (device_is_attached(sc->cbdev))
584 CARD_DETACH_CARD(sc->cbdev);
585 }
586 cbb_destroy_res(sc);
587}
588
589/************************************************************************/

--- 113 unchanged lines hidden (view full) ---

703 * (because IRQ1 is selected), and IRQ1 won't be asserted
704 * because our controllers don't generate IRQ1.
705 *
706 * Other, non O2Micro controllers will generate irq 1 in some
707 * situations, so we can't do this hack for everybody. Reports of
708 * keyboard controller's interrupts being suppressed occurred when
709 * we did this.
710 */
580 } else {
581 if (device_is_attached(sc->cbdev))
582 CARD_DETACH_CARD(sc->cbdev);
583 }
584 cbb_destroy_res(sc);
585}
586
587/************************************************************************/

--- 113 unchanged lines hidden (view full) ---

701 * (because IRQ1 is selected), and IRQ1 won't be asserted
702 * because our controllers don't generate IRQ1.
703 *
704 * Other, non O2Micro controllers will generate irq 1 in some
705 * situations, so we can't do this hack for everybody. Reports of
706 * keyboard controller's interrupts being suppressed occurred when
707 * we did this.
708 */
711 reg = exca_getb(&sc->exca[0], EXCA_INTR);
712 exca_putb(&sc->exca[0], EXCA_INTR, (reg & 0xf0) | 1);
709 reg = exca_getb(&sc->exca, EXCA_INTR);
710 exca_putb(&sc->exca, EXCA_INTR, (reg & 0xf0) | 1);
713 return (reg);
714}
715
716/*
717 * Restore the damage that cbb_o2micro_power_hack does to EXCA_INTR so
718 * we don't have an interrupt storm on power on. This has the effect of
719 * disabling card status change interrupts for the duration of poweron.
720 */
721static void
722cbb_o2micro_power_hack2(struct cbb_softc *sc, uint8_t reg)
723{
711 return (reg);
712}
713
714/*
715 * Restore the damage that cbb_o2micro_power_hack does to EXCA_INTR so
716 * we don't have an interrupt storm on power on. This has the effect of
717 * disabling card status change interrupts for the duration of poweron.
718 */
719static void
720cbb_o2micro_power_hack2(struct cbb_softc *sc, uint8_t reg)
721{
724 exca_putb(&sc->exca[0], EXCA_INTR, reg);
722 exca_putb(&sc->exca, EXCA_INTR, reg);
725}
726
727int
728cbb_power(device_t brdev, int volts)
729{
730 uint32_t status, sock_ctrl, reg_ctrl, mask;
731 struct cbb_softc *sc = device_get_softc(brdev);
732 int cnt, sane;

--- 183 unchanged lines hidden (view full) ---

916static int
917cbb_do_power(device_t brdev)
918{
919 struct cbb_softc *sc = device_get_softc(brdev);
920 uint32_t voltage, curpwr;
921 uint32_t status;
922
923 /* Don't enable OE (output enable) until power stable */
723}
724
725int
726cbb_power(device_t brdev, int volts)
727{
728 uint32_t status, sock_ctrl, reg_ctrl, mask;
729 struct cbb_softc *sc = device_get_softc(brdev);
730 int cnt, sane;

--- 183 unchanged lines hidden (view full) ---

914static int
915cbb_do_power(device_t brdev)
916{
917 struct cbb_softc *sc = device_get_softc(brdev);
918 uint32_t voltage, curpwr;
919 uint32_t status;
920
921 /* Don't enable OE (output enable) until power stable */
924 exca_clrb(&sc->exca[0], EXCA_PWRCTL, EXCA_PWRCTL_OE);
922 exca_clrb(&sc->exca, EXCA_PWRCTL, EXCA_PWRCTL_OE);
925
926 voltage = cbb_detect_voltage(brdev);
927 curpwr = cbb_current_voltage(brdev);
928 status = cbb_get(sc, CBB_SOCKET_STATE);
929 if ((status & CBB_STATE_POWER_CYCLE) && (voltage & curpwr))
930 return 0;
931 /* Prefer lowest voltage supported */
932 cbb_power(brdev, CARD_OFF);

--- 374 unchanged lines hidden (view full) ---

1307 int err;
1308
1309 DPRINTF(("cbb_pcic_socket_enable:\n"));
1310
1311 /* power down/up the socket to reset */
1312 err = cbb_do_power(brdev);
1313 if (err)
1314 return (err);
923
924 voltage = cbb_detect_voltage(brdev);
925 curpwr = cbb_current_voltage(brdev);
926 status = cbb_get(sc, CBB_SOCKET_STATE);
927 if ((status & CBB_STATE_POWER_CYCLE) && (voltage & curpwr))
928 return 0;
929 /* Prefer lowest voltage supported */
930 cbb_power(brdev, CARD_OFF);

--- 374 unchanged lines hidden (view full) ---

1305 int err;
1306
1307 DPRINTF(("cbb_pcic_socket_enable:\n"));
1308
1309 /* power down/up the socket to reset */
1310 err = cbb_do_power(brdev);
1311 if (err)
1312 return (err);
1315 exca_reset(&sc->exca[0], child);
1313 exca_reset(&sc->exca, child);
1316
1317 return (0);
1318}
1319
1320static int
1321cbb_pcic_power_disable_socket(device_t brdev, device_t child)
1322{
1323 struct cbb_softc *sc = device_get_softc(brdev);
1324
1325 DPRINTF(("cbb_pcic_socket_disable\n"));
1326
1327 /* Turn off the card's interrupt and leave it in reset, wait 10ms */
1314
1315 return (0);
1316}
1317
1318static int
1319cbb_pcic_power_disable_socket(device_t brdev, device_t child)
1320{
1321 struct cbb_softc *sc = device_get_softc(brdev);
1322
1323 DPRINTF(("cbb_pcic_socket_disable\n"));
1324
1325 /* Turn off the card's interrupt and leave it in reset, wait 10ms */
1328 exca_putb(&sc->exca[0], EXCA_INTR, 0);
1326 exca_putb(&sc->exca, EXCA_INTR, 0);
1329 pause("cbbP1", hz / 100);
1330
1331 /* power down the socket */
1332 cbb_power(brdev, CARD_OFF);
1327 pause("cbbP1", hz / 100);
1328
1329 /* power down the socket */
1330 cbb_power(brdev, CARD_OFF);
1333 exca_putb(&sc->exca[0], EXCA_PWRCTL, 0);
1331 exca_putb(&sc->exca, EXCA_PWRCTL, 0);
1334
1335 /* wait 300ms until power fails (Tpf). */
1336 pause("cbbP2", hz * 300 / 1000);
1337
1338 /* enable CSC interrupts */
1332
1333 /* wait 300ms until power fails (Tpf). */
1334 pause("cbbP2", hz * 300 / 1000);
1335
1336 /* enable CSC interrupts */
1339 exca_putb(&sc->exca[0], EXCA_INTR, EXCA_INTR_ENABLE);
1337 exca_putb(&sc->exca, EXCA_INTR, EXCA_INTR_ENABLE);
1340 return (0);
1341}
1342
1343/************************************************************************/
1344/* POWER methods */
1345/************************************************************************/
1346
1347int

--- 17 unchanged lines hidden (view full) ---

1365
1366static int
1367cbb_pcic_activate_resource(device_t brdev, device_t child, int type, int rid,
1368 struct resource *res)
1369{
1370 struct cbb_softc *sc = device_get_softc(brdev);
1371 int error;
1372
1338 return (0);
1339}
1340
1341/************************************************************************/
1342/* POWER methods */
1343/************************************************************************/
1344
1345int

--- 17 unchanged lines hidden (view full) ---

1363
1364static int
1365cbb_pcic_activate_resource(device_t brdev, device_t child, int type, int rid,
1366 struct resource *res)
1367{
1368 struct cbb_softc *sc = device_get_softc(brdev);
1369 int error;
1370
1373 error = exca_activate_resource(&sc->exca[0], child, type, rid, res);
1371 error = exca_activate_resource(&sc->exca, child, type, rid, res);
1374 if (error == 0)
1375 cbb_activate_window(brdev, type);
1376 return (error);
1377}
1378
1379static int
1380cbb_pcic_deactivate_resource(device_t brdev, device_t child, int type,
1381 int rid, struct resource *res)
1382{
1383 struct cbb_softc *sc = device_get_softc(brdev);
1372 if (error == 0)
1373 cbb_activate_window(brdev, type);
1374 return (error);
1375}
1376
1377static int
1378cbb_pcic_deactivate_resource(device_t brdev, device_t child, int type,
1379 int rid, struct resource *res)
1380{
1381 struct cbb_softc *sc = device_get_softc(brdev);
1384 return (exca_deactivate_resource(&sc->exca[0], child, type, rid, res));
1382 return (exca_deactivate_resource(&sc->exca, child, type, rid, res));
1385}
1386
1387static struct resource *
1388cbb_pcic_alloc_resource(device_t brdev, device_t child, int type, int *rid,
1389 rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
1390{
1391 struct resource *res = NULL;
1392 struct cbb_softc *sc = device_get_softc(brdev);

--- 78 unchanged lines hidden (view full) ---

1471 if (type != SYS_RES_MEMORY)
1472 return (EINVAL);
1473 res = cbb_find_res(sc, type, rid);
1474 if (res == NULL) {
1475 device_printf(brdev,
1476 "set_res_flags: specified rid not found\n");
1477 return (ENOENT);
1478 }
1383}
1384
1385static struct resource *
1386cbb_pcic_alloc_resource(device_t brdev, device_t child, int type, int *rid,
1387 rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
1388{
1389 struct resource *res = NULL;
1390 struct cbb_softc *sc = device_get_softc(brdev);

--- 78 unchanged lines hidden (view full) ---

1469 if (type != SYS_RES_MEMORY)
1470 return (EINVAL);
1471 res = cbb_find_res(sc, type, rid);
1472 if (res == NULL) {
1473 device_printf(brdev,
1474 "set_res_flags: specified rid not found\n");
1475 return (ENOENT);
1476 }
1479 return (exca_mem_set_flags(&sc->exca[0], res, flags));
1477 return (exca_mem_set_flags(&sc->exca, res, flags));
1480}
1481
1482int
1483cbb_pcic_set_memory_offset(device_t brdev, device_t child, int rid,
1484 uint32_t cardaddr, uint32_t *deltap)
1485{
1486 struct cbb_softc *sc = device_get_softc(brdev);
1487 struct resource *res;
1488
1489 res = cbb_find_res(sc, SYS_RES_MEMORY, rid);
1490 if (res == NULL) {
1491 device_printf(brdev,
1492 "set_memory_offset: specified rid not found\n");
1493 return (ENOENT);
1494 }
1478}
1479
1480int
1481cbb_pcic_set_memory_offset(device_t brdev, device_t child, int rid,
1482 uint32_t cardaddr, uint32_t *deltap)
1483{
1484 struct cbb_softc *sc = device_get_softc(brdev);
1485 struct resource *res;
1486
1487 res = cbb_find_res(sc, SYS_RES_MEMORY, rid);
1488 if (res == NULL) {
1489 device_printf(brdev,
1490 "set_memory_offset: specified rid not found\n");
1491 return (ENOENT);
1492 }
1495 return (exca_mem_set_offset(&sc->exca[0], res, cardaddr, deltap));
1493 return (exca_mem_set_offset(&sc->exca, res, cardaddr, deltap));
1496}
1497
1498/************************************************************************/
1499/* BUS Methods */
1500/************************************************************************/
1501
1502
1503int

--- 92 unchanged lines hidden ---
1494}
1495
1496/************************************************************************/
1497/* BUS Methods */
1498/************************************************************************/
1499
1500
1501int

--- 92 unchanged lines hidden ---