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>
15 /* The use of interrupts is not yet ready for prime time */
31 volatile struct csr
*csr_ptr
;
33 char buffer
[2*I386_PAGE_SIZE
];
45 PRIVATE
struct pcitab pcitab_ti
[]=
47 { 0x104C, 0xAC1C, 0 }, /* TI PCI1225 */
51 PRIVATE
char *progname
;
54 FORWARD
_PROTOTYPE( void hw_init
, (struct port
*pp
) );
55 FORWARD
_PROTOTYPE( void map_regs
, (struct port
*pp
, u32_t base
) );
56 FORWARD
_PROTOTYPE( void do_int
, (struct port
*pp
) );
57 FORWARD
_PROTOTYPE( void do_outb
, (port_t port
, u8_t value
) );
58 FORWARD
_PROTOTYPE( u8_t do_inb
, (port_t port
) );
60 /* SEF functions and variables. */
61 FORWARD
_PROTOTYPE( void sef_local_startup
, (void) );
62 FORWARD
_PROTOTYPE( int sef_cb_init_fresh
, (int type
, sef_init_info_t
*info
) );
64 EXTERN
char **env_argv
;
66 /*===========================================================================*
68 *===========================================================================*/
69 int main(int argc
, char *argv
[])
75 /* SEF local startup. */
76 env_setargs(argc
, argv
);
81 r
= driver_receive(ANY
, &m
, &ipc_status
);
83 panic("driver_receive failed: %d", r
);
84 printf("ti1225: got message %u from %d\n",
85 m
.m_type
, m
.m_source
);
90 /*===========================================================================*
92 *===========================================================================*/
93 PRIVATE
void sef_local_startup()
95 /* Register init callbacks. */
96 sef_setcb_init_fresh(sef_cb_init_fresh
);
97 sef_setcb_init_lu(sef_cb_init_fresh
);
98 sef_setcb_init_restart(sef_cb_init_fresh
);
100 /* Register live update callbacks. */
101 sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready
);
102 sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard
);
104 /* Let SEF perform startup. */
108 /*===========================================================================*
109 * sef_cb_init_fresh *
110 *===========================================================================*/
111 PRIVATE
int sef_cb_init_fresh(int type
, sef_init_info_t
*info
)
113 /* Initialize the ti1225 driver. */
114 int c
, i
, r
, first
, devind
, port
;
117 (progname
=strrchr(env_argv
[0],'/')) ? progname
++
118 : (progname
=env_argv
[0]);
120 if((r
=tsc_calibrate()) != OK
)
121 panic("tsc_calibrate failed: %d", r
);
124 while (c
= getopt(env_argc
, env_argv
, "d?"), c
!= -1)
128 case '?': panic("Usage: ti1225 [-d]");
129 case 'd': debug
++; break;
130 default: panic("getopt failed");
143 r
= pci_first_dev(&devind
, &vid
, &did
);
146 r
= pci_next_dev(&devind
, &vid
, &did
);
150 for (i
= 0; pcitab_ti
[i
].vid
!= 0; i
++)
152 if (pcitab_ti
[i
].vid
!= vid
)
154 if (pcitab_ti
[i
].did
!= did
)
156 if (pcitab_ti
[i
].checkclass
) {
157 panic("fxp_probe: class check not implemented");
161 if (pcitab_ti
[i
].vid
== 0)
167 printf("ti1225: found device %04x/%04x\n", vid
, did
);
168 ports
[port
].p_devind
= devind
;
169 ports
[port
].p_flags
|= PF_PRESENT
;
171 if (port
>= NR_PORTS
)
175 for (i
= 0; i
<NR_PORTS
; i
++)
177 if (!(ports
[i
].p_flags
& PF_PRESENT
))
182 /* Announce we are up! */
188 PRIVATE
void hw_init(struct port
*pp
)
195 devind
= pp
->p_devind
;
197 printf("hw_init: devind = %d\n", devind
);
201 v16
= pci_attr_r16(devind
, PCI_CR
);
202 printf("ti1225: command register 0x%x\n", v16
);
205 v32
= pci_attr_r32(devind
, TI_CB_BASEADDR
);
207 printf("ti1225: Cardbus/ExCA base address 0x%x\n", v32
);
209 pp
->csr_ptr
= (struct csr
*)pp
->base_ptr
;
213 v8
= pci_attr_r8(devind
, TI_PCI_BUS_NR
);
214 printf("ti1225: PCI bus number %d\n", v8
);
216 v8
= pci_attr_r8(devind
, TI_CB_BUS_NR
);
220 printf("ti1225: CardBus bus number %d\n", v8
);
221 v8
= pci_attr_r8(devind
, TI_SO_BUS_NR
);
222 printf("ti1225: Subordinate bus number %d\n", v8
);
226 irq
= pci_attr_r8(devind
, PCI_ILR
);
228 printf("ti1225 using IRQ %d\n", irq
);
231 v32
= pci_attr_r32(devind
, TI_LEGACY_BA
);
235 printf("ti1225: PC Card 16-bit legacy-mode base address 0x%x\n",
240 panic("bad legacy-mode base address: %d", v32
);
241 pp
->p_exca_port
= v32
;
245 v32
= pci_attr_r32(devind
, TI_MF_ROUTE
);
246 printf("ti1225: Multifunction routing 0x%08x\n", v32
);
250 pp
->p_hook
= pp
->p_irq
;
251 r
= sys_irqsetpolicy(pp
->p_irq
, 0, &pp
->p_hook
);
253 panic("sys_irqsetpolicy failed: %d", r
);
256 /* Clear CBB_BC_INTEXCA */
257 v16
= pci_attr_r16(devind
, CBB_BRIDGECTRL
);
259 printf("ti1225: Bridge control 0x%04x\n", v16
);
260 v16
&= ~CBB_BC_INTEXCA
;
261 pci_attr_w16(devind
, CBB_BRIDGECTRL
, v16
);
265 v32
= pci_attr_r32(devind
, TI_SYSCTRL
);
266 printf("ti1225: System Control Register 0x%08x\n", v32
);
268 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
269 printf("ti1225: Card Control 0x%02x\n", v8
);
271 v8
= pci_attr_r8(devind
, TI_DEV_CTRL
);
272 printf("ti1225: Device Control 0x%02x\n", v8
);
275 /* Enable socket interrupts */
276 pp
->csr_ptr
->csr_mask
|= CM_PWRMASK
| CM_CDMASK
| CM_CSTSMASK
;
281 r
= sys_irqenable(&pp
->p_hook
);
283 panic("unable enable interrupts: %d", r
);
287 PRIVATE
void map_regs(struct port
*pp
, u32_t base
)
292 buf_base
= (vir_bytes
)pp
->buffer
;
293 if (buf_base
% I386_PAGE_SIZE
)
294 buf_base
+= I386_PAGE_SIZE
-(buf_base
% I386_PAGE_SIZE
);
295 pp
->base_ptr
= (char *)buf_base
;
298 printf("ti1225: map_regs: using %p for %p\n",
299 pp
->base_ptr
, pp
->buffer
);
302 /* Clear low order bits in base */
306 r
= sys_vm_map(SELF
, 1 /* map */, (vir_bytes
)pp
->base_ptr
,
307 I386_PAGE_SIZE
, (phys_bytes
)base
);
312 panic("map_regs: sys_vm_map failed: %d", r
);
315 PRIVATE
void do_int(struct port
*pp
)
317 int r
, devind
, vcc_5v
, vcc_3v
, vcc_Xv
, vcc_Yv
,
318 socket_5v
, socket_3v
, socket_Xv
, socket_Yv
;
320 u32_t csr_event
, csr_present
, csr_control
;
324 devind
= pp
->p_devind
;
325 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
328 printf("ti1225: got functional interrupt\n");
329 pci_attr_w8(devind
, TI_CARD_CTRL
, v8
);
334 printf("Socket event: 0x%x\n", pp
->csr_ptr
->csr_event
);
335 printf("Socket mask: 0x%x\n", pp
->csr_ptr
->csr_mask
);
338 csr_present
= pp
->csr_ptr
->csr_present
;
339 csr_control
= pp
->csr_ptr
->csr_control
;
341 if ((csr_present
& (CP_CDETECT1
|CP_CDETECT2
)) != 0)
344 printf("do_int: no card present\n");
347 if (csr_present
& CP_BADVCCREQ
)
349 printf("do_int: Bad Vcc request\n");
352 if (csr_present
& CP_DATALOST
)
356 printf("do_int: Data lost\n");
359 if (csr_present
& CP_NOTACARD
)
361 printf("do_int: Not a card\n");
366 if (csr_present
& CP_CBCARD
)
367 printf("do_int: Cardbus card detected\n");
368 if (csr_present
& CP_16BITCARD
)
369 printf("do_int: 16-bit card detected\n");
371 if (csr_present
& CP_PWRCYCLE
)
374 printf("do_int: powered up\n");
377 vcc_5v
= !!(csr_present
& CP_5VCARD
);
378 vcc_3v
= !!(csr_present
& CP_3VCARD
);
379 vcc_Xv
= !!(csr_present
& CP_XVCARD
);
380 vcc_Yv
= !!(csr_present
& CP_YVCARD
);
383 printf("do_int: card supports:%s%s%s%s\n",
384 vcc_5v
? " 5V" : "", vcc_3v
? " 3V" : "",
385 vcc_Xv
? " X.X V" : "", vcc_Yv
? " Y.Y V" : "");
387 socket_5v
= !!(csr_present
& CP_5VSOCKET
);
388 socket_3v
= !!(csr_present
& CP_3VSOCKET
);
389 socket_Xv
= !!(csr_present
& CP_XVSOCKET
);
390 socket_Yv
= !!(csr_present
& CP_YVSOCKET
);
393 printf("do_int: socket supports:%s%s%s%s\n",
394 socket_5v
? " 5V" : "", socket_3v
? " 3V" : "",
395 socket_Xv
? " X.X V" : "", socket_Yv
? " Y.Y V" : "");
397 if (vcc_5v
&& socket_5v
)
399 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_5V
;
400 pp
->csr_ptr
->csr_control
= csr_control
;
402 printf("do_int: applying 5V\n");
404 else if (vcc_3v
&& socket_3v
)
406 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_3V
;
407 pp
->csr_ptr
->csr_control
= csr_control
;
409 printf("do_int: applying 3V\n");
411 else if (vcc_Xv
&& socket_Xv
)
413 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_XV
;
414 pp
->csr_ptr
->csr_control
= csr_control
;
415 printf("do_int: applying X.X V\n");
417 else if (vcc_Yv
&& socket_Yv
)
419 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_YV
;
420 pp
->csr_ptr
->csr_control
= csr_control
;
421 printf("do_int: applying Y.Y V\n");
425 printf("do_int: socket and card are not compatible\n");
429 csr_event
= pp
->csr_ptr
->csr_event
;
433 printf("clearing socket event\n");
434 pp
->csr_ptr
->csr_event
= csr_event
;
437 printf("Socket event (cleared): 0x%x\n",
438 pp
->csr_ptr
->csr_event
);
442 devind
= pp
->p_devind
;
443 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
446 printf("ti1225: got functional interrupt\n");
447 pci_attr_w8(devind
, TI_CARD_CTRL
, v8
);
452 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
453 printf("TI_CARD_CTRL: 0x%02x\n", v8
);
458 csr_present
= pp
->csr_ptr
->csr_present
;
459 if (csr_present
& CP_PWRCYCLE
)
461 } while (getuptime(&t1
)==OK
&& (t1
-t0
) < micros_to_ticks(100000));
463 if (!(csr_present
& CP_PWRCYCLE
))
465 printf("do_int: not powered up?\n");
470 v16
= pci_attr_r16(devind
, CBB_BRIDGECTRL
);
472 pci_attr_w16(devind
, CBB_BRIDGECTRL
, v16
);
474 /* Wait one microsecond. Is this correct? What are the specs? */
477 /* Clear CBB_BC_CRST */
478 v16
= pci_attr_r16(devind
, CBB_BRIDGECTRL
);
480 pci_attr_w16(devind
, CBB_BRIDGECTRL
, v16
);
482 /* Wait one microsecond after clearing the reset line. Is this
483 * correct? What are the specs?
487 pci_rescan_bus(pp
->p_cb_busnr
);
490 r
= sys_irqenable(&pp
->p_hook
);
492 panic("unable enable interrupts: %d", r
);
498 PRIVATE u8_t
do_inb(port_t port
)
503 r
= sys_inb(port
, &value
);
505 panic("sys_inb failed: %d", r
);
509 PRIVATE
void do_outb(port_t port
, u8_t value
)
513 r
= sys_outb(port
, value
);
515 panic("sys_outb failed: %d", r
);