1098ca2bdSWarner Losh /*-
24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
3718cf2ccSPedro F. Giffuni *
4f86e6000SWarner Losh * Copyright (c) 2000,2001 Jonathan Chen All rights reserved.
5f86e6000SWarner Losh * Copyright (c) 2003-2004 M. Warner Losh <imp@FreeBSD.org>
60db7e66cSJonathan Chen *
70db7e66cSJonathan Chen * Redistribution and use in source and binary forms, with or without
80db7e66cSJonathan Chen * modification, are permitted provided that the following conditions
90db7e66cSJonathan Chen * are met:
100db7e66cSJonathan Chen * 1. Redistributions of source code must retain the above copyright
11523675f6SWarner Losh * notice, this list of conditions and the following disclaimer.
120db7e66cSJonathan Chen * 2. Redistributions in binary form must reproduce the above copyright
13523675f6SWarner Losh * notice, this list of conditions and the following disclaimer in the
14523675f6SWarner Losh * documentation and/or other materials provided with the distribution.
150db7e66cSJonathan Chen *
160db7e66cSJonathan Chen * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
170db7e66cSJonathan Chen * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
180db7e66cSJonathan Chen * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19523675f6SWarner Losh * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20523675f6SWarner Losh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
210db7e66cSJonathan Chen * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
220db7e66cSJonathan Chen * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
230db7e66cSJonathan Chen * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
240db7e66cSJonathan Chen * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
250db7e66cSJonathan Chen * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
260db7e66cSJonathan Chen * SUCH DAMAGE.
270db7e66cSJonathan Chen */
280db7e66cSJonathan Chen
290db7e66cSJonathan Chen /*
300db7e66cSJonathan Chen * Structure definitions for the Cardbus Bridge driver
310db7e66cSJonathan Chen */
320db7e66cSJonathan Chen
3301d8ff4dSWarner Losh struct cbb_intrhand {
3497caddeeSPaolo Pisati driver_filter_t *filt;
3501d8ff4dSWarner Losh driver_intr_t *intr;
360db7e66cSJonathan Chen void *arg;
3793185c74SWarner Losh struct cbb_softc *sc;
3893185c74SWarner Losh void *cookie;
390db7e66cSJonathan Chen };
400db7e66cSJonathan Chen
41b35cf671SWarner Losh struct cbb_reslist {
42b35cf671SWarner Losh SLIST_ENTRY(cbb_reslist) link;
4363fa9f4cSJonathan Chen struct resource *res;
440db7e66cSJonathan Chen int type;
450db7e66cSJonathan Chen int rid;
4663fa9f4cSJonathan Chen /* note: unlike the regular resource list, there can be
4763fa9f4cSJonathan Chen * duplicate rid's in the same list. However, the
4863fa9f4cSJonathan Chen * combination of rid and res->r_dev should be unique.
4963fa9f4cSJonathan Chen */
5063fa9f4cSJonathan Chen bus_addr_t cardaddr; /* for 16-bit pccard memory */
510db7e66cSJonathan Chen };
520db7e66cSJonathan Chen
53b35cf671SWarner Losh #define CBB_AUTO_OPEN_SMALLHOLE 0x100
540db7e66cSJonathan Chen
55b35cf671SWarner Losh struct cbb_softc {
56c92e45e4SWarner Losh device_t dev;
577b9439d0SWarner Losh struct exca_softc exca;
58c92e45e4SWarner Losh struct resource *base_res;
59c92e45e4SWarner Losh struct resource *irq_res;
60c92e45e4SWarner Losh void *intrhand;
61c92e45e4SWarner Losh bus_space_tag_t bst;
62c92e45e4SWarner Losh bus_space_handle_t bsh;
6355aaf894SMarius Strobl uint32_t domain;
64fef03554SWarner Losh unsigned int pribus;
654edef187SJohn Baldwin struct pcib_secbus bus;
66c92e45e4SWarner Losh struct mtx mtx;
676e878bc7SWarner Losh int cardok;
68c92e45e4SWarner Losh u_int32_t flags;
69b35cf671SWarner Losh #define CBB_16BIT_CARD 0x20000000
70b35cf671SWarner Losh #define CBB_KTHREAD_RUNNING 0x40000000
71b35cf671SWarner Losh #define CBB_KTHREAD_DONE 0x80000000
72c92e45e4SWarner Losh int chipset; /* chipset id */
730db7e66cSJonathan Chen #define CB_UNKNOWN 0 /* NOT Cardbus-PCI bridge */
740db7e66cSJonathan Chen #define CB_TI113X 1 /* TI PCI1130/1131 */
75e4188e91SWarner Losh #define CB_TI12XX 2 /* TI PCI12xx/14xx/44xx/15xx/45xx */
76e4188e91SWarner Losh #define CB_TI125X 3 /* TI PCI1250/1251(B)/1450 */
77e4188e91SWarner Losh #define CB_RF5C47X 4 /* RICOH RF5C475/476/477 */
78e4188e91SWarner Losh #define CB_RF5C46X 5 /* RICOH RF5C465/466/467 */
79e4188e91SWarner Losh #define CB_CIRRUS 6 /* Cirrus Logic CLPD683x */
80e4188e91SWarner Losh #define CB_TOPIC95 7 /* Toshiba ToPIC95 */
81e4188e91SWarner Losh #define CB_TOPIC97 8 /* Toshiba ToPIC97/100 */
82e4e7b5bcSWarner Losh #define CB_O2MICRO 9 /* O2Micro chips */
83b35cf671SWarner Losh SLIST_HEAD(, cbb_reslist) rl;
84c92e45e4SWarner Losh device_t cbdev;
850db7e66cSJonathan Chen struct proc *event_thread;
8693185c74SWarner Losh void (*chipinit)(struct cbb_softc *);
875b9ee137SWarner Losh int powerintr;
88993b1ae2SWarner Losh struct root_hold_token *sc_root_token;
890db7e66cSJonathan Chen };
900db7e66cSJonathan Chen
91af82f62dSJonathan Chen /* result of detect_card */
92af82f62dSJonathan Chen #define CARD_UKN_CARD 0x00
93af82f62dSJonathan Chen #define CARD_5V_CARD 0x01
94af82f62dSJonathan Chen #define CARD_3V_CARD 0x02
95af82f62dSJonathan Chen #define CARD_XV_CARD 0x04
96af82f62dSJonathan Chen #define CARD_YV_CARD 0x08
97af82f62dSJonathan Chen
98af82f62dSJonathan Chen /* for power_socket */
99bb22b141SWarner Losh #define CARD_VCC(X) (X)
100bb22b141SWarner Losh #define CARD_VPP_VCC 0xf0
101bb22b141SWarner Losh #define CARD_VCCMASK 0xf
102bb22b141SWarner Losh #define CARD_VCCSHIFT 0
103bb22b141SWarner Losh #define XV 2
104bb22b141SWarner Losh #define YV 1
105bb22b141SWarner Losh
106bb22b141SWarner Losh #define CARD_OFF (CARD_VCC(0))
10793185c74SWarner Losh
10893185c74SWarner Losh extern int cbb_debug;
10993185c74SWarner Losh
11093185c74SWarner Losh int cbb_activate_resource(device_t brdev, device_t child,
1112baed46eSJohn Baldwin struct resource *r);
11293185c74SWarner Losh struct resource *cbb_alloc_resource(device_t brdev, device_t child,
1132dd1bdf1SJustin Hibbits int type, int *rid, rman_res_t start, rman_res_t end, rman_res_t count,
11493185c74SWarner Losh u_int flags);
11593185c74SWarner Losh void cbb_child_detached(device_t brdev, device_t child);
116a620f9a5SWarner Losh int cbb_child_present(device_t parent, device_t child);
11793185c74SWarner Losh int cbb_deactivate_resource(device_t brdev, device_t child,
1182baed46eSJohn Baldwin struct resource *r);
11993185c74SWarner Losh int cbb_detach(device_t brdev);
12093185c74SWarner Losh void cbb_disable_func_intr(struct cbb_softc *sc);
12193185c74SWarner Losh void cbb_driver_added(device_t brdev, driver_t *driver);
12293185c74SWarner Losh void cbb_event_thread(void *arg);
12393185c74SWarner Losh int cbb_pcic_set_memory_offset(device_t brdev, device_t child, int rid,
12493185c74SWarner Losh uint32_t cardaddr, uint32_t *deltap);
12593185c74SWarner Losh int cbb_pcic_set_res_flags(device_t brdev, device_t child, int type,
126a620f9a5SWarner Losh int rid, u_long flags);
12793185c74SWarner Losh int cbb_power(device_t brdev, int volts);
12893185c74SWarner Losh int cbb_power_enable_socket(device_t brdev, device_t child);
129a620f9a5SWarner Losh int cbb_power_disable_socket(device_t brdev, device_t child);
13093185c74SWarner Losh int cbb_read_ivar(device_t brdev, device_t child, int which,
13193185c74SWarner Losh uintptr_t *result);
13293185c74SWarner Losh int cbb_release_resource(device_t brdev, device_t child,
1339dbf5b0eSJohn Baldwin struct resource *r);
13493185c74SWarner Losh int cbb_setup_intr(device_t dev, device_t child, struct resource *irq,
135ef544f63SPaolo Pisati int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg,
136ef544f63SPaolo Pisati void **cookiep);
13793185c74SWarner Losh int cbb_teardown_intr(device_t dev, device_t child, struct resource *irq,
13893185c74SWarner Losh void *cookie);
13993185c74SWarner Losh int cbb_write_ivar(device_t brdev, device_t child, int which,
14093185c74SWarner Losh uintptr_t value);
14193185c74SWarner Losh
14293185c74SWarner Losh /*
14393185c74SWarner Losh */
14493185c74SWarner Losh static __inline void
cbb_set(struct cbb_softc * sc,uint32_t reg,uint32_t val)14593185c74SWarner Losh cbb_set(struct cbb_softc *sc, uint32_t reg, uint32_t val)
14693185c74SWarner Losh {
14793185c74SWarner Losh bus_space_write_4(sc->bst, sc->bsh, reg, val);
14893185c74SWarner Losh }
14993185c74SWarner Losh
15093185c74SWarner Losh static __inline uint32_t
cbb_get(struct cbb_softc * sc,uint32_t reg)15193185c74SWarner Losh cbb_get(struct cbb_softc *sc, uint32_t reg)
15293185c74SWarner Losh {
15393185c74SWarner Losh return (bus_space_read_4(sc->bst, sc->bsh, reg));
15493185c74SWarner Losh }
15593185c74SWarner Losh
15693185c74SWarner Losh static __inline void
cbb_setb(struct cbb_softc * sc,uint32_t reg,uint32_t bits)15793185c74SWarner Losh cbb_setb(struct cbb_softc *sc, uint32_t reg, uint32_t bits)
15893185c74SWarner Losh {
15993185c74SWarner Losh cbb_set(sc, reg, cbb_get(sc, reg) | bits);
16093185c74SWarner Losh }
16193185c74SWarner Losh
16293185c74SWarner Losh static __inline void
cbb_clrb(struct cbb_softc * sc,uint32_t reg,uint32_t bits)16393185c74SWarner Losh cbb_clrb(struct cbb_softc *sc, uint32_t reg, uint32_t bits)
16493185c74SWarner Losh {
16593185c74SWarner Losh cbb_set(sc, reg, cbb_get(sc, reg) & ~bits);
16693185c74SWarner Losh }
167