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 /* Register live update callbacks. */
78 sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready
);
79 sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard
);
81 /* Let SEF perform startup. */
85 /*===========================================================================*
87 *===========================================================================*/
88 static int sef_cb_init_fresh(int UNUSED(type
), sef_init_info_t
*UNUSED(info
))
90 /* Initialize the ti1225 driver. */
94 if((r
=tsc_calibrate()) != OK
)
95 panic("tsc_calibrate failed: %d", r
);
98 (void) env_parse("instance", "d", 0, &v
, 0, 255);
102 (void) env_parse("debug", "d", 0, &v
, 0, 1);
105 devind
= hw_probe(instance
);
110 hw_init(&port
, devind
);
115 /*===========================================================================*
117 *===========================================================================*/
118 static int hw_probe(int skip
)
125 if (pci_first_dev(&devind
, &vid
, &did
) != 1)
129 if (pci_next_dev(&devind
, &vid
, &did
) != 1)
135 printf("ti1225: found device %04x/%04x\n", vid
, did
);
140 /*===========================================================================*
142 *===========================================================================*/
143 static void hw_init(struct port
*pp
, int devind
)
152 pp
->p_devind
= devind
;
154 printf("hw_init: devind = %d\n", devind
);
158 v16
= pci_attr_r16(devind
, PCI_CR
);
159 printf("ti1225: command register 0x%x\n", v16
);
162 v32
= pci_attr_r32(devind
, TI_CB_BASEADDR
);
164 printf("ti1225: Cardbus/ExCA base address 0x%x\n", v32
);
165 v32
&= PCI_BAR_MEM_MASK
; /* Clear low order bits in base */
168 (struct csr
*) vm_map_phys(SELF
, (void *) v32
, PAGE_SIZE
);
169 if (pp
->csr_ptr
== MAP_FAILED
)
170 panic("hw_init: vm_map_phys failed");
174 v8
= pci_attr_r8(devind
, TI_PCI_BUS_NR
);
175 printf("ti1225: PCI bus number %d\n", v8
);
177 v8
= pci_attr_r8(devind
, TI_CB_BUS_NR
);
181 printf("ti1225: CardBus bus number %d\n", v8
);
182 v8
= pci_attr_r8(devind
, TI_SO_BUS_NR
);
183 printf("ti1225: Subordinate bus number %d\n", v8
);
187 irq
= pci_attr_r8(devind
, PCI_ILR
);
189 printf("ti1225 using IRQ %d\n", irq
);
192 v32
= pci_attr_r32(devind
, TI_LEGACY_BA
);
196 printf("ti1225: PC Card 16-bit legacy-mode base address 0x%x\n",
201 panic("bad legacy-mode base address: %d", v32
);
202 pp
->p_exca_port
= v32
;
206 v32
= pci_attr_r32(devind
, TI_MF_ROUTE
);
207 printf("ti1225: Multifunction routing 0x%08x\n", v32
);
211 pp
->p_hook
= pp
->p_irq
;
212 r
= sys_irqsetpolicy(pp
->p_irq
, 0, &pp
->p_hook
);
214 panic("sys_irqsetpolicy failed: %d", r
);
217 /* Clear CBB_BC_INTEXCA */
218 v16
= pci_attr_r16(devind
, CBB_BRIDGECTRL
);
220 printf("ti1225: Bridge control 0x%04x\n", v16
);
221 v16
&= ~CBB_BC_INTEXCA
;
222 pci_attr_w16(devind
, CBB_BRIDGECTRL
, v16
);
226 v32
= pci_attr_r32(devind
, TI_SYSCTRL
);
227 printf("ti1225: System Control Register 0x%08x\n", v32
);
229 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
230 printf("ti1225: Card Control 0x%02x\n", v8
);
232 v8
= pci_attr_r8(devind
, TI_DEV_CTRL
);
233 printf("ti1225: Device Control 0x%02x\n", v8
);
236 /* Enable socket interrupts */
237 pp
->csr_ptr
->csr_mask
|= CM_PWRMASK
| CM_CDMASK
| CM_CSTSMASK
;
242 r
= sys_irqenable(&pp
->p_hook
);
244 panic("unable enable interrupts: %d", r
);
248 /*===========================================================================*
250 *===========================================================================*/
251 static void do_int(struct port
*pp
)
253 int devind
, vcc_5v
, vcc_3v
, vcc_Xv
, vcc_Yv
,
254 socket_5v
, socket_3v
, socket_Xv
, socket_Yv
;
256 u32_t csr_event
, csr_present
, csr_control
;
263 devind
= pp
->p_devind
;
264 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
267 printf("ti1225: got functional interrupt\n");
268 pci_attr_w8(devind
, TI_CARD_CTRL
, v8
);
273 printf("Socket event: 0x%x\n", pp
->csr_ptr
->csr_event
);
274 printf("Socket mask: 0x%x\n", pp
->csr_ptr
->csr_mask
);
277 csr_present
= pp
->csr_ptr
->csr_present
;
278 csr_control
= pp
->csr_ptr
->csr_control
;
280 if ((csr_present
& (CP_CDETECT1
|CP_CDETECT2
)) != 0)
283 printf("do_int: no card present\n");
286 if (csr_present
& CP_BADVCCREQ
)
288 printf("do_int: Bad Vcc request\n");
291 if (csr_present
& CP_DATALOST
)
295 printf("do_int: Data lost\n");
298 if (csr_present
& CP_NOTACARD
)
300 printf("do_int: Not a card\n");
305 if (csr_present
& CP_CBCARD
)
306 printf("do_int: Cardbus card detected\n");
307 if (csr_present
& CP_16BITCARD
)
308 printf("do_int: 16-bit card detected\n");
310 if (csr_present
& CP_PWRCYCLE
)
313 printf("do_int: powered up\n");
316 vcc_5v
= !!(csr_present
& CP_5VCARD
);
317 vcc_3v
= !!(csr_present
& CP_3VCARD
);
318 vcc_Xv
= !!(csr_present
& CP_XVCARD
);
319 vcc_Yv
= !!(csr_present
& CP_YVCARD
);
322 printf("do_int: card supports:%s%s%s%s\n",
323 vcc_5v
? " 5V" : "", vcc_3v
? " 3V" : "",
324 vcc_Xv
? " X.X V" : "", vcc_Yv
? " Y.Y V" : "");
326 socket_5v
= !!(csr_present
& CP_5VSOCKET
);
327 socket_3v
= !!(csr_present
& CP_3VSOCKET
);
328 socket_Xv
= !!(csr_present
& CP_XVSOCKET
);
329 socket_Yv
= !!(csr_present
& CP_YVSOCKET
);
332 printf("do_int: socket supports:%s%s%s%s\n",
333 socket_5v
? " 5V" : "", socket_3v
? " 3V" : "",
334 socket_Xv
? " X.X V" : "", socket_Yv
? " Y.Y V" : "");
336 if (vcc_5v
&& socket_5v
)
338 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_5V
;
339 pp
->csr_ptr
->csr_control
= csr_control
;
341 printf("do_int: applying 5V\n");
343 else if (vcc_3v
&& socket_3v
)
345 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_3V
;
346 pp
->csr_ptr
->csr_control
= csr_control
;
348 printf("do_int: applying 3V\n");
350 else if (vcc_Xv
&& socket_Xv
)
352 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_XV
;
353 pp
->csr_ptr
->csr_control
= csr_control
;
354 printf("do_int: applying X.X V\n");
356 else if (vcc_Yv
&& socket_Yv
)
358 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_YV
;
359 pp
->csr_ptr
->csr_control
= csr_control
;
360 printf("do_int: applying Y.Y V\n");
364 printf("do_int: socket and card are not compatible\n");
368 csr_event
= pp
->csr_ptr
->csr_event
;
372 printf("clearing socket event\n");
373 pp
->csr_ptr
->csr_event
= csr_event
;
376 printf("Socket event (cleared): 0x%x\n",
377 pp
->csr_ptr
->csr_event
);
381 devind
= pp
->p_devind
;
382 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
385 printf("ti1225: got functional interrupt\n");
386 pci_attr_w8(devind
, TI_CARD_CTRL
, v8
);
391 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
392 printf("TI_CARD_CTRL: 0x%02x\n", v8
);
395 spin_init(&spin
, 100000);
397 csr_present
= pp
->csr_ptr
->csr_present
;
398 if (csr_present
& CP_PWRCYCLE
)
400 } while (spin_check(&spin
));
402 if (!(csr_present
& CP_PWRCYCLE
))
404 printf("do_int: not powered up?\n");
409 v16
= pci_attr_r16(devind
, CBB_BRIDGECTRL
);
411 pci_attr_w16(devind
, CBB_BRIDGECTRL
, v16
);
413 /* Wait one microsecond. Is this correct? What are the specs? */
416 /* Clear CBB_BC_CRST */
417 v16
= pci_attr_r16(devind
, CBB_BRIDGECTRL
);
419 pci_attr_w16(devind
, CBB_BRIDGECTRL
, v16
);
421 /* Wait one microsecond after clearing the reset line. Is this
422 * correct? What are the specs?
426 pci_rescan_bus(pp
->p_cb_busnr
);
429 r
= sys_irqenable(&pp
->p_hook
);
431 panic("unable enable interrupts: %d", r
);