00001
00002
00003
00004
00005
00006
00007 #include "../drivers.h"
00008 #include <ibm/pci.h>
00009 #include <sys/vm.h>
00010
00011 #include "ti1225.h"
00012 #include "i82365.h"
00013
00014
00015 #define USE_INTS 0
00016
00017 #define MICROS_TO_TICKS(m) (((m)*HZ/1000000)+1)
00018
00019 #define NR_PORTS 2
00020
00021 PRIVATE struct port
00022 {
00023 unsigned p_flags;
00024 int p_devind;
00025 u8_t p_cb_busnr;
00026 u16_t p_exca_port;
00027 #if USE_INTS
00028 int p_irq;
00029 int p_hook;
00030 #endif
00031 char *base_ptr;
00032 volatile struct csr *csr_ptr;
00033
00034 char buffer[2*PAGE_SIZE];
00035 } ports[NR_PORTS];
00036
00037 #define PF_PRESENT 1
00038
00039 struct pcitab
00040 {
00041 u16_t vid;
00042 u16_t did;
00043 int checkclass;
00044 };
00045
00046 PRIVATE struct pcitab pcitab_ti[]=
00047 {
00048 { 0x104C, 0xAC1C, 0 },
00049
00050 { 0x0000, 0x0000, 0 }
00051 };
00052 PRIVATE char *progname;
00053 PRIVATE int debug;
00054
00055 FORWARD _PROTOTYPE( void init, (void) );
00056 FORWARD _PROTOTYPE( void hw_init, (struct port *pp) );
00057 FORWARD _PROTOTYPE( void map_regs, (struct port *pp, u32_t base) );
00058 FORWARD _PROTOTYPE( void do_int, (struct port *pp) );
00059 FORWARD _PROTOTYPE( u8_t read_exca, (struct port *pp, int socket, int reg) );
00060 FORWARD _PROTOTYPE( void do_outb, (port_t port, u8_t value) );
00061 FORWARD _PROTOTYPE( u8_t do_inb, (port_t port) );
00062 FORWARD _PROTOTYPE( void micro_delay, (unsigned long usecs) );
00063
00064 int main(int argc, char *argv[])
00065 {
00066 int c, r;
00067 message m;
00068
00069 (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
00070
00071 debug= 0;
00072 while (c= getopt(argc, argv, "d?"), c != -1)
00073 {
00074 switch(c)
00075 {
00076 case '?': panic("ti1225", "Usage: ti1225 [-d]", NO_NUM);
00077 case 'd': debug++; break;
00078 default: panic("ti1225", "getopt failed", NO_NUM);
00079 }
00080 }
00081
00082 init();
00083
00084 for (;;)
00085 {
00086 r= receive(ANY, &m);
00087 if (r != OK)
00088 panic("ti1225", "receive failed", r);
00089 printf("ti1225: got message %u from %d\n",
00090 m.m_type, m.m_source);
00091 }
00092 return 0;
00093 }
00094
00095 PRIVATE void init()
00096 {
00097 int i, r, first, devind, port;
00098 u16_t vid, did;
00099
00100 pci_init1(progname);
00101
00102 first= 1;
00103 port= 0;
00104 for (;;)
00105 {
00106 if (first)
00107 {
00108 first= 0;
00109 r= pci_first_dev(&devind, &vid, &did);
00110 }
00111 else
00112 r= pci_next_dev(&devind, &vid, &did);
00113 if (r != 1)
00114 break;
00115
00116 for (i= 0; pcitab_ti[i].vid != 0; i++)
00117 {
00118 if (pcitab_ti[i].vid != vid)
00119 continue;
00120 if (pcitab_ti[i].did != did)
00121 continue;
00122 if (pcitab_ti[i].checkclass)
00123 {
00124 panic("ti1225",
00125 "fxp_probe: class check not implemented",
00126 NO_NUM);
00127 }
00128 break;
00129 }
00130 if (pcitab_ti[i].vid == 0)
00131 continue;
00132
00133 pci_reserve(devind);
00134
00135 if (debug)
00136 printf("ti1225: found device %04x/%04x\n", vid, did);
00137 ports[port].p_devind= devind;
00138 ports[port].p_flags |= PF_PRESENT;
00139 port++;
00140 if (port >= NR_PORTS)
00141 break;
00142 }
00143
00144 for (i= 0; i<NR_PORTS; i++)
00145 {
00146 if (!(ports[i].p_flags & PF_PRESENT))
00147 continue;
00148 hw_init(&ports[i]);
00149 }
00150 }
00151
00152 PRIVATE void hw_init(pp)
00153 struct port *pp;
00154 {
00155 int i, r, devind, irq, socket;
00156 u8_t v8;
00157 u16_t v16;
00158 u32_t v32;
00159
00160 devind= pp->p_devind;
00161 if (debug)
00162 printf("hw_init: devind = %d\n", devind);
00163
00164 if (debug)
00165 {
00166 v16= pci_attr_r16(devind, PCI_CR);
00167 printf("ti1225: command register 0x%x\n", v16);
00168 }
00169
00170 v32= pci_attr_r32(devind, TI_CB_BASEADDR);
00171 if (debug)
00172 printf("ti1225: Cardbus/ExCA base address 0x%x\n", v32);
00173 map_regs(pp, v32);
00174 pp->csr_ptr= (struct csr *)pp->base_ptr;
00175
00176 if (debug)
00177 {
00178 v8= pci_attr_r8(devind, TI_PCI_BUS_NR);
00179 printf("ti1225: PCI bus number %d\n", v8);
00180 }
00181 v8= pci_attr_r8(devind, TI_CB_BUS_NR);
00182 pp->p_cb_busnr= v8;
00183 if (debug)
00184 {
00185 printf("ti1225: CardBus bus number %d\n", v8);
00186 v8= pci_attr_r8(devind, TI_SO_BUS_NR);
00187 printf("ti1225: Subordinate bus number %d\n", v8);
00188 }
00189
00190 #if USE_INTS
00191 irq= pci_attr_r8(devind, PCI_ILR);
00192 pp->p_irq= irq;
00193 printf("ti1225 using IRQ %d\n", irq);
00194 #endif
00195
00196 v32= pci_attr_r32(devind, TI_LEGACY_BA);
00197 v32 &= ~1;
00198 if (debug)
00199 {
00200 printf("ti1225: PC Card 16-bit legacy-mode base address 0x%x\n",
00201 v32);
00202 }
00203
00204 if (v32 == 0)
00205 panic("ti1225", "bad lagacy-mode base address 0x%x\n", v32);
00206 pp->p_exca_port= v32;
00207
00208 if (debug)
00209 {
00210 v32= pci_attr_r32(devind, TI_MF_ROUTE);
00211 printf("ti1225: Multifunction routing 0x%08x\n", v32);
00212 }
00213
00214 #if USE_INTS
00215 pp->p_hook = pp->p_irq;
00216 r= sys_irqsetpolicy(pp->p_irq, 0, &pp->p_hook);
00217 if (r != OK)
00218 panic("ti1225","sys_irqsetpolicy failed", r);
00219 #endif
00220
00221
00222 v16= pci_attr_r16(devind, CBB_BRIDGECTRL);
00223 if (debug)
00224 printf("ti1225: Bridge control 0x%04x\n", v16);
00225 v16 &= ~CBB_BC_INTEXCA;
00226 pci_attr_w16(devind, CBB_BRIDGECTRL, v16);
00227
00228 if (debug)
00229 {
00230 v32= pci_attr_r32(devind, TI_SYSCTRL);
00231 printf("ti1225: System Control Register 0x%08x\n", v32);
00232
00233 v8= pci_attr_r8(devind, TI_CARD_CTRL);
00234 printf("ti1225: Card Control 0x%02x\n", v8);
00235
00236 v8= pci_attr_r8(devind, TI_DEV_CTRL);
00237 printf("ti1225: Device Control 0x%02x\n", v8);
00238 }
00239
00240
00241 pp->csr_ptr->csr_mask |= CM_PWRMASK | CM_CDMASK | CM_CSTSMASK;
00242
00243 do_int(pp);
00244
00245 #if USE_INTS
00246 r= sys_irqenable(&pp->p_hook);
00247 if (r != OK)
00248 panic("ti1225","unable enable interrupts", r);
00249 #endif
00250 }
00251
00252 PRIVATE void map_regs(pp, base)
00253 struct port *pp;
00254 u32_t base;
00255 {
00256 int r;
00257 vir_bytes buf_base;
00258
00259 buf_base= (vir_bytes)pp->buffer;
00260 if (buf_base % PAGE_SIZE)
00261 buf_base += PAGE_SIZE-(buf_base % PAGE_SIZE);
00262 pp->base_ptr= (char *)buf_base;
00263 if (debug)
00264 {
00265 printf("ti1225: map_regs: using %p for %p\n",
00266 pp->base_ptr, pp->buffer);
00267 }
00268
00269
00270 base &= ~(u32_t)0xF;
00271
00272 r= sys_vm_map(SELF, 1 , (vir_bytes)pp->base_ptr,
00273 PAGE_SIZE, (phys_bytes)base);
00274 if (r != OK)
00275 panic("ti1225", "map_regs: sys_vm_map failed", r);
00276 }
00277
00278 PRIVATE void do_int(pp)
00279 struct port *pp;
00280 {
00281 int i, r, devind, vcc_5v, vcc_3v, vcc_Xv, vcc_Yv,
00282 socket_5v, socket_3v, socket_Xv, socket_Yv;
00283 clock_t t0, t1;
00284 u32_t csr_event, csr_present, csr_control;
00285 u8_t v8;
00286 u16_t v16;
00287
00288 devind= pp->p_devind;
00289 v8= pci_attr_r8(devind, TI_CARD_CTRL);
00290 if (v8 & TI_CCR_IFG)
00291 {
00292 printf("ti1225: got functional interrupt\n", v8);
00293 pci_attr_w8(devind, TI_CARD_CTRL, v8);
00294 }
00295
00296 if (debug)
00297 {
00298 printf("Socket event: 0x%x\n", pp->csr_ptr->csr_event);
00299 printf("Socket mask: 0x%x\n", pp->csr_ptr->csr_mask);
00300 }
00301
00302 csr_present= pp->csr_ptr->csr_present;
00303 csr_control= pp->csr_ptr->csr_control;
00304
00305 if ((csr_present & (CP_CDETECT1|CP_CDETECT2)) != 0)
00306 {
00307 if (debug)
00308 printf("do_int: no card present\n");
00309 return;
00310 }
00311 if (csr_present & CP_BADVCCREQ)
00312 {
00313 printf("do_int: Bad Vcc request\n");
00314
00315 }
00316 if (csr_present & CP_DATALOST)
00317 {
00318
00319 if (debug)
00320 printf("do_int: Data lost\n");
00321
00322 }
00323 if (csr_present & CP_NOTACARD)
00324 {
00325 printf("do_int: Not a card\n");
00326 return;
00327 }
00328 if (debug)
00329 {
00330 if (csr_present & CP_CBCARD)
00331 printf("do_int: Cardbus card detected\n");
00332 if (csr_present & CP_16BITCARD)
00333 printf("do_int: 16-bit card detected\n");
00334 }
00335 if (csr_present & CP_PWRCYCLE)
00336 {
00337 if (debug)
00338 printf("do_int: powered up\n");
00339 return;
00340 }
00341 vcc_5v= !!(csr_present & CP_5VCARD);
00342 vcc_3v= !!(csr_present & CP_3VCARD);
00343 vcc_Xv= !!(csr_present & CP_XVCARD);
00344 vcc_Yv= !!(csr_present & CP_YVCARD);
00345 if (debug)
00346 {
00347 printf("do_int: card supports:%s%s%s%s\n",
00348 vcc_5v ? " 5V" : "", vcc_3v ? " 3V" : "",
00349 vcc_Xv ? " X.X V" : "", vcc_Yv ? " Y.Y V" : "");
00350 }
00351 socket_5v= !!(csr_present & CP_5VSOCKET);
00352 socket_3v= !!(csr_present & CP_3VSOCKET);
00353 socket_Xv= !!(csr_present & CP_XVSOCKET);
00354 socket_Yv= !!(csr_present & CP_YVSOCKET);
00355 if (debug)
00356 {
00357 printf("do_int: socket supports:%s%s%s%s\n",
00358 socket_5v ? " 5V" : "", socket_3v ? " 3V" : "",
00359 socket_Xv ? " X.X V" : "", socket_Yv ? " Y.Y V" : "");
00360 }
00361 if (vcc_5v && socket_5v)
00362 {
00363 csr_control= (csr_control & ~CC_VCCCTRL) | CC_VCC_5V;
00364 pp->csr_ptr->csr_control= csr_control;
00365 if (debug)
00366 printf("do_int: applying 5V\n");
00367 }
00368 else if (vcc_3v && socket_3v)
00369 {
00370 csr_control= (csr_control & ~CC_VCCCTRL) | CC_VCC_3V;
00371 pp->csr_ptr->csr_control= csr_control;
00372 if (debug)
00373 printf("do_int: applying 3V\n");
00374 }
00375 else if (vcc_Xv && socket_Xv)
00376 {
00377 csr_control= (csr_control & ~CC_VCCCTRL) | CC_VCC_XV;
00378 pp->csr_ptr->csr_control= csr_control;
00379 printf("do_int: applying X.X V\n");
00380 }
00381 else if (vcc_Yv && socket_Yv)
00382 {
00383 csr_control= (csr_control & ~CC_VCCCTRL) | CC_VCC_YV;
00384 pp->csr_ptr->csr_control= csr_control;
00385 printf("do_int: applying Y.Y V\n");
00386 }
00387 else
00388 {
00389 printf("do_int: socket and card are not compatible\n");
00390 return;
00391 }
00392
00393 csr_event= pp->csr_ptr->csr_event;
00394 if (csr_event)
00395 {
00396 if (debug)
00397 printf("clearing socket event\n");
00398 pp->csr_ptr->csr_event= csr_event;
00399 if (debug)
00400 {
00401 printf("Socket event (cleared): 0x%x\n",
00402 pp->csr_ptr->csr_event);
00403 }
00404 }
00405
00406 devind= pp->p_devind;
00407 v8= pci_attr_r8(devind, TI_CARD_CTRL);
00408 if (v8 & TI_CCR_IFG)
00409 {
00410 printf("ti1225: got functional interrupt\n", v8);
00411 pci_attr_w8(devind, TI_CARD_CTRL, v8);
00412 }
00413
00414 if (debug)
00415 {
00416 v8= pci_attr_r8(devind, TI_CARD_CTRL);
00417 printf("TI_CARD_CTRL: 0x%02x\n", v8);
00418 }
00419
00420 getuptime(&t0);
00421 do {
00422 csr_present= pp->csr_ptr->csr_present;
00423 if (csr_present & CP_PWRCYCLE)
00424 break;
00425 } while (getuptime(&t1)==OK && (t1-t0) < MICROS_TO_TICKS(100000));
00426
00427 if (!(csr_present & CP_PWRCYCLE))
00428 {
00429 printf("do_int: not powered up?\n");
00430 return;
00431 }
00432
00433
00434 v16= pci_attr_r16(devind, CBB_BRIDGECTRL);
00435 v16 |= CBB_BC_CRST;
00436 pci_attr_w16(devind, CBB_BRIDGECTRL, v16);
00437
00438
00439 micro_delay(1);
00440
00441
00442 v16= pci_attr_r16(devind, CBB_BRIDGECTRL);
00443 v16 &= ~CBB_BC_CRST;
00444 pci_attr_w16(devind, CBB_BRIDGECTRL, v16);
00445
00446
00447
00448
00449 micro_delay(1);
00450
00451 pci_rescan_bus(pp->p_cb_busnr);
00452
00453 #if USE_INTS
00454 r= sys_irqenable(&pp->p_hook);
00455 if (r != OK)
00456 panic("ti1225","unable enable interrupts", r);
00457 #endif
00458
00459 }
00460
00461 PRIVATE u8_t read_exca(pp, socket, reg)
00462 struct port *pp;
00463 int socket;
00464 int reg;
00465 {
00466 u16_t port;
00467
00468 port= pp->p_exca_port;
00469 if (port == 0)
00470 panic("ti1225", "read_exca: bad port", NO_NUM);
00471 do_outb(port, socket * 0x40 + reg);
00472 return do_inb(port+1);
00473 }
00474
00475 PRIVATE u8_t do_inb(port_t port)
00476 {
00477 int r;
00478 u32_t value;
00479
00480 r= sys_inb(port, &value);
00481 if (r != OK)
00482 panic("ti1225","sys_inb failed", r);
00483 return value;
00484 }
00485
00486 PRIVATE void do_outb(port_t port, u8_t value)
00487 {
00488 int r;
00489
00490 r= sys_outb(port, value);
00491 if (r != OK)
00492 panic("ti1225","sys_outb failed", r);
00493 }
00494
00495 PRIVATE void micro_delay(unsigned long usecs)
00496 {
00497 tickdelay(MICROS_TO_TICKS(usecs));
00498 }
00499