00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 #include <time.h>
00056 #include "rt_pci.h"
00057
00058 #ifdef CONFIG_PCI_DIRECT
00059 #define PCIBIOS_SUCCESSFUL 0x00
00060
00061 #define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3))
00062
00063
00064
00079 int rt_pci_enable_wake(struct pci_dev *dev, u32 state, int enable)
00080 {
00081 int pm;
00082 u16 value;
00083
00084
00085 pm = rt_pci_find_capability(dev, PCI_CAP_ID_PM);
00086
00087
00088
00089 if (!pm)
00090 return enable ? -EIO : 0;
00091
00092
00093 rt_pci_read_config_word(dev,pm+PCI_PM_PMC,&value);
00094
00095 value &= PCI_PM_CAP_PME_MASK;
00096 value >>= ffs(value);
00097
00098
00099 if (!value || !(value & (1 << state)))
00100 return enable ? -EINVAL : 0;
00101
00102 rt_pci_read_config_word(dev, pm + PCI_PM_CTRL, &value);
00103
00104
00105 value |= PCI_PM_CTRL_PME_STATUS | PCI_PM_CTRL_PME_ENABLE;
00106
00107 if (!enable)
00108 value &= ~PCI_PM_CTRL_PME_ENABLE;
00109
00110 rt_pci_write_config_word(dev, pm + PCI_PM_CTRL, value);
00111
00112 return 0;
00113 }
00114
00115
00116
00125 int rt_pci_save_state(struct pci_dev *dev, u32 *buffer)
00126 {
00127 int i;
00128 if (buffer) {
00129
00130 for (i = 0; i < 16; i++)
00131 rt_pci_read_config_dword(dev, i * 4,&buffer[i]);
00132 }
00133 return 0;
00134 }
00135
00136
00137
00138
00139
00140
00141 int rt_pcibios_read_config_byte(unsigned int bus, unsigned int device_fn,
00142 unsigned int where, unsigned char *value)
00143 {
00144 outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
00145 *value = inb(0xCFC + (where&3));
00146 return PCIBIOS_SUCCESSFUL;
00147 }
00148
00149
00150 int rt_pcibios_read_config_word (unsigned int bus,
00151 unsigned int device_fn, unsigned int where, unsigned short *value)
00152 {
00153 outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
00154 *value = inw(0xCFC + (where&2));
00155 return PCIBIOS_SUCCESSFUL;
00156 }
00157
00158
00159 int rt_pcibios_read_config_dword (unsigned int bus, unsigned int device_fn,
00160 unsigned int where, unsigned int *value)
00161 {
00162 outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
00163 *value = inl(0xCFC);
00164 return PCIBIOS_SUCCESSFUL;
00165 }
00166
00167
00168 int rt_pcibios_write_config_byte (unsigned int bus, unsigned int device_fn,
00169 unsigned int where, unsigned char value)
00170 {
00171 outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
00172 outb(value, 0xCFC + (where&3));
00173 return PCIBIOS_SUCCESSFUL;
00174 }
00175
00176
00177 int rt_pcibios_write_config_word (unsigned int bus, unsigned int device_fn,
00178 unsigned int where, unsigned short value)
00179 {
00180 outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
00181 outw(value, 0xCFC + (where&2));
00182 return PCIBIOS_SUCCESSFUL;
00183 }
00184
00185
00186 int rt_pcibios_write_config_dword (unsigned int bus, unsigned int device_fn, unsigned int where, unsigned int value)
00187 {
00188 outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
00189 outl(value, 0xCFC);
00190 return PCIBIOS_SUCCESSFUL;
00191 }
00192
00193
00194 int rt_pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq){
00195 rt_pcibios_write_config_byte ((int) dev->bus, (int) dev->devfn,
00196 PCI_INTERRUPT_LINE, irq);
00197 rt_pcibios_write_config_byte ((int) dev->bus, (int)dev->devfn,
00198 PCI_INTERRUPT_PIN, pin);
00199 return 1;
00200 }
00201
00202
00203 #undef CONFIG_CMD
00204
00205 #else
00206
00207 static struct {
00208 unsigned long address;
00209 unsigned short segment;
00210 } bios32_indirect = { 0, KERN_CODE_SEG };
00211
00212 static long pcibios_entry;
00213 static struct {
00214 unsigned long address;
00215 unsigned short segment;
00216 } pci_indirect = { 0, KERN_CODE_SEG };
00217
00218
00219 static unsigned long bios32_service(unsigned long service)
00220 {
00221 unsigned char return_code;
00222 unsigned long address;
00223 unsigned long length;
00224 unsigned long entry;
00225 unsigned long flags;
00226
00227 save_flags(flags);
00228 __asm__(
00229 #ifdef ABSOLUTE_WITHOUT_ASTERISK
00230 "lcall (%%edi)"
00231 #else
00232 "lcall *(%%edi)"
00233 #endif
00234 : "=a" (return_code),
00235 "=b" (address),
00236 "=c" (length),
00237 "=d" (entry)
00238 : "0" (service),
00239 "1" (0),
00240 "D" (&bios32_indirect));
00241 restore_flags(flags);
00242
00243 switch (return_code) {
00244 case 0:
00245 return address + entry;
00246 case 0x80:
00247 ethernet_printf("bios32_service(%d) : no presente\n", service);
00248 return 0;
00249 default:
00250 ethernet_printf("bios32_service(%d) : devuelto %#X\n",
00251 service, return_code);
00252 return 0;
00253 }
00254 }
00255
00256
00257 int rt_pcibios_read_config_byte(unsigned int bus,
00258 unsigned int device_fn, unsigned int where, unsigned char *value)
00259 {
00260 unsigned long ret;
00261 unsigned long bx = (bus << 8) | device_fn;
00262 unsigned long flags;
00263
00264 save_flags(flags);
00265 __asm__(
00266 #ifdef ABSOLUTE_WITHOUT_ASTERISK
00267 "lcall (%%esi)\n\t"
00268 #else
00269 "lcall *(%%esi)\n\t"
00270 #endif
00271 "jc 1f\n\t"
00272 "xor %%ah, %%ah\n"
00273 "1:"
00274 : "=c" (*value),
00275 "=a" (ret)
00276 : "1" (PCIBIOS_READ_CONFIG_BYTE),
00277 "b" (bx),
00278 "D" ((long) where),
00279 "S" (&pci_indirect));
00280 restore_flags(flags);
00281 return (int) (ret & 0xff00) >> 8;
00282 }
00283
00284
00285 int rt_pcibios_read_config_word(unsigned int bus,
00286 unsigned int device_fn, unsigned int where, unsigned short *value)
00287 {
00288 unsigned long ret;
00289 unsigned long bx = (bus << 8) | device_fn;
00290 unsigned long flags;
00291
00292 save_flags(flags);
00293 __asm__(
00294 #ifdef ABSOLUTE_WITHOUT_ASTERISK
00295 "lcall (%%esi)\n\t"
00296 #else
00297 "lcall *(%%esi)\n\t"
00298 #endif
00299 "jc 1f\n\t"
00300 "xor %%ah, %%ah\n"
00301 "1:"
00302 : "=c" (*value),
00303 "=a" (ret)
00304 : "1" (PCIBIOS_READ_CONFIG_WORD),
00305 "b" (bx),
00306 "D" ((long) where),
00307 "S" (&pci_indirect));
00308 restore_flags(flags);
00309 return (int) (ret & 0xff00) >> 8;
00310 }
00311
00312
00313 int rt_pcibios_read_config_dword(unsigned int bus,
00314 unsigned int device_fn, unsigned int where, unsigned int *value)
00315 {
00316 unsigned long ret;
00317 unsigned long bx = (bus << 8) | device_fn;
00318 unsigned long flags;
00319
00320 save_flags(flags);
00321 __asm__(
00322 #ifdef ABSOLUTE_WITHOUT_ASTERISK
00323 "lcall (%%esi)\n\t"
00324 #else
00325 "lcall *(%%esi)\n\t"
00326 #endif
00327 "jc 1f\n\t"
00328 "xor %%ah, %%ah\n"
00329 "1:"
00330 : "=c" (*value),
00331 "=a" (ret)
00332 : "1" (PCIBIOS_READ_CONFIG_DWORD),
00333 "b" (bx),
00334 "D" ((long) where),
00335 "S" (&pci_indirect));
00336 restore_flags(flags);
00337 return (int) (ret & 0xff00) >> 8;
00338 }
00339
00340
00341 int rt_pcibios_write_config_byte (unsigned int bus,
00342 unsigned int device_fn, unsigned int where, unsigned char value)
00343 {
00344 unsigned long ret;
00345 unsigned long bx = (bus << 8) | device_fn;
00346 unsigned long flags;
00347
00348 save_flags(flags); cli();
00349 __asm__(
00350 #ifdef ABSOLUTE_WITHOUT_ASTERISK
00351 "lcall (%%esi)\n\t"
00352 #else
00353 "lcall *(%%esi)\n\t"
00354 #endif
00355 "jc 1f\n\t"
00356 "xor %%ah, %%ah\n"
00357 "1:"
00358 : "=a" (ret)
00359 : "0" (PCIBIOS_WRITE_CONFIG_BYTE),
00360 "c" (value),
00361 "b" (bx),
00362 "D" ((long) where),
00363 "S" (&pci_indirect));
00364 restore_flags(flags);
00365 return (int) (ret & 0xff00) >> 8;
00366 }
00367
00368
00369
00370
00371
00372 int rt_pcibios_write_config_word (unsigned int bus,
00373 unsigned int device_fn, unsigned int where, unsigned short value)
00374 {
00375 unsigned long ret;
00376 unsigned long bx = (bus << 8) | device_fn;
00377 unsigned long flags;
00378
00379 save_flags(flags); cli();
00380 __asm__(
00381 #ifdef ABSOLUTE_WITHOUT_ASTERISK
00382 "lcall (%%esi)\n\t"
00383 #else
00384 "lcall *(%%esi)\n\t"
00385 #endif
00386 "jc 1f\n\t"
00387 "xor %%ah, %%ah\n"
00388 "1:"
00389 : "=a" (ret)
00390 : "0" (PCIBIOS_WRITE_CONFIG_WORD),
00391 "c" (value),
00392 "b" (bx),
00393 "D" ((long) where),
00394 "S" (&pci_indirect));
00395 restore_flags(flags);
00396 return (int) (ret & 0xff00) >> 8;
00397 }
00398
00399
00400 int rt_pcibios_write_config_dword (unsigned int bus,
00401 unsigned int device_fn, unsigned int where, unsigned int value)
00402 {
00403 unsigned long ret;
00404 unsigned long bx = (bus << 8) | device_fn;
00405 unsigned long flags;
00406
00407 save_flags(flags); cli();
00408 __asm__(
00409 #ifdef ABSOLUTE_WITHOUT_ASTERISK
00410 "lcall (%%esi)\n\t"
00411 #else
00412 "lcall *(%%esi)\n\t"
00413 #endif
00414 "jc 1f\n\t"
00415 "xor %%ah, %%ah\n"
00416 "1:"
00417 : "=a" (ret)
00418 : "0" (PCIBIOS_WRITE_CONFIG_DWORD),
00419 "c" (value),
00420 "b" (bx),
00421 "D" ((long) where),
00422 "S" (&pci_indirect));
00423 restore_flags(flags);
00424 return (int) (ret & 0xff00) >> 8;
00425 }
00426
00427
00428 static void check_pcibios(void)
00429 {
00430 unsigned long signature;
00431 unsigned char present_status;
00432 unsigned char major_revision;
00433 unsigned char minor_revision;
00434 unsigned long flags;
00435 int pack;
00436
00437 if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
00438 pci_indirect.address = pcibios_entry;
00439
00440 save_flags(flags);
00441 __asm__(
00442 #ifdef ABSOLUTE_WITHOUT_ASTERISK
00443 "lcall (%%edi)\n\t"
00444 #else
00445 "lcall *(%%edi)\n\t"
00446 #endif
00447 "jc 1f\n\t"
00448 "xor %%ah, %%ah\n"
00449 "1:\tshl $8, %%eax\n\t"
00450 "movw %%bx, %%ax"
00451 : "=d" (signature),
00452 "=a" (pack)
00453 : "1" (PCIBIOS_PCI_BIOS_PRESENT),
00454 "D" (&pci_indirect)
00455 : "bx", "cx");
00456 restore_flags(flags);
00457
00458 present_status = (pack >> 16) & 0xff;
00459 major_revision = (pack >> 8) & 0xff;
00460 minor_revision = pack & 0xff;
00461 if (present_status || (signature != PCI_SIGNATURE)) {
00462 printf("ERROR: BIOS32 dice PCI BIOS, pero no PCI "
00463 "BIOS????\n");
00464 pcibios_entry = 0;
00465 }
00466 #if DEBUG
00467 if (pcibios_entry) {
00468 printf ("pcibios_init : PCI BIOS revision %hhX.%hhX"
00469 " entrada en %#X\n", major_revision,
00470 minor_revision, pcibios_entry);
00471 }
00472 #endif
00473 }
00474 }
00475
00476
00477 static void pcibios_init(void)
00478 {
00479 union bios32 *check;
00480 unsigned char sum;
00481 int i, length;
00482 unsigned long bios32_entry = 0;
00483
00484
00485
00486
00487
00488
00489
00490 for (check = (union bios32 *) 0xe0000; check <= (union bios32 *) 0xffff0; ++check) {
00491 if (check->fields.signature != BIOS32_SIGNATURE)
00492 continue;
00493 length = check->fields.length * 16;
00494 if (!length)
00495 continue;
00496 sum = 0;
00497 for (i = 0; i < length ; ++i)
00498 sum += check->chars[i];
00499 if (sum != 0)
00500 continue;
00501 if (check->fields.revision != 0) {
00502 printf("pcibios_init : revision no soportada %d en %#X\n", check->fields.revision,(unsigned int) check);
00503 continue;
00504 }
00505 #if DEBUG
00506 printf("pcibios_init : BIOS32 Service Directory "
00507 "estructura en %#X\n", check);
00508 #endif
00509 if (!bios32_entry) {
00510 if (check->fields.entry >= 0x100000) {
00511 printf("pcibios_init: entrada en la memoria alta\n");
00512 return;
00513 } else {
00514 bios32_entry = check->fields.entry;
00515 #if DEBUG
00516 printf("pcibios_init : BIOS32 Service Directory \nentrada en %#X\n", bios32_entry);
00517 #endif
00518 bios32_indirect.address = bios32_entry;
00519 }
00520 }
00521 }
00522 if (bios32_entry)
00523 check_pcibios();
00524 }
00525
00526
00527 int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq)
00528 {
00529 int ret;
00530
00531 __asm__(
00532 #ifdef ABSOLUTE_WITHOUT_ASTERISK
00533 "lcall (%%esi); cld\n\t"
00534 #else
00535 "lcall *(%%esi); cld\n\t"
00536 #endif
00537 "jc 1f\n\t"
00538 "xor %%ah, %%ah\n"
00539 "1:"
00540 : "=a" (ret)
00541 : "0" (PCIBIOS_SET_PCI_HW_INT),
00542 "b" ((dev->bus << 8) | dev->devfn),
00543 "c" ((irq << 8) | (pin + 10)),
00544 "S" (&pci_indirect));
00545 return !(ret & 0xff00);
00546 }
00547
00548 #endif
00549
00550
00551
00552 int rt_pci_set_power_state(struct pci_dev *dev, int state)
00553 {
00554 int pm;
00555 u16 pmcsr;
00556
00557
00558 if (state > 3) state = 3;
00559
00560
00561
00562
00563
00564 if (state > 0 && dev->current_state > state)
00565 return -EINVAL;
00566 else if (dev->current_state == state)
00567 return 0;
00568
00569
00570 pm = rt_pci_find_capability(dev, PCI_CAP_ID_PM);
00571
00572
00573 if (!pm) return -EIO;
00574
00575
00576 if (state == 1 || state == 2) {
00577 u16 pmc;
00578 rt_pci_read_config_word(dev,pm + PCI_PM_PMC,&pmc);
00579 if (state == 1 && !(pmc & PCI_PM_CAP_D1)) return -EIO;
00580 else if (state == 2 && !(pmc & PCI_PM_CAP_D2)) return -EIO;
00581 }
00582
00583
00584
00585
00586
00587 if (dev->current_state >= 3)
00588 pmcsr = 0;
00589 else {
00590 rt_pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr);
00591 pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
00592 pmcsr |= state;
00593 }
00594
00595
00596 rt_pci_write_config_word(dev, pm + PCI_PM_CTRL, pmcsr);
00597
00598
00599
00600 if(state == 3 || dev->current_state == 3)
00601 {
00602
00603
00604 rtl_delay(200000);
00605 }
00606 else if(state == 2 || dev->current_state == 2)
00607 rtl_delay(200000);
00608 dev->current_state = state;
00609
00610 return 0;
00611 }
00612
00613
00636 int rt_pci_find_capability(struct pci_dev *dev, int cap)
00637 {
00638 u16 status;
00639 u8 pos, id;
00640 int ttl = 48;
00641
00642 rt_pci_read_config_word(dev, PCI_STATUS, &status);
00643 if (!(status & PCI_STATUS_CAP_LIST))
00644 return 0;
00645 switch (dev->hdr_type) {
00646 case PCI_HEADER_TYPE_NORMAL:
00647 case PCI_HEADER_TYPE_BRIDGE:
00648 rt_pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &pos);
00649 break;
00650 case PCI_HEADER_TYPE_CARDBUS:
00651 rt_pci_read_config_byte(dev, PCI_CB_CAPABILITY_LIST, &pos);
00652 break;
00653 default:
00654 return 0;
00655 }
00656 while (ttl-- && pos >= 0x40) {
00657 pos &= ~3;
00658 rt_pci_read_config_byte(dev, pos + PCI_CAP_LIST_ID, &id);
00659 if (id == 0xff)
00660 break;
00661 if (id == cap)
00662 return pos;
00663 rt_pci_read_config_byte(dev, pos + PCI_CAP_LIST_NEXT, &pos);
00664 }
00665 return 0;
00666 }
00667
00668
00669
00670
00671
00672 struct pci_dev * rt_pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev *from){
00673 return(pci_find_device(vendor, device, from));
00674 }
00675
00676
00677
00678
00679 int rt_pci_enable_device(struct pci_dev *dev){
00680 return(pci_enable_device(dev));
00681 }
00682
00683
00684
00691 int rt_pci_restore_state(struct pci_dev *dev, u32 *buffer)
00692 {
00693 int i;
00694
00695 if (buffer) {
00696 for (i = 0; i < 16; i++)
00697 rt_pci_write_config_dword(dev,i * 4, buffer[i]);
00698 }
00699
00700
00701
00702
00703
00704
00705 else {
00706 for (i = 0; i < 6; i ++)
00707 rt_pci_write_config_dword(dev,
00708 PCI_BASE_ADDRESS_0 + (i * 4),
00709 dev->resource[i].start);
00710 rt_pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
00711 }
00712 return 0;
00713 }