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>
16 /* The use of interrupts is not yet ready for prime time */
28 volatile struct csr
*csr_ptr
;
34 static int hw_probe(int skip
);
35 static void hw_init(struct port
*pp
, int devind
);
36 static void do_int(struct port
*pp
);
38 /* SEF functions and variables. */
39 static void sef_local_startup(void);
40 static int sef_cb_init_fresh(int type
, sef_init_info_t
*info
);
42 /*===========================================================================*
44 *===========================================================================*/
45 int main(int argc
, char *argv
[])
51 /* SEF local startup. */
52 env_setargs(argc
, argv
);
57 r
= driver_receive(ANY
, &m
, &ipc_status
);
59 panic("driver_receive failed: %d", r
);
60 printf("ti1225: got message %u from %d\n",
61 m
.m_type
, m
.m_source
);
66 /*===========================================================================*
68 *===========================================================================*/
69 static void sef_local_startup()
71 /* Register init callbacks. */
72 sef_setcb_init_fresh(sef_cb_init_fresh
);
73 sef_setcb_init_lu(sef_cb_init_fresh
);
74 sef_setcb_init_restart(sef_cb_init_fresh
);
76 /* Register live update callbacks. */
77 sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready
);
78 sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard
);
80 /* Let SEF perform startup. */
84 /*===========================================================================*
86 *===========================================================================*/
87 static int sef_cb_init_fresh(int UNUSED(type
), sef_init_info_t
*UNUSED(info
))
89 /* Initialize the ti1225 driver. */
93 if((r
=tsc_calibrate()) != OK
)
94 panic("tsc_calibrate failed: %d", r
);
97 (void) env_parse("instance", "d", 0, &v
, 0, 255);
101 (void) env_parse("debug", "d", 0, &v
, 0, 1);
104 devind
= hw_probe(instance
);
109 hw_init(&port
, devind
);
114 /*===========================================================================*
116 *===========================================================================*/
117 static int hw_probe(int skip
)
124 if (pci_first_dev(&devind
, &vid
, &did
) != 1)
128 if (pci_next_dev(&devind
, &vid
, &did
) != 1)
134 printf("ti1225: found device %04x/%04x\n", vid
, did
);
139 /*===========================================================================*
141 *===========================================================================*/
142 static void hw_init(struct port
*pp
, int devind
)
151 pp
->p_devind
= devind
;
153 printf("hw_init: devind = %d\n", devind
);
157 v16
= pci_attr_r16(devind
, PCI_CR
);
158 printf("ti1225: command register 0x%x\n", v16
);
161 v32
= pci_attr_r32(devind
, TI_CB_BASEADDR
);
163 printf("ti1225: Cardbus/ExCA base address 0x%x\n", v32
);
164 v32
&= PCI_BAR_MEM_MASK
; /* Clear low order bits in base */
167 (struct csr
*) vm_map_phys(SELF
, (void *) v32
, I386_PAGE_SIZE
);
168 if (pp
->csr_ptr
== MAP_FAILED
)
169 panic("hw_init: vm_map_phys failed");
173 v8
= pci_attr_r8(devind
, TI_PCI_BUS_NR
);
174 printf("ti1225: PCI bus number %d\n", v8
);
176 v8
= pci_attr_r8(devind
, TI_CB_BUS_NR
);
180 printf("ti1225: CardBus bus number %d\n", v8
);
181 v8
= pci_attr_r8(devind
, TI_SO_BUS_NR
);
182 printf("ti1225: Subordinate bus number %d\n", v8
);
186 irq
= pci_attr_r8(devind
, PCI_ILR
);
188 printf("ti1225 using IRQ %d\n", irq
);
191 v32
= pci_attr_r32(devind
, TI_LEGACY_BA
);
195 printf("ti1225: PC Card 16-bit legacy-mode base address 0x%x\n",
200 panic("bad legacy-mode base address: %d", v32
);
201 pp
->p_exca_port
= v32
;
205 v32
= pci_attr_r32(devind
, TI_MF_ROUTE
);
206 printf("ti1225: Multifunction routing 0x%08x\n", v32
);
210 pp
->p_hook
= pp
->p_irq
;
211 r
= sys_irqsetpolicy(pp
->p_irq
, 0, &pp
->p_hook
);
213 panic("sys_irqsetpolicy failed: %d", r
);
216 /* Clear CBB_BC_INTEXCA */
217 v16
= pci_attr_r16(devind
, CBB_BRIDGECTRL
);
219 printf("ti1225: Bridge control 0x%04x\n", v16
);
220 v16
&= ~CBB_BC_INTEXCA
;
221 pci_attr_w16(devind
, CBB_BRIDGECTRL
, v16
);
225 v32
= pci_attr_r32(devind
, TI_SYSCTRL
);
226 printf("ti1225: System Control Register 0x%08x\n", v32
);
228 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
229 printf("ti1225: Card Control 0x%02x\n", v8
);
231 v8
= pci_attr_r8(devind
, TI_DEV_CTRL
);
232 printf("ti1225: Device Control 0x%02x\n", v8
);
235 /* Enable socket interrupts */
236 pp
->csr_ptr
->csr_mask
|= CM_PWRMASK
| CM_CDMASK
| CM_CSTSMASK
;
241 r
= sys_irqenable(&pp
->p_hook
);
243 panic("unable enable interrupts: %d", r
);
247 /*===========================================================================*
249 *===========================================================================*/
250 static void do_int(struct port
*pp
)
252 int devind
, vcc_5v
, vcc_3v
, vcc_Xv
, vcc_Yv
,
253 socket_5v
, socket_3v
, socket_Xv
, socket_Yv
;
255 u32_t csr_event
, csr_present
, csr_control
;
262 devind
= pp
->p_devind
;
263 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
266 printf("ti1225: got functional interrupt\n");
267 pci_attr_w8(devind
, TI_CARD_CTRL
, v8
);
272 printf("Socket event: 0x%x\n", pp
->csr_ptr
->csr_event
);
273 printf("Socket mask: 0x%x\n", pp
->csr_ptr
->csr_mask
);
276 csr_present
= pp
->csr_ptr
->csr_present
;
277 csr_control
= pp
->csr_ptr
->csr_control
;
279 if ((csr_present
& (CP_CDETECT1
|CP_CDETECT2
)) != 0)
282 printf("do_int: no card present\n");
285 if (csr_present
& CP_BADVCCREQ
)
287 printf("do_int: Bad Vcc request\n");
290 if (csr_present
& CP_DATALOST
)
294 printf("do_int: Data lost\n");
297 if (csr_present
& CP_NOTACARD
)
299 printf("do_int: Not a card\n");
304 if (csr_present
& CP_CBCARD
)
305 printf("do_int: Cardbus card detected\n");
306 if (csr_present
& CP_16BITCARD
)
307 printf("do_int: 16-bit card detected\n");
309 if (csr_present
& CP_PWRCYCLE
)
312 printf("do_int: powered up\n");
315 vcc_5v
= !!(csr_present
& CP_5VCARD
);
316 vcc_3v
= !!(csr_present
& CP_3VCARD
);
317 vcc_Xv
= !!(csr_present
& CP_XVCARD
);
318 vcc_Yv
= !!(csr_present
& CP_YVCARD
);
321 printf("do_int: card supports:%s%s%s%s\n",
322 vcc_5v
? " 5V" : "", vcc_3v
? " 3V" : "",
323 vcc_Xv
? " X.X V" : "", vcc_Yv
? " Y.Y V" : "");
325 socket_5v
= !!(csr_present
& CP_5VSOCKET
);
326 socket_3v
= !!(csr_present
& CP_3VSOCKET
);
327 socket_Xv
= !!(csr_present
& CP_XVSOCKET
);
328 socket_Yv
= !!(csr_present
& CP_YVSOCKET
);
331 printf("do_int: socket supports:%s%s%s%s\n",
332 socket_5v
? " 5V" : "", socket_3v
? " 3V" : "",
333 socket_Xv
? " X.X V" : "", socket_Yv
? " Y.Y V" : "");
335 if (vcc_5v
&& socket_5v
)
337 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_5V
;
338 pp
->csr_ptr
->csr_control
= csr_control
;
340 printf("do_int: applying 5V\n");
342 else if (vcc_3v
&& socket_3v
)
344 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_3V
;
345 pp
->csr_ptr
->csr_control
= csr_control
;
347 printf("do_int: applying 3V\n");
349 else if (vcc_Xv
&& socket_Xv
)
351 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_XV
;
352 pp
->csr_ptr
->csr_control
= csr_control
;
353 printf("do_int: applying X.X V\n");
355 else if (vcc_Yv
&& socket_Yv
)
357 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_YV
;
358 pp
->csr_ptr
->csr_control
= csr_control
;
359 printf("do_int: applying Y.Y V\n");
363 printf("do_int: socket and card are not compatible\n");
367 csr_event
= pp
->csr_ptr
->csr_event
;
371 printf("clearing socket event\n");
372 pp
->csr_ptr
->csr_event
= csr_event
;
375 printf("Socket event (cleared): 0x%x\n",
376 pp
->csr_ptr
->csr_event
);
380 devind
= pp
->p_devind
;
381 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
384 printf("ti1225: got functional interrupt\n");
385 pci_attr_w8(devind
, TI_CARD_CTRL
, v8
);
390 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
391 printf("TI_CARD_CTRL: 0x%02x\n", v8
);
394 spin_init(&spin
, 100000);
396 csr_present
= pp
->csr_ptr
->csr_present
;
397 if (csr_present
& CP_PWRCYCLE
)
399 } while (spin_check(&spin
));
401 if (!(csr_present
& CP_PWRCYCLE
))
403 printf("do_int: not powered up?\n");
408 v16
= pci_attr_r16(devind
, CBB_BRIDGECTRL
);
410 pci_attr_w16(devind
, CBB_BRIDGECTRL
, v16
);
412 /* Wait one microsecond. Is this correct? What are the specs? */
415 /* Clear CBB_BC_CRST */
416 v16
= pci_attr_r16(devind
, CBB_BRIDGECTRL
);
418 pci_attr_w16(devind
, CBB_BRIDGECTRL
, v16
);
420 /* Wait one microsecond after clearing the reset line. Is this
421 * correct? What are the specs?
425 pci_rescan_bus(pp
->p_cb_busnr
);
428 r
= sys_irqenable(&pp
->p_hook
);
430 panic("unable enable interrupts: %d", r
);