static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc) { u32 val; if (WARN_ON(extpci_core)) return; extpci_core = pc; ssb_dprintk(KERN_INFO PFX "PCIcore in host mode found\n"); val = SSB_PCICORE_CTL_RST_OE; val |= SSB_PCICORE_CTL_CLK_OE; pcicore_write32(pc, SSB_PCICORE_CTL, val); val |= SSB_PCICORE_CTL_CLK; pcicore_write32(pc, SSB_PCICORE_CTL, val); udelay(150); val |= SSB_PCICORE_CTL_RST; pcicore_write32(pc, SSB_PCICORE_CTL, val); val = SSB_PCICORE_ARBCTL_INTERN; pcicore_write32(pc, SSB_PCICORE_ARBCTL, val); udelay(1); if (pc->dev->bus->has_cardbus_slot) { ssb_dprintk(KERN_INFO PFX "CardBus slot detected\n"); pc->cardbusmode = 1; ssb_gpio_out(pc->dev->bus, 1, 1); ssb_gpio_outen(pc->dev->bus, 1, 1); pcicore_write16(pc, SSB_PCICORE_SPROM(0), pcicore_read16(pc, SSB_PCICORE_SPROM(0)) | 0x0400); } pcicore_write32(pc, SSB_PCICORE_SBTOPCI0, SSB_PCICORE_SBTOPCI_IO); pcicore_write32(pc, SSB_PCICORE_SBTOPCI1, SSB_PCICORE_SBTOPCI_CFG0); pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, SSB_PCICORE_SBTOPCI_MEM | SSB_PCI_DMA); val = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; ssb_extpci_write_config(pc, 0, 0, 0, PCI_COMMAND, &val, 2); val = 0; ssb_extpci_write_config(pc, 0, 0, 0, PCI_STATUS, &val, 2); pcicore_write32(pc, SSB_PCICORE_IMASK, SSB_PCICORE_IMASK_INTA); ssb_pcicore_controller.io_map_base = (unsigned long)ioremap_nocache(SSB_PCI_MEM, 0x04000000); set_io_port_base(ssb_pcicore_controller.io_map_base); mdelay(10); register_pci_controller(&ssb_pcicore_controller); }
static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc) { u32 val; if (WARN_ON(extpci_core)) return; extpci_core = pc; ssb_dprintk(KERN_INFO PFX "PCIcore in host mode found\n"); /* Reset devices on the external PCI bus */ val = SSB_PCICORE_CTL_RST_OE; val |= SSB_PCICORE_CTL_CLK_OE; pcicore_write32(pc, SSB_PCICORE_CTL, val); val |= SSB_PCICORE_CTL_CLK; /* Clock on */ pcicore_write32(pc, SSB_PCICORE_CTL, val); udelay(150); /* Assertion time demanded by the PCI standard */ val |= SSB_PCICORE_CTL_RST; /* Deassert RST# */ pcicore_write32(pc, SSB_PCICORE_CTL, val); val = SSB_PCICORE_ARBCTL_INTERN; pcicore_write32(pc, SSB_PCICORE_ARBCTL, val); udelay(1); /* Assertion time demanded by the PCI standard */ if (pc->dev->bus->has_cardbus_slot) { ssb_dprintk(KERN_INFO PFX "CardBus slot detected\n"); pc->cardbusmode = 1; /* GPIO 1 resets the bridge */ ssb_gpio_out(pc->dev->bus, 1, 1); ssb_gpio_outen(pc->dev->bus, 1, 1); pcicore_write16(pc, SSB_PCICORE_SPROM(0), pcicore_read16(pc, SSB_PCICORE_SPROM(0)) | 0x0400); } /* 64MB I/O window */ pcicore_write32(pc, SSB_PCICORE_SBTOPCI0, SSB_PCICORE_SBTOPCI_IO); /* 64MB config space */ pcicore_write32(pc, SSB_PCICORE_SBTOPCI1, SSB_PCICORE_SBTOPCI_CFG0); /* 1GB memory window */ pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, SSB_PCICORE_SBTOPCI_MEM | SSB_PCI_DMA); /* Enable PCI bridge BAR0 prefetch and burst */ val = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; ssb_extpci_write_config(pc, 0, 0, 0, PCI_COMMAND, &val, 2); /* Clear error conditions */ val = 0; ssb_extpci_write_config(pc, 0, 0, 0, PCI_STATUS, &val, 2); /* Enable PCI interrupts */ pcicore_write32(pc, SSB_PCICORE_IMASK, SSB_PCICORE_IMASK_INTA); /* Ok, ready to run, register it to the system. * The following needs change, if we want to port hostmode * to non-MIPS platform. */ ssb_pcicore_controller.io_map_base = (unsigned long)ioremap_nocache(SSB_PCI_MEM, 0x04000000); set_io_port_base(ssb_pcicore_controller.io_map_base); /* Give some time to the PCI controller to configure itself with the new * values. Not waiting at this point causes crashes of the machine. */ mdelay(10); register_pci_controller(&ssb_pcicore_controller); }