4 Created: Dec 2005 by Philip Homburg
7 #include <minix/drivers.h>
8 #include <minix/driver.h>
9 #include <machine/pci.h>
10 #include <machine/vm.h>
11 #include <machine/vmparam.h>
17 /* The use of interrupts is not yet ready for prime time */
29 volatile struct csr
*csr_ptr
;
35 static int hw_probe(int skip
);
36 static void hw_init(struct port
*pp
, int devind
);
37 static void do_int(struct port
*pp
);
39 /* SEF functions and variables. */
40 static void sef_local_startup(void);
41 static int sef_cb_init_fresh(int type
, sef_init_info_t
*info
);
43 /*===========================================================================*
45 *===========================================================================*/
46 int main(int argc
, char *argv
[])
52 /* SEF local startup. */
53 env_setargs(argc
, argv
);
58 r
= driver_receive(ANY
, &m
, &ipc_status
);
60 panic("driver_receive failed: %d", r
);
61 printf("ti1225: got message %u from %d\n",
62 m
.m_type
, m
.m_source
);
67 /*===========================================================================*
69 *===========================================================================*/
70 static void sef_local_startup()
72 /* Register init callbacks. */
73 sef_setcb_init_fresh(sef_cb_init_fresh
);
74 sef_setcb_init_lu(sef_cb_init_fresh
);
75 sef_setcb_init_restart(sef_cb_init_fresh
);
77 /* Let SEF perform startup. */
81 /*===========================================================================*
83 *===========================================================================*/
84 static int sef_cb_init_fresh(int UNUSED(type
), sef_init_info_t
*UNUSED(info
))
86 /* Initialize the ti1225 driver. */
90 if((r
=tsc_calibrate()) != OK
)
91 panic("tsc_calibrate failed: %d", r
);
94 (void) env_parse("instance", "d", 0, &v
, 0, 255);
98 (void) env_parse("debug", "d", 0, &v
, 0, 1);
101 devind
= hw_probe(instance
);
106 hw_init(&port
, devind
);
111 /*===========================================================================*
113 *===========================================================================*/
114 static int hw_probe(int skip
)
121 if (pci_first_dev(&devind
, &vid
, &did
) != 1)
125 if (pci_next_dev(&devind
, &vid
, &did
) != 1)
131 printf("ti1225: found device %04x/%04x\n", vid
, did
);
136 /*===========================================================================*
138 *===========================================================================*/
139 static void hw_init(struct port
*pp
, int devind
)
148 pp
->p_devind
= devind
;
150 printf("hw_init: devind = %d\n", devind
);
154 v16
= pci_attr_r16(devind
, PCI_CR
);
155 printf("ti1225: command register 0x%x\n", v16
);
158 v32
= pci_attr_r32(devind
, TI_CB_BASEADDR
);
160 printf("ti1225: Cardbus/ExCA base address 0x%x\n", v32
);
161 v32
&= PCI_BAR_MEM_MASK
; /* Clear low order bits in base */
164 (struct csr
*) vm_map_phys(SELF
, (void *) v32
, PAGE_SIZE
);
165 if (pp
->csr_ptr
== MAP_FAILED
)
166 panic("hw_init: vm_map_phys failed");
170 v8
= pci_attr_r8(devind
, TI_PCI_BUS_NR
);
171 printf("ti1225: PCI bus number %d\n", v8
);
173 v8
= pci_attr_r8(devind
, TI_CB_BUS_NR
);
177 printf("ti1225: CardBus bus number %d\n", v8
);
178 v8
= pci_attr_r8(devind
, TI_SO_BUS_NR
);
179 printf("ti1225: Subordinate bus number %d\n", v8
);
183 irq
= pci_attr_r8(devind
, PCI_ILR
);
185 printf("ti1225 using IRQ %d\n", irq
);
188 v32
= pci_attr_r32(devind
, TI_LEGACY_BA
);
192 printf("ti1225: PC Card 16-bit legacy-mode base address 0x%x\n",
197 panic("bad legacy-mode base address: %d", v32
);
198 pp
->p_exca_port
= v32
;
202 v32
= pci_attr_r32(devind
, TI_MF_ROUTE
);
203 printf("ti1225: Multifunction routing 0x%08x\n", v32
);
207 pp
->p_hook
= pp
->p_irq
;
208 r
= sys_irqsetpolicy(pp
->p_irq
, 0, &pp
->p_hook
);
210 panic("sys_irqsetpolicy failed: %d", r
);
213 /* Clear CBB_BC_INTEXCA */
214 v16
= pci_attr_r16(devind
, CBB_BRIDGECTRL
);
216 printf("ti1225: Bridge control 0x%04x\n", v16
);
217 v16
&= ~CBB_BC_INTEXCA
;
218 pci_attr_w16(devind
, CBB_BRIDGECTRL
, v16
);
222 v32
= pci_attr_r32(devind
, TI_SYSCTRL
);
223 printf("ti1225: System Control Register 0x%08x\n", v32
);
225 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
226 printf("ti1225: Card Control 0x%02x\n", v8
);
228 v8
= pci_attr_r8(devind
, TI_DEV_CTRL
);
229 printf("ti1225: Device Control 0x%02x\n", v8
);
232 /* Enable socket interrupts */
233 pp
->csr_ptr
->csr_mask
|= CM_PWRMASK
| CM_CDMASK
| CM_CSTSMASK
;
238 r
= sys_irqenable(&pp
->p_hook
);
240 panic("unable enable interrupts: %d", r
);
244 /*===========================================================================*
246 *===========================================================================*/
247 static void do_int(struct port
*pp
)
249 int devind
, vcc_5v
, vcc_3v
, vcc_Xv
, vcc_Yv
,
250 socket_5v
, socket_3v
, socket_Xv
, socket_Yv
;
252 u32_t csr_event
, csr_present
, csr_control
;
259 devind
= pp
->p_devind
;
260 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
263 printf("ti1225: got functional interrupt\n");
264 pci_attr_w8(devind
, TI_CARD_CTRL
, v8
);
269 printf("Socket event: 0x%x\n", pp
->csr_ptr
->csr_event
);
270 printf("Socket mask: 0x%x\n", pp
->csr_ptr
->csr_mask
);
273 csr_present
= pp
->csr_ptr
->csr_present
;
274 csr_control
= pp
->csr_ptr
->csr_control
;
276 if ((csr_present
& (CP_CDETECT1
|CP_CDETECT2
)) != 0)
279 printf("do_int: no card present\n");
282 if (csr_present
& CP_BADVCCREQ
)
284 printf("do_int: Bad Vcc request\n");
287 if (csr_present
& CP_DATALOST
)
291 printf("do_int: Data lost\n");
294 if (csr_present
& CP_NOTACARD
)
296 printf("do_int: Not a card\n");
301 if (csr_present
& CP_CBCARD
)
302 printf("do_int: Cardbus card detected\n");
303 if (csr_present
& CP_16BITCARD
)
304 printf("do_int: 16-bit card detected\n");
306 if (csr_present
& CP_PWRCYCLE
)
309 printf("do_int: powered up\n");
312 vcc_5v
= !!(csr_present
& CP_5VCARD
);
313 vcc_3v
= !!(csr_present
& CP_3VCARD
);
314 vcc_Xv
= !!(csr_present
& CP_XVCARD
);
315 vcc_Yv
= !!(csr_present
& CP_YVCARD
);
318 printf("do_int: card supports:%s%s%s%s\n",
319 vcc_5v
? " 5V" : "", vcc_3v
? " 3V" : "",
320 vcc_Xv
? " X.X V" : "", vcc_Yv
? " Y.Y V" : "");
322 socket_5v
= !!(csr_present
& CP_5VSOCKET
);
323 socket_3v
= !!(csr_present
& CP_3VSOCKET
);
324 socket_Xv
= !!(csr_present
& CP_XVSOCKET
);
325 socket_Yv
= !!(csr_present
& CP_YVSOCKET
);
328 printf("do_int: socket supports:%s%s%s%s\n",
329 socket_5v
? " 5V" : "", socket_3v
? " 3V" : "",
330 socket_Xv
? " X.X V" : "", socket_Yv
? " Y.Y V" : "");
332 if (vcc_5v
&& socket_5v
)
334 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_5V
;
335 pp
->csr_ptr
->csr_control
= csr_control
;
337 printf("do_int: applying 5V\n");
339 else if (vcc_3v
&& socket_3v
)
341 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_3V
;
342 pp
->csr_ptr
->csr_control
= csr_control
;
344 printf("do_int: applying 3V\n");
346 else if (vcc_Xv
&& socket_Xv
)
348 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_XV
;
349 pp
->csr_ptr
->csr_control
= csr_control
;
350 printf("do_int: applying X.X V\n");
352 else if (vcc_Yv
&& socket_Yv
)
354 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_YV
;
355 pp
->csr_ptr
->csr_control
= csr_control
;
356 printf("do_int: applying Y.Y V\n");
360 printf("do_int: socket and card are not compatible\n");
364 csr_event
= pp
->csr_ptr
->csr_event
;
368 printf("clearing socket event\n");
369 pp
->csr_ptr
->csr_event
= csr_event
;
372 printf("Socket event (cleared): 0x%x\n",
373 pp
->csr_ptr
->csr_event
);
377 devind
= pp
->p_devind
;
378 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
381 printf("ti1225: got functional interrupt\n");
382 pci_attr_w8(devind
, TI_CARD_CTRL
, v8
);
387 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
388 printf("TI_CARD_CTRL: 0x%02x\n", v8
);
391 spin_init(&spin
, 100000);
393 csr_present
= pp
->csr_ptr
->csr_present
;
394 if (csr_present
& CP_PWRCYCLE
)
396 } while (spin_check(&spin
));
398 if (!(csr_present
& CP_PWRCYCLE
))
400 printf("do_int: not powered up?\n");
405 v16
= pci_attr_r16(devind
, CBB_BRIDGECTRL
);
407 pci_attr_w16(devind
, CBB_BRIDGECTRL
, v16
);
409 /* Wait one microsecond. Is this correct? What are the specs? */
412 /* Clear CBB_BC_CRST */
413 v16
= pci_attr_r16(devind
, CBB_BRIDGECTRL
);
415 pci_attr_w16(devind
, CBB_BRIDGECTRL
, v16
);
417 /* Wait one microsecond after clearing the reset line. Is this
418 * correct? What are the specs?
422 pci_rescan_bus(pp
->p_cb_busnr
);
425 r
= sys_irqenable(&pp
->p_hook
);
427 panic("unable enable interrupts: %d", r
);