|
@@ -191,3 +191,113 @@ conf_write(unsigned long addr, unsigned int value)
|
|
|
*(vulp)LCA_IOC_STAT0 = stat0;
|
|
|
mb();
|
|
|
|
|
|
+ /* Reset machine check. */
|
|
|
+ wrmces(0x7);
|
|
|
+ }
|
|
|
+ local_irq_restore(flags);
|
|
|
+}
|
|
|
+
|
|
|
+static int
|
|
|
+lca_read_config(struct pci_bus *bus, unsigned int devfn, int where,
|
|
|
+ int size, u32 *value)
|
|
|
+{
|
|
|
+ unsigned long addr, pci_addr;
|
|
|
+ long mask;
|
|
|
+ int shift;
|
|
|
+
|
|
|
+ if (mk_conf_addr(bus, devfn, where, &pci_addr))
|
|
|
+ return PCIBIOS_DEVICE_NOT_FOUND;
|
|
|
+
|
|
|
+ shift = (where & 3) * 8;
|
|
|
+ mask = (size - 1) * 8;
|
|
|
+ addr = (pci_addr << 5) + mask + LCA_CONF;
|
|
|
+ *value = conf_read(addr) >> (shift);
|
|
|
+ return PCIBIOS_SUCCESSFUL;
|
|
|
+}
|
|
|
+
|
|
|
+static int
|
|
|
+lca_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size,
|
|
|
+ u32 value)
|
|
|
+{
|
|
|
+ unsigned long addr, pci_addr;
|
|
|
+ long mask;
|
|
|
+
|
|
|
+ if (mk_conf_addr(bus, devfn, where, &pci_addr))
|
|
|
+ return PCIBIOS_DEVICE_NOT_FOUND;
|
|
|
+
|
|
|
+ mask = (size - 1) * 8;
|
|
|
+ addr = (pci_addr << 5) + mask + LCA_CONF;
|
|
|
+ conf_write(addr, value << ((where & 3) * 8));
|
|
|
+ return PCIBIOS_SUCCESSFUL;
|
|
|
+}
|
|
|
+
|
|
|
+struct pci_ops lca_pci_ops =
|
|
|
+{
|
|
|
+ .read = lca_read_config,
|
|
|
+ .write = lca_write_config,
|
|
|
+};
|
|
|
+
|
|
|
+void
|
|
|
+lca_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
|
|
|
+{
|
|
|
+ wmb();
|
|
|
+ *(vulp)LCA_IOC_TBIA = 0;
|
|
|
+ mb();
|
|
|
+}
|
|
|
+
|
|
|
+void __init
|
|
|
+lca_init_arch(void)
|
|
|
+{
|
|
|
+ struct pci_controller *hose;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Create our single hose.
|
|
|
+ */
|
|
|
+
|
|
|
+ pci_isa_hose = hose = alloc_pci_controller();
|
|
|
+ hose->io_space = &ioport_resource;
|
|
|
+ hose->mem_space = &iomem_resource;
|
|
|
+ hose->index = 0;
|
|
|
+
|
|
|
+ hose->sparse_mem_base = LCA_SPARSE_MEM - IDENT_ADDR;
|
|
|
+ hose->dense_mem_base = LCA_DENSE_MEM - IDENT_ADDR;
|
|
|
+ hose->sparse_io_base = LCA_IO - IDENT_ADDR;
|
|
|
+ hose->dense_io_base = 0;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Set up the PCI to main memory translation windows.
|
|
|
+ *
|
|
|
+ * Mimic the SRM settings for the direct-map window.
|
|
|
+ * Window 0 is scatter-gather 8MB at 8MB (for isa).
|
|
|
+ * Window 1 is direct access 1GB at 1GB.
|
|
|
+ *
|
|
|
+ * Note that we do not try to save any of the DMA window CSRs
|
|
|
+ * before setting them, since we cannot read those CSRs on LCA.
|
|
|
+ */
|
|
|
+ hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
|
|
|
+ hose->sg_pci = NULL;
|
|
|
+ __direct_map_base = 0x40000000;
|
|
|
+ __direct_map_size = 0x40000000;
|
|
|
+
|
|
|
+ *(vulp)LCA_IOC_W_BASE0 = hose->sg_isa->dma_base | (3UL << 32);
|
|
|
+ *(vulp)LCA_IOC_W_MASK0 = (hose->sg_isa->size - 1) & 0xfff00000;
|
|
|
+ *(vulp)LCA_IOC_T_BASE0 = virt_to_phys(hose->sg_isa->ptes);
|
|
|
+
|
|
|
+ *(vulp)LCA_IOC_W_BASE1 = __direct_map_base | (2UL << 32);
|
|
|
+ *(vulp)LCA_IOC_W_MASK1 = (__direct_map_size - 1) & 0xfff00000;
|
|
|
+ *(vulp)LCA_IOC_T_BASE1 = 0;
|
|
|
+
|
|
|
+ *(vulp)LCA_IOC_TB_ENA = 0x80;
|
|
|
+
|
|
|
+ lca_pci_tbi(hose, 0, -1);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Disable PCI parity for now. The NCR53c810 chip has
|
|
|
+ * troubles meeting the PCI spec which results in
|
|
|
+ * data parity errors.
|
|
|
+ */
|
|
|
+ *(vulp)LCA_IOC_PAR_DIS = 1UL<<5;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Finally, set up for restoring the correct HAE if using SRM.
|
|
|
+ * Again, since we cannot read many of the CSRs on the LCA,
|