4 Created: Dec 2005 by Philip Homburg
7 #include "../drivers.h"
10 #include <sys/vm_i386.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( u8_t read_exca
, (struct port
*pp
, int socket
, int reg
) );
58 FORWARD
_PROTOTYPE( void do_outb
, (port_t port
, u8_t value
) );
59 FORWARD
_PROTOTYPE( u8_t do_inb
, (port_t port
) );
61 /* SEF functions and variables. */
62 FORWARD
_PROTOTYPE( void sef_local_startup
, (void) );
63 FORWARD
_PROTOTYPE( int sef_cb_init_fresh
, (int type
, sef_init_info_t
*info
) );
65 EXTERN
char **env_argv
;
67 /*===========================================================================*
69 *===========================================================================*/
70 int main(int argc
, char *argv
[])
75 /* SEF local startup. */
76 env_setargs(argc
, argv
);
81 r
= sef_receive(ANY
, &m
);
83 panic("ti1225", "sef_receive failed", 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("ti1225", "tsc_calibrate failed", r
);
124 while (c
= getopt(env_argc
, env_argv
, "d?"), c
!= -1)
128 case '?': panic("ti1225", "Usage: ti1225 [-d]", NO_NUM
);
129 case 'd': debug
++; break;
130 default: panic("ti1225", "getopt failed", NO_NUM
);
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
)
159 "fxp_probe: class check not implemented",
164 if (pcitab_ti
[i
].vid
== 0)
170 printf("ti1225: found device %04x/%04x\n", vid
, did
);
171 ports
[port
].p_devind
= devind
;
172 ports
[port
].p_flags
|= PF_PRESENT
;
174 if (port
>= NR_PORTS
)
178 for (i
= 0; i
<NR_PORTS
; i
++)
180 if (!(ports
[i
].p_flags
& PF_PRESENT
))
188 PRIVATE
void hw_init(pp
)
191 int i
, r
, devind
, irq
, socket
;
196 devind
= pp
->p_devind
;
198 printf("hw_init: devind = %d\n", devind
);
202 v16
= pci_attr_r16(devind
, PCI_CR
);
203 printf("ti1225: command register 0x%x\n", v16
);
206 v32
= pci_attr_r32(devind
, TI_CB_BASEADDR
);
208 printf("ti1225: Cardbus/ExCA base address 0x%x\n", v32
);
210 pp
->csr_ptr
= (struct csr
*)pp
->base_ptr
;
214 v8
= pci_attr_r8(devind
, TI_PCI_BUS_NR
);
215 printf("ti1225: PCI bus number %d\n", v8
);
217 v8
= pci_attr_r8(devind
, TI_CB_BUS_NR
);
221 printf("ti1225: CardBus bus number %d\n", v8
);
222 v8
= pci_attr_r8(devind
, TI_SO_BUS_NR
);
223 printf("ti1225: Subordinate bus number %d\n", v8
);
227 irq
= pci_attr_r8(devind
, PCI_ILR
);
229 printf("ti1225 using IRQ %d\n", irq
);
232 v32
= pci_attr_r32(devind
, TI_LEGACY_BA
);
236 printf("ti1225: PC Card 16-bit legacy-mode base address 0x%x\n",
241 panic("ti1225", "bad lagacy-mode base address 0x%x\n", v32
);
242 pp
->p_exca_port
= v32
;
246 v32
= pci_attr_r32(devind
, TI_MF_ROUTE
);
247 printf("ti1225: Multifunction routing 0x%08x\n", v32
);
251 pp
->p_hook
= pp
->p_irq
;
252 r
= sys_irqsetpolicy(pp
->p_irq
, 0, &pp
->p_hook
);
254 panic("ti1225","sys_irqsetpolicy failed", r
);
257 /* Clear CBB_BC_INTEXCA */
258 v16
= pci_attr_r16(devind
, CBB_BRIDGECTRL
);
260 printf("ti1225: Bridge control 0x%04x\n", v16
);
261 v16
&= ~CBB_BC_INTEXCA
;
262 pci_attr_w16(devind
, CBB_BRIDGECTRL
, v16
);
266 v32
= pci_attr_r32(devind
, TI_SYSCTRL
);
267 printf("ti1225: System Control Register 0x%08x\n", v32
);
269 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
270 printf("ti1225: Card Control 0x%02x\n", v8
);
272 v8
= pci_attr_r8(devind
, TI_DEV_CTRL
);
273 printf("ti1225: Device Control 0x%02x\n", v8
);
276 /* Enable socket interrupts */
277 pp
->csr_ptr
->csr_mask
|= CM_PWRMASK
| CM_CDMASK
| CM_CSTSMASK
;
282 r
= sys_irqenable(&pp
->p_hook
);
284 panic("ti1225","unable enable interrupts", r
);
288 PRIVATE
void map_regs(pp
, base
)
295 buf_base
= (vir_bytes
)pp
->buffer
;
296 if (buf_base
% I386_PAGE_SIZE
)
297 buf_base
+= I386_PAGE_SIZE
-(buf_base
% I386_PAGE_SIZE
);
298 pp
->base_ptr
= (char *)buf_base
;
301 printf("ti1225: map_regs: using %p for %p\n",
302 pp
->base_ptr
, pp
->buffer
);
305 /* Clear low order bits in base */
309 r
= sys_vm_map(SELF
, 1 /* map */, (vir_bytes
)pp
->base_ptr
,
310 I386_PAGE_SIZE
, (phys_bytes
)base
);
315 panic("ti1225", "map_regs: sys_vm_map failed", r
);
318 PRIVATE
void do_int(pp
)
321 int i
, r
, devind
, vcc_5v
, vcc_3v
, vcc_Xv
, vcc_Yv
,
322 socket_5v
, socket_3v
, socket_Xv
, socket_Yv
;
324 u32_t csr_event
, csr_present
, csr_control
;
328 devind
= pp
->p_devind
;
329 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
332 printf("ti1225: got functional interrupt\n");
333 pci_attr_w8(devind
, TI_CARD_CTRL
, v8
);
338 printf("Socket event: 0x%x\n", pp
->csr_ptr
->csr_event
);
339 printf("Socket mask: 0x%x\n", pp
->csr_ptr
->csr_mask
);
342 csr_present
= pp
->csr_ptr
->csr_present
;
343 csr_control
= pp
->csr_ptr
->csr_control
;
345 if ((csr_present
& (CP_CDETECT1
|CP_CDETECT2
)) != 0)
348 printf("do_int: no card present\n");
351 if (csr_present
& CP_BADVCCREQ
)
353 printf("do_int: Bad Vcc request\n");
356 if (csr_present
& CP_DATALOST
)
360 printf("do_int: Data lost\n");
363 if (csr_present
& CP_NOTACARD
)
365 printf("do_int: Not a card\n");
370 if (csr_present
& CP_CBCARD
)
371 printf("do_int: Cardbus card detected\n");
372 if (csr_present
& CP_16BITCARD
)
373 printf("do_int: 16-bit card detected\n");
375 if (csr_present
& CP_PWRCYCLE
)
378 printf("do_int: powered up\n");
381 vcc_5v
= !!(csr_present
& CP_5VCARD
);
382 vcc_3v
= !!(csr_present
& CP_3VCARD
);
383 vcc_Xv
= !!(csr_present
& CP_XVCARD
);
384 vcc_Yv
= !!(csr_present
& CP_YVCARD
);
387 printf("do_int: card supports:%s%s%s%s\n",
388 vcc_5v
? " 5V" : "", vcc_3v
? " 3V" : "",
389 vcc_Xv
? " X.X V" : "", vcc_Yv
? " Y.Y V" : "");
391 socket_5v
= !!(csr_present
& CP_5VSOCKET
);
392 socket_3v
= !!(csr_present
& CP_3VSOCKET
);
393 socket_Xv
= !!(csr_present
& CP_XVSOCKET
);
394 socket_Yv
= !!(csr_present
& CP_YVSOCKET
);
397 printf("do_int: socket supports:%s%s%s%s\n",
398 socket_5v
? " 5V" : "", socket_3v
? " 3V" : "",
399 socket_Xv
? " X.X V" : "", socket_Yv
? " Y.Y V" : "");
401 if (vcc_5v
&& socket_5v
)
403 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_5V
;
404 pp
->csr_ptr
->csr_control
= csr_control
;
406 printf("do_int: applying 5V\n");
408 else if (vcc_3v
&& socket_3v
)
410 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_3V
;
411 pp
->csr_ptr
->csr_control
= csr_control
;
413 printf("do_int: applying 3V\n");
415 else if (vcc_Xv
&& socket_Xv
)
417 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_XV
;
418 pp
->csr_ptr
->csr_control
= csr_control
;
419 printf("do_int: applying X.X V\n");
421 else if (vcc_Yv
&& socket_Yv
)
423 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_YV
;
424 pp
->csr_ptr
->csr_control
= csr_control
;
425 printf("do_int: applying Y.Y V\n");
429 printf("do_int: socket and card are not compatible\n");
433 csr_event
= pp
->csr_ptr
->csr_event
;
437 printf("clearing socket event\n");
438 pp
->csr_ptr
->csr_event
= csr_event
;
441 printf("Socket event (cleared): 0x%x\n",
442 pp
->csr_ptr
->csr_event
);
446 devind
= pp
->p_devind
;
447 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
450 printf("ti1225: got functional interrupt\n", v8
);
451 pci_attr_w8(devind
, TI_CARD_CTRL
, v8
);
456 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
457 printf("TI_CARD_CTRL: 0x%02x\n", v8
);
462 csr_present
= pp
->csr_ptr
->csr_present
;
463 if (csr_present
& CP_PWRCYCLE
)
465 } while (getuptime(&t1
)==OK
&& (t1
-t0
) < micros_to_ticks(100000));
467 if (!(csr_present
& CP_PWRCYCLE
))
469 printf("do_int: not powered up?\n");
474 v16
= pci_attr_r16(devind
, CBB_BRIDGECTRL
);
476 pci_attr_w16(devind
, CBB_BRIDGECTRL
, v16
);
478 /* Wait one microsecond. Is this correct? What are the specs? */
481 /* Clear CBB_BC_CRST */
482 v16
= pci_attr_r16(devind
, CBB_BRIDGECTRL
);
484 pci_attr_w16(devind
, CBB_BRIDGECTRL
, v16
);
486 /* Wait one microsecond after clearing the reset line. Is this
487 * correct? What are the specs?
491 pci_rescan_bus(pp
->p_cb_busnr
);
494 r
= sys_irqenable(&pp
->p_hook
);
496 panic("ti1225","unable enable interrupts", r
);
501 PRIVATE u8_t
read_exca(pp
, socket
, reg
)
508 port
= pp
->p_exca_port
;
510 panic("ti1225", "read_exca: bad port", NO_NUM
);
511 do_outb(port
, socket
* 0x40 + reg
);
512 return do_inb(port
+1);
515 PRIVATE u8_t
do_inb(port_t port
)
520 r
= sys_inb(port
, &value
);
522 panic("ti1225","sys_inb failed", r
);
526 PRIVATE
void do_outb(port_t port
, u8_t value
)
530 r
= sys_outb(port
, value
);
532 panic("ti1225","sys_outb failed", r
);