📄 setup.c
字号:
if (early_read_config_word(hose, top_bus, current_bus, pci_devfn, PCI_VENDOR_ID, &vid) != PCIBIOS_SUCCESSFUL) continue; if (vid == 0xffff) continue; /* check 66MHz capability */ if (cap66 < 0) cap66 = 1; if (cap66) { early_read_config_word(hose, top_bus, current_bus, pci_devfn, PCI_STATUS, &stat); if (!(stat & PCI_STATUS_66MHZ)) { printk(KERN_DEBUG "PCI: %02x:%02x not 66MHz capable.\n", current_bus, pci_devfn); cap66 = 0; break; } } } return cap66 > 0;}int __inittx4938_pciclk66_setup(void){ int pciclk; /* Assert M66EN */ tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI66; /* Double PCICLK (if possible) */ if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) { unsigned int pcidivmode = tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIDIVMODE_MASK; switch (pcidivmode) { case TX4938_CCFG_PCIDIVMODE_8: case TX4938_CCFG_PCIDIVMODE_4: pcidivmode = TX4938_CCFG_PCIDIVMODE_4; pciclk = txx9_cpu_clock / 4; break; case TX4938_CCFG_PCIDIVMODE_9: case TX4938_CCFG_PCIDIVMODE_4_5: pcidivmode = TX4938_CCFG_PCIDIVMODE_4_5; pciclk = txx9_cpu_clock * 2 / 9; break; case TX4938_CCFG_PCIDIVMODE_10: case TX4938_CCFG_PCIDIVMODE_5: pcidivmode = TX4938_CCFG_PCIDIVMODE_5; pciclk = txx9_cpu_clock / 5; break; case TX4938_CCFG_PCIDIVMODE_11: case TX4938_CCFG_PCIDIVMODE_5_5: default: pcidivmode = TX4938_CCFG_PCIDIVMODE_5_5; pciclk = txx9_cpu_clock * 2 / 11; break; } tx4938_ccfgptr->ccfg = (tx4938_ccfgptr->ccfg & ~TX4938_CCFG_PCIDIVMODE_MASK) | pcidivmode; printk(KERN_DEBUG "PCICLK: ccfg:%08lx\n", (unsigned long)tx4938_ccfgptr->ccfg); } else { pciclk = -1; } return pciclk;}extern struct pci_controller tx4938_pci_controller[];static int __init tx4938_pcibios_init(void){ unsigned long mem_base[2]; unsigned long mem_size[2] = {TX4938_PCIMEM_SIZE_0, TX4938_PCIMEM_SIZE_1}; /* MAX 128M,64K */ unsigned long io_base[2]; unsigned long io_size[2] = {TX4938_PCIIO_SIZE_0, TX4938_PCIIO_SIZE_1}; /* MAX 16M,64K */ /* TX4938 PCIC1: 64K MEM/IO is enough for ETH0,ETH1 */ int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB); PCIBIOS_MIN_IO = 0x00001000UL; mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]); io_base[0] = txboard_request_phys_region_shrink(&io_size[0]); printk("TX4938 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n", (unsigned short)(tx4938_pcicptr->pciid >> 16), (unsigned short)(tx4938_pcicptr->pciid & 0xffff), (unsigned short)(tx4938_pcicptr->pciccrev & 0xff), extarb ? "External" : "Internal"); /* setup PCI area */ tx4938_pci_controller[0].io_resource->start = io_base[0]; tx4938_pci_controller[0].io_resource->end = (io_base[0] + io_size[0]) - 1; tx4938_pci_controller[0].mem_resource->start = mem_base[0]; tx4938_pci_controller[0].mem_resource->end = mem_base[0] + mem_size[0] - 1; set_tx4938_pcicptr(0, tx4938_pcicptr); register_pci_controller(&tx4938_pci_controller[0]); if (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) { printk("TX4938_CCFG_PCI66 already configured\n"); txboard_pci66_mode = -1; /* already configured */ } /* Reset PCI Bus */ *rbtx4938_pcireset_ptr = 0; /* Reset PCIC */ tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST; if (txboard_pci66_mode > 0) tx4938_pciclk66_setup(); mdelay(10); /* clear PCIC reset */ tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST; *rbtx4938_pcireset_ptr = 1; wbflush(); tx4938_report_pcic_status1(tx4938_pcicptr); tx4938_report_pciclk(); tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb); if (txboard_pci66_mode == 0 && txboard_pci66_check(&tx4938_pci_controller[0], 0, 0)) { /* Reset PCI Bus */ *rbtx4938_pcireset_ptr = 0; /* Reset PCIC */ tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST; tx4938_pciclk66_setup(); mdelay(10); /* clear PCIC reset */ tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST; *rbtx4938_pcireset_ptr = 1; wbflush(); /* Reinitialize PCIC */ tx4938_report_pciclk(); tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb); } mem_base[1] = txboard_request_phys_region_shrink(&mem_size[1]); io_base[1] = txboard_request_phys_region_shrink(&io_size[1]); /* Reset PCIC1 */ tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIC1RST; /* PCI1DMD==0 => PCI1CLK==GBUSCLK/2 => PCI66 */ if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD)) tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI1_66; else tx4938_ccfgptr->ccfg &= ~TX4938_CCFG_PCI1_66; mdelay(10); /* clear PCIC1 reset */ tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST; tx4938_report_pcic_status1(tx4938_pcic1ptr); printk("TX4938 PCIC1 -- DID:%04x VID:%04x RID:%02x", (unsigned short)(tx4938_pcic1ptr->pciid >> 16), (unsigned short)(tx4938_pcic1ptr->pciid & 0xffff), (unsigned short)(tx4938_pcic1ptr->pciccrev & 0xff)); printk("%s PCICLK:%dMHz\n", (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1_66) ? " PCI66" : "", txx9_gbus_clock / ((tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD) ? 4 : 2) / 1000000); /* assumption: CPHYSADDR(mips_io_port_base) == io_base[0] */ tx4938_pci_controller[1].io_resource->start = io_base[1] - io_base[0]; tx4938_pci_controller[1].io_resource->end = io_base[1] - io_base[0] + io_size[1] - 1; tx4938_pci_controller[1].mem_resource->start = mem_base[1]; tx4938_pci_controller[1].mem_resource->end = mem_base[1] + mem_size[1] - 1; set_tx4938_pcicptr(1, tx4938_pcic1ptr); register_pci_controller(&tx4938_pci_controller[1]); tx4938_pcic_setup(tx4938_pcic1ptr, &tx4938_pci_controller[1], io_base[1], extarb); /* map ioport 0 to PCI I/O space address 0 */ set_io_port_base(KSEG1 + io_base[0]); return 0;}arch_initcall(tx4938_pcibios_init);#endif /* CONFIG_PCI *//* SPI support *//* chip select for SPI devices */#define SEEPROM1_CS 7 /* PIO7 */#define SEEPROM2_CS 0 /* IOC */#define SEEPROM3_CS 1 /* IOC */#define SRTC_CS 2 /* IOC */#ifdef CONFIG_PCIstatic int __init rbtx4938_ethaddr_init(void){ unsigned char dat[17]; unsigned char sum; int i; /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */ if (spi_eeprom_read(SEEPROM1_CS, 0, dat, sizeof(dat))) { printk(KERN_ERR "seeprom: read error.\n"); return -ENODEV; } else { if (strcmp(dat, "MAC") != 0) printk(KERN_WARNING "seeprom: bad signature.\n"); for (i = 0, sum = 0; i < sizeof(dat); i++) sum += dat[i]; if (sum) printk(KERN_WARNING "seeprom: bad checksum.\n"); } for (i = 0; i < 2; i++) { unsigned int id = TXX9_IRQ_BASE + (i ? TX4938_IR_ETH1 : TX4938_IR_ETH0); struct platform_device *pdev; if (!(tx4938_ccfgptr->pcfg & (i ? TX4938_PCFG_ETH1_SEL : TX4938_PCFG_ETH0_SEL))) continue; pdev = platform_device_alloc("tc35815-mac", id); if (!pdev || platform_device_add_data(pdev, &dat[4 + 6 * i], 6) || platform_device_add(pdev)) platform_device_put(pdev); } return 0;}device_initcall(rbtx4938_ethaddr_init);#endif /* CONFIG_PCI */static void __init rbtx4938_spi_setup(void){ /* set SPI_SEL */ tx4938_ccfgptr->pcfg |= TX4938_PCFG_SPI_SEL; /* chip selects for SPI devices */ tx4938_pioptr->dout |= (1 << SEEPROM1_CS); tx4938_pioptr->dir |= (1 << SEEPROM1_CS);}static struct resource rbtx4938_fpga_resource;static char pcode_str[8];static struct resource tx4938_reg_resource = { .start = TX4938_REG_BASE, .end = TX4938_REG_BASE + TX4938_REG_SIZE, .name = pcode_str, .flags = IORESOURCE_MEM};void __init tx4938_board_setup(void){ int i; unsigned long divmode; int cpuclk = 0; unsigned long pcode = TX4938_REV_PCODE(); ioport_resource.start = 0x1000; ioport_resource.end = 0xffffffff; iomem_resource.start = 0x1000; iomem_resource.end = 0xffffffff; /* expand to 4GB */ sprintf(pcode_str, "TX%lx", pcode); /* SDRAMC,EBUSC are configured by PROM */ for (i = 0; i < 8; i++) { if (!(tx4938_ebuscptr->cr[i] & 0x8)) continue; /* disabled */ rbtx4938_ce_base[i] = (unsigned long)TX4938_EBUSC_BA(i); txboard_add_phys_region(rbtx4938_ce_base[i], TX4938_EBUSC_SIZE(i)); } /* clocks */ if (txx9_master_clock) { /* calculate gbus_clock and cpu_clock_freq from master_clock */ divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK; switch (divmode) { case TX4938_CCFG_DIVMODE_8: case TX4938_CCFG_DIVMODE_10: case TX4938_CCFG_DIVMODE_12: case TX4938_CCFG_DIVMODE_16: case TX4938_CCFG_DIVMODE_18: txx9_gbus_clock = txx9_master_clock * 4; break; default: txx9_gbus_clock = txx9_master_clock; } switch (divmode) { case TX4938_CCFG_DIVMODE_2: case TX4938_CCFG_DIVMODE_8: cpuclk = txx9_gbus_clock * 2; break; case TX4938_CCFG_DIVMODE_2_5: case TX4938_CCFG_DIVMODE_10: cpuclk = txx9_gbus_clock * 5 / 2; break; case TX4938_CCFG_DIVMODE_3: case TX4938_CCFG_DIVMODE_12: cpuclk = txx9_gbus_clock * 3; break; case TX4938_CCFG_DIVMODE_4: case TX4938_CCFG_DIVMODE_16: cpuclk = txx9_gbus_clock * 4; break; case TX4938_CCFG_DIVMODE_4_5: case TX4938_CCFG_DIVMODE_18: cpuclk = txx9_gbus_clock * 9 / 2; break; } txx9_cpu_clock = cpuclk; } else { if (txx9_cpu_clock == 0) { txx9_cpu_clock = 300000000; /* 300MHz */ } /* calculate gbus_clock and master_clock from cpu_clock_freq */ cpuclk = txx9_cpu_clock; divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK; switch (divmode) { case TX4938_CCFG_DIVMODE_2: case TX4938_CCFG_DIVMODE_8: txx9_gbus_clock = cpuclk / 2; break; case TX4938_CCFG_DIVMODE_2_5: case TX4938_CCFG_DIVMODE_10: txx9_gbus_clock = cpuclk * 2 / 5; break; case TX4938_CCFG_DIVMODE_3: case TX4938_CCFG_DIVMODE_12: txx9_gbus_clock = cpuclk / 3; break; case TX4938_CCFG_DIVMODE_4: case TX4938_CCFG_DIVMODE_16: txx9_gbus_clock = cpuclk / 4; break; case TX4938_CCFG_DIVMODE_4_5: case TX4938_CCFG_DIVMODE_18: txx9_gbus_clock = cpuclk * 2 / 9; break; } switch (divmode) { case TX4938_CCFG_DIVMODE_8: case TX4938_CCFG_DIVMODE_10: case TX4938_CCFG_DIVMODE_12: case TX4938_CCFG_DIVMODE_16: case TX4938_CCFG_DIVMODE_18: txx9_master_clock = txx9_gbus_clock / 4; break; default: txx9_master_clock = txx9_gbus_clock; } } /* change default value to udelay/mdelay take reasonable time */ loops_per_jiffy = txx9_cpu_clock / HZ / 2; /* CCFG */ /* clear WatchDogReset,BusErrorOnWrite flag (W1C) */ tx4938_ccfgptr->ccfg |= TX4938_CCFG_WDRST | TX4938_CCFG_BEOW; /* clear PCIC1 reset */ if (tx4938_ccfgptr->clkctr & TX4938_CLKCTR_PCIC1RST) tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST; /* enable Timeout BusError */ if (tx4938_ccfg_toeon) tx4938_ccfgptr->ccfg |= TX4938_CCFG_TOE; /* DMA selection */ tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_DMASEL_ALL; /* Use external clock for external arbiter */ if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB)) tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_PCICLKEN_ALL; printk("%s -- %dMHz(M%dMHz) CRIR:%08lx CCFG:%Lx PCFG:%Lx\n", pcode_str, cpuclk / 1000000, txx9_master_clock / 1000000, (unsigned long)tx4938_ccfgptr->crir, tx4938_ccfgptr->ccfg, tx4938_ccfgptr->pcfg); printk("%s SDRAMC --", pcode_str); for (i = 0; i < 4; i++) { unsigned long long cr = tx4938_sdramcptr->cr[i]; unsigned long ram_base, ram_size; if (!((unsigned long)cr & 0x00000400)) continue; /* disabled */ ram_base = (unsigned long)(cr >> 49) << 21; ram_size = ((unsigned long)(cr >> 33) + 1) << 21; if (ram_base >= 0x20000000) continue; /* high memory (ignore) */ printk(" CR%d:%016Lx", i, cr); txboard_add_phys_region(ram_base, ram_size); } printk(" TR:%09Lx\n", tx4938_sdramcptr->tr); /* SRAM */ if (pcode == 0x4938 && tx4938_sramcptr->cr & 1) { unsigned int size = 0x800; unsigned long base = (tx4938_sramcptr->cr >> (39-11)) & ~(size - 1); txboard_add_phys_region(base, size); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -