?? pci.c
字號:
bus = device->bus->number; dev = PCI_SLOT(device->devfn); if (pci_range_ck(bus, dev)) return PCIBIOS_DEVICE_NOT_FOUND; if (bus == 0) tmp = pci0ReadConfigReg(offset, device);// if (bus == 1) tmp = pci1ReadConfigReg (offset,device); if ((offset % 4) == 0) tmp = (tmp & 0xffffff00) | (val & 0xff); if ((offset % 4) == 1) tmp = (tmp & 0xffff00ff) | ((val & 0xff) << 8); if ((offset % 4) == 2) tmp = (tmp & 0xff00ffff) | ((val & 0xff) << 16); if ((offset % 4) == 3) tmp = (tmp & 0x00ffffff) | ((val & 0xff) << 24); if (bus == 0) pci0WriteConfigReg(offset, device, tmp);// if (bus == 1) pci1WriteConfigReg (offset,device,tmp); return PCIBIOS_SUCCESSFUL;}static void galileo_pcibios_set_master(struct pci_dev *dev){ u16 cmd; galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); cmd |= PCI_COMMAND_MASTER; galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd);}/* Externally-expected functions. Do not change function names */int pcibios_enable_resources(struct pci_dev *dev){ u16 cmd, old_cmd; u8 tmp1; int idx; struct resource *r; galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); old_cmd = cmd; for (idx = 0; idx < 6; idx++) { r = &dev->resource[idx]; if (!r->start && r->end) { printk(KERN_ERR "PCI: Device %s not available because of " "resource collisions\n", dev->slot_name); return -EINVAL; } if (r->flags & IORESOURCE_IO) cmd |= PCI_COMMAND_IO; if (r->flags & IORESOURCE_MEM) cmd |= PCI_COMMAND_MEMORY; } if (cmd != old_cmd) { galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd); } /* * Let's fix up the latency timer and cache line size here. Cache * line size = 32 bytes / sizeof dword (4) = 8. * Latency timer must be > 8. 32 is random but appears to work. */ galileo_pcibios_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1); if (tmp1 != 8) { printk(KERN_WARNING "PCI setting cache line size to 8 from " "%d\n", tmp1); galileo_pcibios_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8); } galileo_pcibios_read_config_byte(dev, PCI_LATENCY_TIMER, &tmp1); if (tmp1 < 32) { printk(KERN_WARNING "PCI setting latency timer to 32 from %d\n", tmp1); galileo_pcibios_write_config_byte(dev, PCI_LATENCY_TIMER, 32); } return 0;}int pcibios_enable_device(struct pci_dev *dev){ return pcibios_enable_resources(dev);}void pcibios_update_resource(struct pci_dev *dev, struct resource *root, struct resource *res, int resource){ u32 new, check; int reg; return; new = res->start | (res->flags & PCI_REGION_FLAG_MASK); if (resource < 6) { reg = PCI_BASE_ADDRESS_0 + 4 * resource; } else if (resource == PCI_ROM_RESOURCE) { res->flags |= PCI_ROM_ADDRESS_ENABLE; reg = dev->rom_base_reg; } else { /* * Somebody might have asked allocation of a non-standard * resource */ return; } pci_write_config_dword(dev, reg, new); pci_read_config_dword(dev, reg, &check); if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) { printk(KERN_ERR "PCI: Error while updating region " "%s/%d (%08x != %08x)\n", dev->slot_name, resource, new, check); }}void pcibios_align_resource(void *data, struct resource *res, unsigned long size){ struct pci_dev *dev = data; if (res->flags & IORESOURCE_IO) { unsigned long start = res->start; /* We need to avoid collisions with `mirrored' VGA ports and other strange ISA hardware, so we always want the addresses kilobyte aligned. */ if (size > 0x100) { printk(KERN_ERR "PCI: I/O Region %s/%d too large" " (%ld bytes)\n", dev->slot_name, dev->resource - res, size); } start = (start + 1024 - 1) & ~(1024 - 1); res->start = start; }}struct pci_ops galileo_pci_ops = { galileo_pcibios_read_config_byte, galileo_pcibios_read_config_word, galileo_pcibios_read_config_dword, galileo_pcibios_write_config_byte, galileo_pcibios_write_config_word, galileo_pcibios_write_config_dword};struct pci_fixup pcibios_fixups[] = { {0}};void __init pcibios_fixup_bus(struct pci_bus *c){ gt64120_board_pcibios_fixup_bus(c);}/* * This code was derived from Galileo Technology's example * and significantly reworked. * * This is very simple. It does not scan multiple function devices. It does * not scan behind bridges. Those would be simple to implement, but we don't * currently need this. */static void __init scan_and_initialize_pci(void){ struct pci_device pci_devices[MAX_PCI_DEVS]; if (scan_pci_bus(pci_devices)) { allocate_pci_space(pci_devices); }}/* * This is your basic PCI scan. It goes through each slot and checks to * see if there's something that responds. If so, then get the size and * type of each of the responding BARs. Save them for later. */static u32 __init scan_pci_bus(struct pci_device *pci_devices){ u32 arrayCounter = 0; u32 memType; u32 memSize; u32 pci_slot, bar; u32 id; u32 c18RegValue; struct pci_dev device; /* * According to PCI REV 2.1 MAX agents on the bus are 21. * We don't bother scanning ourselves (slot 0). */ for (pci_slot = 1; pci_slot < 22; pci_slot++) { device.devfn = PCI_DEVFN(pci_slot, 0); id = pci0ReadConfigReg(PCI_VENDOR_ID, &device); /* * Check for a PCI Master Abort (nothing responds in the * slot) */ GT_READ(GT_INTRCAUSE_OFS, &c18RegValue); /* * Clearing bit 18 of in the Cause Register 0xc18 by * writting 0. */ GT_WRITE(GT_INTRCAUSE_OFS, (c18RegValue & 0xfffbffff)); if ((id != 0xffffffff) && !(c18RegValue & 0x40000)) { pci_devices[arrayCounter].slot = pci_slot; for (bar = 0; bar < 6; bar++) { memType = pci0ReadConfigReg(PCI_BASE_ADDRESS_0 + (bar * 4), &device); pci_devices[arrayCounter].BARtype[bar] = memType & 1; pci0WriteConfigReg(PCI_BASE_ADDRESS_0 + (bar * 4), &device, 0xffffffff); memSize = pci0ReadConfigReg(PCI_BASE_ADDRESS_0 + (bar * 4), &device); if (memType & 1) { /* IO space */ pci_devices[arrayCounter]. BARsize[bar] = ~(memSize & 0xfffffffc) + 1; } else { /* memory space */ pci_devices[arrayCounter]. BARsize[bar] = ~(memSize & 0xfffffff0) + 1; } } /* BAR counter */ arrayCounter++; } /* found a device */ } /* slot counter */ if (arrayCounter < MAX_PCI_DEVS) pci_devices[arrayCounter].slot = -1; return arrayCounter;}#define ALIGN(val,align) (((val) + ((align) - 1)) & ~((align) - 1))#define MAX(val1, val2) ((val1) > (val2) ? (val1) : (val2))/* * This function goes through the list of devices and allocates the BARs in * either IO or MEM space. It does it in order of size, which will limit the * amount of fragmentation we have in the IO and MEM spaces. */static void __init allocate_pci_space(struct pci_device *pci_devices){ u32 count, maxcount, bar; u32 maxSize, maxDevice, maxBAR; u32 alignto; u32 base; u32 pci0_mem_base = pci0GetMemory0Base(); u32 pci0_io_base = pci0GetIOspaceBase(); struct pci_dev device; /* How many PCI devices do we have? */ maxcount = MAX_PCI_DEVS; for (count = 0; count < MAX_PCI_DEVS; count++) { if (pci_devices[count].slot == -1) { maxcount = count; break; } } do { /* Find the largest size BAR we need to allocate */ maxSize = 0; for (count = 0; count < maxcount; count++) { for (bar = 0; bar < 6; bar++) { if (pci_devices[count].BARsize[bar] > maxSize) { maxSize = pci_devices[count]. BARsize[bar]; maxDevice = count; maxBAR = bar; } } } /* * We've found the largest BAR. Allocate it into IO or * mem space. We don't idiot check the bases to make * sure they haven't overflowed the current size for that * aperture. * Don't bother to enable the device's IO or MEM space here. * That will be done in pci_enable_resources if the device is * activated by a driver. */ if (maxSize) { device.devfn = PCI_DEVFN(pci_devices[maxDevice].slot, 0); if (pci_devices[maxDevice].BARtype[maxBAR] == 1) { alignto = MAX(0x1000, maxSize); base = ALIGN(pci0_io_base, alignto); pci0WriteConfigReg(PCI_BASE_ADDRESS_0 + (maxBAR * 4), &device, base | 0x1); pci0_io_base = base + alignto; } else { alignto = MAX(0x1000, maxSize); base = ALIGN(pci0_mem_base, alignto); pci0WriteConfigReg(PCI_BASE_ADDRESS_0 + (maxBAR * 4), &device, base); pci0_mem_base = base + alignto; } /* * This entry is finished. Remove it from the list * we'll scan. */ pci_devices[maxDevice].BARsize[maxBAR] = 0; } } while (maxSize);}void __init pcibios_init(void){ u32 tmp; struct pci_dev controller; controller.devfn = SELF; GT_READ(GT_PCI0_CMD_OFS, &tmp); GT_READ(GT_PCI0_BARE_OFS, &tmp); /* * You have to enable bus mastering to configure any other * card on the bus. */ tmp = pci0ReadConfigReg(PCI_COMMAND, &controller); tmp |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SERR; pci0WriteConfigReg(PCI_COMMAND, &controller, tmp); /* This scans the PCI bus and sets up initial values. */ scan_and_initialize_pci(); /* * Reset PCI I/O and PCI MEM values to ones supported by EVM. */ ioport_resource.start = GT_PCI_IO_BASE; ioport_resource.end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1; iomem_resource.start = GT_PCI_MEM_BASE; iomem_resource.end = GT_PCI_MEM_BASE + GT_PCI_MEM_BASE - 1; pci_scan_bus(0, &galileo_pci_ops, NULL);}/* * for parsing "pci=" kernel boot arguments. */char *pcibios_setup(char *str){ printk(KERN_INFO "rr: pcibios_setup\n"); /* Nothing to do for now. */ return str;}unsigned __init int pcibios_assign_all_busses(void){ return 1;}#endif /* CONFIG_PCI */
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -