1 /* $Id: njata_cardbus.c,v 1.8 2009/05/12 14:17:31 cegger Exp $ */
4 * Copyright (c) 2006 ITOH Yasufumi <itohy@NetBSD.org>.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS''
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26 * THE POSSIBILITY OF SUCH DAMAGE.
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: njata_cardbus.c,v 1.7 2008/06/24 19:44:52 drochner Exp $");
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/kernel.h>
35 #include <sys/device.h>
40 #include <dev/cardbus/cardbusvar.h>
41 #include <dev/pci/pcidevs.h>
43 #include <dev/ata/atavar.h>
44 #include <dev/ic/wdcreg.h>
45 #include <dev/ic/wdcvar.h>
47 #include <dev/ic/ninjaata32reg.h>
48 #include <dev/ic/ninjaata32var.h>
50 #define NJATA32_CARDBUS_BASEADDR_IO CARDBUS_BASE0_REG
51 #define NJATA32_CARDBUS_BASEADDR_MEM CARDBUS_BASE1_REG
53 struct njata32_cardbus_softc
{
54 struct njata32_softc sc_njata32
;
56 /* CardBus-specific goo */
57 cardbus_devfunc_t sc_ct
; /* our CardBus devfuncs */
58 cardbus_intr_line_t sc_intrline
; /* our interrupt line */
61 bus_space_handle_t sc_regmaph
;
62 bus_size_t sc_regmap_size
;
65 static const struct njata32_cardbus_product
*njata_cardbus_lookup
66 (const struct cardbus_attach_args
*);
67 static int njata_cardbus_match(device_t
, cfdata_t
, void *);
68 static void njata_cardbus_attach(device_t
, device_t
, void *);
69 static int njata_cardbus_detach(device_t
, int);
71 CFATTACH_DECL_NEW(njata_cardbus
, sizeof(struct njata32_cardbus_softc
),
72 njata_cardbus_match
, njata_cardbus_attach
, njata_cardbus_detach
, NULL
);
74 static const struct njata32_cardbus_product
{
75 cardbus_vendor_id_t p_vendor
;
76 cardbus_product_id_t p_product
;
78 #define NJATA32_FL_IOMAP_ONLY 1 /* registers are only in the I/O map */
79 } njata32_cardbus_products
[] = {
80 { PCI_VENDOR_IODATA
, PCI_PRODUCT_IODATA_CBIDE2
,
82 { PCI_VENDOR_WORKBIT
, PCI_PRODUCT_WORKBIT_NJATA32BI
,
84 { PCI_VENDOR_WORKBIT
, PCI_PRODUCT_WORKBIT_NJATA32BI_KME
,
86 { PCI_VENDOR_WORKBIT
, PCI_PRODUCT_WORKBIT_NPATA32_CF32A
,
87 NJATA32_FL_IOMAP_ONLY
},
88 { PCI_VENDOR_WORKBIT
, PCI_PRODUCT_WORKBIT_NPATA32_CF32A_BUFFALO
,
89 NJATA32_FL_IOMAP_ONLY
},
90 { PCI_VENDOR_WORKBIT
, PCI_PRODUCT_WORKBIT_NPATA32_KME
,
91 NJATA32_FL_IOMAP_ONLY
},
93 { PCI_VENDOR_INVALID
, 0,
97 static const struct njata32_cardbus_product
*
98 njata_cardbus_lookup(const struct cardbus_attach_args
*ca
)
100 const struct njata32_cardbus_product
*p
;
102 for (p
= njata32_cardbus_products
;
103 p
->p_vendor
!= PCI_VENDOR_INVALID
; p
++) {
104 if (CARDBUS_VENDOR(ca
->ca_id
) == p
->p_vendor
&&
105 CARDBUS_PRODUCT(ca
->ca_id
) == p
->p_product
)
113 njata_cardbus_match(device_t parent
, cfdata_t match
, void *aux
)
115 struct cardbus_attach_args
*ca
= aux
;
117 if (njata_cardbus_lookup(ca
))
124 njata_cardbus_attach(device_t parent
, device_t self
, void *aux
)
126 struct cardbus_attach_args
*ca
= aux
;
127 struct njata32_cardbus_softc
*csc
= device_private(self
);
128 struct njata32_softc
*sc
= &csc
->sc_njata32
;
129 const struct njata32_cardbus_product
*prod
;
130 cardbus_devfunc_t ct
= ca
->ca_ct
;
131 cardbus_chipset_tag_t cc
= ct
->ct_cc
;
132 cardbus_function_tag_t cf
= ct
->ct_cf
;
135 uint8_t latency
= 0x20;
137 sc
->sc_wdcdev
.sc_atac
.atac_dev
= self
;
138 if ((prod
= njata_cardbus_lookup(ca
)) == NULL
)
139 panic("njata_cardbus_attach");
141 aprint_normal(": Workbit NinjaATA-32 IDE controller\n");
144 csc
->sc_tag
= ca
->ca_tag
;
145 csc
->sc_intrline
= ca
->ca_intrline
;
150 csr
= PCI_COMMAND_MASTER_ENABLE
;
154 * Try memory map first, and then try I/O.
156 if ((prod
->p_flags
& NJATA32_FL_IOMAP_ONLY
) == 0 &&
157 Cardbus_mapreg_map(csc
->sc_ct
, NJATA32_CARDBUS_BASEADDR_MEM
,
158 PCI_MAPREG_TYPE_MEM
|PCI_MAPREG_MEM_TYPE_32BIT
, 0,
159 &NJATA32_REGT(sc
), &csc
->sc_regmaph
, NULL
, &csc
->sc_regmap_size
)
161 if (bus_space_subregion(NJATA32_REGT(sc
), csc
->sc_regmaph
,
162 NJATA32_MEMOFFSET_REG
, NJATA32_REGSIZE
, &NJATA32_REGH(sc
))
164 /* failed -- undo map and try I/O */
165 Cardbus_mapreg_unmap(csc
->sc_ct
,
166 NJATA32_CARDBUS_BASEADDR_MEM
, NJATA32_REGT(sc
),
167 csc
->sc_regmaph
, csc
->sc_regmap_size
);
171 aprint_normal("%s: memory space mapped, size %u\n",
172 NJATA32NAME(sc
), (unsigned)csc
->sc_regmap_size
);
174 csr
|= PCI_COMMAND_MEM_ENABLE
;
175 sc
->sc_flags
= NJATA32_MEM_MAPPED
;
176 (*ct
->ct_cf
->cardbus_ctrl
)(cc
, CARDBUS_MEM_ENABLE
);
179 if (Cardbus_mapreg_map(csc
->sc_ct
, NJATA32_CARDBUS_BASEADDR_IO
,
180 PCI_MAPREG_TYPE_IO
, 0, &NJATA32_REGT(sc
),
181 &NJATA32_REGH(sc
), NULL
, &csc
->sc_regmap_size
) == 0) {
183 aprint_normal("%s: io space mapped, size %u\n",
184 NJATA32NAME(sc
), (unsigned)csc
->sc_regmap_size
);
186 csr
|= PCI_COMMAND_IO_ENABLE
;
187 sc
->sc_flags
= NJATA32_IO_MAPPED
;
188 (*ct
->ct_cf
->cardbus_ctrl
)(cc
, CARDBUS_IO_ENABLE
);
190 aprint_error("%s: unable to map device registers\n",
196 /* Make sure the right access type is on the CardBus bridge. */
197 (*ct
->ct_cf
->cardbus_ctrl
)(cc
, CARDBUS_BM_ENABLE
);
199 /* Enable the appropriate bits in the PCI CSR. */
200 reg
= cardbus_conf_read(cc
, cf
, ca
->ca_tag
, PCI_COMMAND_STATUS_REG
);
201 reg
&= ~(PCI_COMMAND_IO_ENABLE
|PCI_COMMAND_MEM_ENABLE
);
203 cardbus_conf_write(cc
, cf
, ca
->ca_tag
, PCI_COMMAND_STATUS_REG
, reg
);
206 * Make sure the latency timer is set to some reasonable
209 reg
= cardbus_conf_read(cc
, cf
, ca
->ca_tag
, CARDBUS_BHLC_REG
);
210 if (CARDBUS_LATTIMER(reg
) < latency
) {
211 reg
&= ~(CARDBUS_LATTIMER_MASK
<< CARDBUS_LATTIMER_SHIFT
);
212 reg
|= (latency
<< CARDBUS_LATTIMER_SHIFT
);
213 cardbus_conf_write(cc
, cf
, ca
->ca_tag
, CARDBUS_BHLC_REG
, reg
);
216 sc
->sc_dmat
= ca
->ca_dmat
;
219 * Establish the interrupt.
221 sc
->sc_ih
= cardbus_intr_establish(cc
, cf
, ca
->ca_intrline
, IPL_BIO
,
223 if (sc
->sc_ih
== NULL
) {
224 aprint_error("%s: unable to establish interrupt\n",
234 njata_cardbus_detach(device_t self
, int flags
)
236 struct njata32_cardbus_softc
*csc
= device_private(self
);
237 struct njata32_softc
*sc
= &csc
->sc_njata32
;
240 rv
= njata32_detach(sc
, flags
);
245 cardbus_intr_disestablish(csc
->sc_ct
->ct_cc
,
246 csc
->sc_ct
->ct_cf
, sc
->sc_ih
);
248 if (sc
->sc_flags
& NJATA32_IO_MAPPED
)
249 Cardbus_mapreg_unmap(csc
->sc_ct
, NJATA32_CARDBUS_BASEADDR_IO
,
250 NJATA32_REGT(sc
), NJATA32_REGH(sc
), csc
->sc_regmap_size
);
251 if (sc
->sc_flags
& NJATA32_MEM_MAPPED
)
252 Cardbus_mapreg_unmap(csc
->sc_ct
, NJATA32_CARDBUS_BASEADDR_MEM
,
253 NJATA32_REGT(sc
), csc
->sc_regmaph
, csc
->sc_regmap_size
);