4 Created: Dec 2005 by Philip Homburg
7 #include "../drivers.h"
14 /* The use of interrupts is not yet ready for prime time */
17 #define MICROS_TO_TICKS(m) (((m)*HZ/1000000)+1)
32 volatile struct csr
*csr_ptr
;
34 char buffer
[2*PAGE_SIZE
];
46 PRIVATE
struct pcitab pcitab_ti
[]=
48 { 0x104C, 0xAC1C, 0 }, /* TI PCI1225 */
52 PRIVATE
char *progname
;
55 FORWARD
_PROTOTYPE( void init
, (void) );
56 FORWARD
_PROTOTYPE( void hw_init
, (struct port
*pp
) );
57 FORWARD
_PROTOTYPE( void map_regs
, (struct port
*pp
, u32_t base
) );
58 FORWARD
_PROTOTYPE( void do_int
, (struct port
*pp
) );
59 FORWARD
_PROTOTYPE( u8_t read_exca
, (struct port
*pp
, int socket
, int reg
) );
60 FORWARD
_PROTOTYPE( void do_outb
, (port_t port
, u8_t value
) );
61 FORWARD
_PROTOTYPE( u8_t do_inb
, (port_t port
) );
62 FORWARD
_PROTOTYPE( void micro_delay
, (unsigned long usecs
) );
64 int main(int argc
, char *argv
[])
69 (progname
=strrchr(argv
[0],'/')) ? progname
++ : (progname
=argv
[0]);
72 while (c
= getopt(argc
, argv
, "d?"), c
!= -1)
76 case '?': panic("ti1225", "Usage: ti1225 [-d]", NO_NUM
);
77 case 'd': debug
++; break;
78 default: panic("ti1225", "getopt failed", NO_NUM
);
88 panic("ti1225", "receive failed", r
);
89 printf("ti1225: got message %u from %d\n",
90 m
.m_type
, m
.m_source
);
97 int i
, r
, first
, devind
, port
;
109 r
= pci_first_dev(&devind
, &vid
, &did
);
112 r
= pci_next_dev(&devind
, &vid
, &did
);
116 for (i
= 0; pcitab_ti
[i
].vid
!= 0; i
++)
118 if (pcitab_ti
[i
].vid
!= vid
)
120 if (pcitab_ti
[i
].did
!= did
)
122 if (pcitab_ti
[i
].checkclass
)
125 "fxp_probe: class check not implemented",
130 if (pcitab_ti
[i
].vid
== 0)
136 printf("ti1225: found device %04x/%04x\n", vid
, did
);
137 ports
[port
].p_devind
= devind
;
138 ports
[port
].p_flags
|= PF_PRESENT
;
140 if (port
>= NR_PORTS
)
144 for (i
= 0; i
<NR_PORTS
; i
++)
146 if (!(ports
[i
].p_flags
& PF_PRESENT
))
152 PRIVATE
void hw_init(pp
)
155 int i
, r
, devind
, irq
, socket
;
160 devind
= pp
->p_devind
;
162 printf("hw_init: devind = %d\n", devind
);
166 v16
= pci_attr_r16(devind
, PCI_CR
);
167 printf("ti1225: command register 0x%x\n", v16
);
170 v32
= pci_attr_r32(devind
, TI_CB_BASEADDR
);
172 printf("ti1225: Cardbus/ExCA base address 0x%x\n", v32
);
174 pp
->csr_ptr
= (struct csr
*)pp
->base_ptr
;
178 v8
= pci_attr_r8(devind
, TI_PCI_BUS_NR
);
179 printf("ti1225: PCI bus number %d\n", v8
);
181 v8
= pci_attr_r8(devind
, TI_CB_BUS_NR
);
185 printf("ti1225: CardBus bus number %d\n", v8
);
186 v8
= pci_attr_r8(devind
, TI_SO_BUS_NR
);
187 printf("ti1225: Subordinate bus number %d\n", v8
);
191 irq
= pci_attr_r8(devind
, PCI_ILR
);
193 printf("ti1225 using IRQ %d\n", irq
);
196 v32
= pci_attr_r32(devind
, TI_LEGACY_BA
);
200 printf("ti1225: PC Card 16-bit legacy-mode base address 0x%x\n",
205 panic("ti1225", "bad lagacy-mode base address 0x%x\n", v32
);
206 pp
->p_exca_port
= v32
;
210 v32
= pci_attr_r32(devind
, TI_MF_ROUTE
);
211 printf("ti1225: Multifunction routing 0x%08x\n", v32
);
215 pp
->p_hook
= pp
->p_irq
;
216 r
= sys_irqsetpolicy(pp
->p_irq
, 0, &pp
->p_hook
);
218 panic("ti1225","sys_irqsetpolicy failed", r
);
221 /* Clear CBB_BC_INTEXCA */
222 v16
= pci_attr_r16(devind
, CBB_BRIDGECTRL
);
224 printf("ti1225: Bridge control 0x%04x\n", v16
);
225 v16
&= ~CBB_BC_INTEXCA
;
226 pci_attr_w16(devind
, CBB_BRIDGECTRL
, v16
);
230 v32
= pci_attr_r32(devind
, TI_SYSCTRL
);
231 printf("ti1225: System Control Register 0x%08x\n", v32
);
233 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
234 printf("ti1225: Card Control 0x%02x\n", v8
);
236 v8
= pci_attr_r8(devind
, TI_DEV_CTRL
);
237 printf("ti1225: Device Control 0x%02x\n", v8
);
240 /* Enable socket interrupts */
241 pp
->csr_ptr
->csr_mask
|= CM_PWRMASK
| CM_CDMASK
| CM_CSTSMASK
;
246 r
= sys_irqenable(&pp
->p_hook
);
248 panic("ti1225","unable enable interrupts", r
);
252 PRIVATE
void map_regs(pp
, base
)
259 buf_base
= (vir_bytes
)pp
->buffer
;
260 if (buf_base
% PAGE_SIZE
)
261 buf_base
+= PAGE_SIZE
-(buf_base
% PAGE_SIZE
);
262 pp
->base_ptr
= (char *)buf_base
;
265 printf("ti1225: map_regs: using %p for %p\n",
266 pp
->base_ptr
, pp
->buffer
);
269 /* Clear low order bits in base */
272 r
= sys_vm_map(SELF
, 1 /* map */, (vir_bytes
)pp
->base_ptr
,
273 PAGE_SIZE
, (phys_bytes
)base
);
275 panic("ti1225", "map_regs: sys_vm_map failed", r
);
278 PRIVATE
void do_int(pp
)
281 int i
, r
, devind
, vcc_5v
, vcc_3v
, vcc_Xv
, vcc_Yv
,
282 socket_5v
, socket_3v
, socket_Xv
, socket_Yv
;
284 u32_t csr_event
, csr_present
, csr_control
;
288 devind
= pp
->p_devind
;
289 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
292 printf("ti1225: got functional interrupt\n", v8
);
293 pci_attr_w8(devind
, TI_CARD_CTRL
, v8
);
298 printf("Socket event: 0x%x\n", pp
->csr_ptr
->csr_event
);
299 printf("Socket mask: 0x%x\n", pp
->csr_ptr
->csr_mask
);
302 csr_present
= pp
->csr_ptr
->csr_present
;
303 csr_control
= pp
->csr_ptr
->csr_control
;
305 if ((csr_present
& (CP_CDETECT1
|CP_CDETECT2
)) != 0)
308 printf("do_int: no card present\n");
311 if (csr_present
& CP_BADVCCREQ
)
313 printf("do_int: Bad Vcc request\n");
316 if (csr_present
& CP_DATALOST
)
320 printf("do_int: Data lost\n");
323 if (csr_present
& CP_NOTACARD
)
325 printf("do_int: Not a card\n");
330 if (csr_present
& CP_CBCARD
)
331 printf("do_int: Cardbus card detected\n");
332 if (csr_present
& CP_16BITCARD
)
333 printf("do_int: 16-bit card detected\n");
335 if (csr_present
& CP_PWRCYCLE
)
338 printf("do_int: powered up\n");
341 vcc_5v
= !!(csr_present
& CP_5VCARD
);
342 vcc_3v
= !!(csr_present
& CP_3VCARD
);
343 vcc_Xv
= !!(csr_present
& CP_XVCARD
);
344 vcc_Yv
= !!(csr_present
& CP_YVCARD
);
347 printf("do_int: card supports:%s%s%s%s\n",
348 vcc_5v
? " 5V" : "", vcc_3v
? " 3V" : "",
349 vcc_Xv
? " X.X V" : "", vcc_Yv
? " Y.Y V" : "");
351 socket_5v
= !!(csr_present
& CP_5VSOCKET
);
352 socket_3v
= !!(csr_present
& CP_3VSOCKET
);
353 socket_Xv
= !!(csr_present
& CP_XVSOCKET
);
354 socket_Yv
= !!(csr_present
& CP_YVSOCKET
);
357 printf("do_int: socket supports:%s%s%s%s\n",
358 socket_5v
? " 5V" : "", socket_3v
? " 3V" : "",
359 socket_Xv
? " X.X V" : "", socket_Yv
? " Y.Y V" : "");
361 if (vcc_5v
&& socket_5v
)
363 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_5V
;
364 pp
->csr_ptr
->csr_control
= csr_control
;
366 printf("do_int: applying 5V\n");
368 else if (vcc_3v
&& socket_3v
)
370 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_3V
;
371 pp
->csr_ptr
->csr_control
= csr_control
;
373 printf("do_int: applying 3V\n");
375 else if (vcc_Xv
&& socket_Xv
)
377 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_XV
;
378 pp
->csr_ptr
->csr_control
= csr_control
;
379 printf("do_int: applying X.X V\n");
381 else if (vcc_Yv
&& socket_Yv
)
383 csr_control
= (csr_control
& ~CC_VCCCTRL
) | CC_VCC_YV
;
384 pp
->csr_ptr
->csr_control
= csr_control
;
385 printf("do_int: applying Y.Y V\n");
389 printf("do_int: socket and card are not compatible\n");
393 csr_event
= pp
->csr_ptr
->csr_event
;
397 printf("clearing socket event\n");
398 pp
->csr_ptr
->csr_event
= csr_event
;
401 printf("Socket event (cleared): 0x%x\n",
402 pp
->csr_ptr
->csr_event
);
406 devind
= pp
->p_devind
;
407 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
410 printf("ti1225: got functional interrupt\n", v8
);
411 pci_attr_w8(devind
, TI_CARD_CTRL
, v8
);
416 v8
= pci_attr_r8(devind
, TI_CARD_CTRL
);
417 printf("TI_CARD_CTRL: 0x%02x\n", v8
);
422 csr_present
= pp
->csr_ptr
->csr_present
;
423 if (csr_present
& CP_PWRCYCLE
)
425 } while (getuptime(&t1
)==OK
&& (t1
-t0
) < MICROS_TO_TICKS(100000));
427 if (!(csr_present
& CP_PWRCYCLE
))
429 printf("do_int: not powered up?\n");
434 v16
= pci_attr_r16(devind
, CBB_BRIDGECTRL
);
436 pci_attr_w16(devind
, CBB_BRIDGECTRL
, v16
);
438 /* Wait one microsecond. Is this correct? What are the specs? */
441 /* Clear CBB_BC_CRST */
442 v16
= pci_attr_r16(devind
, CBB_BRIDGECTRL
);
444 pci_attr_w16(devind
, CBB_BRIDGECTRL
, v16
);
446 /* Wait one microsecond after clearing the reset line. Is this
447 * correct? What are the specs?
451 pci_rescan_bus(pp
->p_cb_busnr
);
454 r
= sys_irqenable(&pp
->p_hook
);
456 panic("ti1225","unable enable interrupts", r
);
461 PRIVATE u8_t
read_exca(pp
, socket
, reg
)
468 port
= pp
->p_exca_port
;
470 panic("ti1225", "read_exca: bad port", NO_NUM
);
471 do_outb(port
, socket
* 0x40 + reg
);
472 return do_inb(port
+1);
475 PRIVATE u8_t
do_inb(port_t port
)
480 r
= sys_inb(port
, &value
);
482 panic("ti1225","sys_inb failed", r
);
486 PRIVATE
void do_outb(port_t port
, u8_t value
)
490 r
= sys_outb(port
, value
);
492 panic("ti1225","sys_outb failed", r
);
495 PRIVATE
void micro_delay(unsigned long usecs
)
497 tickdelay(MICROS_TO_TICKS(usecs
));