|
@@ -200,3 +200,142 @@ static void __init
|
|
|
io7_init_hose(struct io7 *io7, int port)
|
|
|
{
|
|
|
static int hose_index = 0;
|
|
|
+
|
|
|
+ struct pci_controller *hose = alloc_pci_controller();
|
|
|
+ struct io7_port *io7_port = &io7->ports[port];
|
|
|
+ io7_ioport_csrs *csrs = IO7_CSRS_KERN(io7->pe, port);
|
|
|
+ int i;
|
|
|
+
|
|
|
+ hose->index = hose_index++; /* arbitrary */
|
|
|
+
|
|
|
+ /*
|
|
|
+ * We don't have an isa or legacy hose, but glibc expects to be
|
|
|
+ * able to use the bus == 0 / dev == 0 form of the iobase syscall
|
|
|
+ * to determine information about the i/o system. Since XFree86
|
|
|
+ * relies on glibc's determination to tell whether or not to use
|
|
|
+ * sparse access, we need to point the pci_isa_hose at a real hose
|
|
|
+ * so at least that determination is correct.
|
|
|
+ */
|
|
|
+ if (hose->index == 0)
|
|
|
+ pci_isa_hose = hose;
|
|
|
+
|
|
|
+ io7_port->csrs = csrs;
|
|
|
+ io7_port->hose = hose;
|
|
|
+ hose->sysdata = io7_port;
|
|
|
+
|
|
|
+ hose->io_space = alloc_resource();
|
|
|
+ hose->mem_space = alloc_resource();
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Base addresses for userland consumption. Since these are going
|
|
|
+ * to be mapped, they are pure physical addresses.
|
|
|
+ */
|
|
|
+ hose->sparse_mem_base = hose->sparse_io_base = 0;
|
|
|
+ hose->dense_mem_base = IO7_MEM_PHYS(io7->pe, port);
|
|
|
+ hose->dense_io_base = IO7_IO_PHYS(io7->pe, port);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Base addresses and resource ranges for kernel consumption.
|
|
|
+ */
|
|
|
+ hose->config_space_base = (unsigned long)IO7_CONF_KERN(io7->pe, port);
|
|
|
+
|
|
|
+ hose->io_space->start = (unsigned long)IO7_IO_KERN(io7->pe, port);
|
|
|
+ hose->io_space->end = hose->io_space->start + IO7_IO_SPACE - 1;
|
|
|
+ hose->io_space->name = mk_resource_name(io7->pe, port, "IO");
|
|
|
+ hose->io_space->flags = IORESOURCE_IO;
|
|
|
+
|
|
|
+ hose->mem_space->start = (unsigned long)IO7_MEM_KERN(io7->pe, port);
|
|
|
+ hose->mem_space->end = hose->mem_space->start + IO7_MEM_SPACE - 1;
|
|
|
+ hose->mem_space->name = mk_resource_name(io7->pe, port, "MEM");
|
|
|
+ hose->mem_space->flags = IORESOURCE_MEM;
|
|
|
+
|
|
|
+ if (request_resource(&ioport_resource, hose->io_space) < 0)
|
|
|
+ printk(KERN_ERR "Failed to request IO on hose %d\n",
|
|
|
+ hose->index);
|
|
|
+ if (request_resource(&iomem_resource, hose->mem_space) < 0)
|
|
|
+ printk(KERN_ERR "Failed to request MEM on hose %d\n",
|
|
|
+ hose->index);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Save the existing DMA window settings for later restoration.
|
|
|
+ */
|
|
|
+ for (i = 0; i < 4; i++) {
|
|
|
+ io7_port->saved_wbase[i] = csrs->POx_WBASE[i].csr;
|
|
|
+ io7_port->saved_wmask[i] = csrs->POx_WMASK[i].csr;
|
|
|
+ io7_port->saved_tbase[i] = csrs->POx_TBASE[i].csr;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Set up the PCI to main memory translation windows.
|
|
|
+ *
|
|
|
+ * Window 0 is scatter-gather 8MB at 8MB
|
|
|
+ * Window 1 is direct access 1GB at 2GB
|
|
|
+ * Window 2 is scatter-gather (up-to) 1GB at 3GB
|
|
|
+ * Window 3 is disabled
|
|
|
+ */
|
|
|
+
|
|
|
+ /*
|
|
|
+ * TBIA before modifying windows.
|
|
|
+ */
|
|
|
+ marvel_pci_tbi(hose, 0, -1);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Set up window 0 for scatter-gather 8MB at 8MB.
|
|
|
+ */
|
|
|
+ hose->sg_isa = iommu_arena_new_node(marvel_cpuid_to_nid(io7->pe),
|
|
|
+ hose, 0x00800000, 0x00800000, 0);
|
|
|
+ hose->sg_isa->align_entry = 8; /* cache line boundary */
|
|
|
+ csrs->POx_WBASE[0].csr =
|
|
|
+ hose->sg_isa->dma_base | wbase_m_ena | wbase_m_sg;
|
|
|
+ csrs->POx_WMASK[0].csr = (hose->sg_isa->size - 1) & wbase_m_addr;
|
|
|
+ csrs->POx_TBASE[0].csr = virt_to_phys(hose->sg_isa->ptes);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Set up window 1 for direct-mapped 1GB at 2GB.
|
|
|
+ */
|
|
|
+ csrs->POx_WBASE[1].csr = __direct_map_base | wbase_m_ena;
|
|
|
+ csrs->POx_WMASK[1].csr = (__direct_map_size - 1) & wbase_m_addr;
|
|
|
+ csrs->POx_TBASE[1].csr = 0;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Set up window 2 for scatter-gather (up-to) 1GB at 3GB.
|
|
|
+ */
|
|
|
+ hose->sg_pci = iommu_arena_new_node(marvel_cpuid_to_nid(io7->pe),
|
|
|
+ hose, 0xc0000000, 0x40000000, 0);
|
|
|
+ hose->sg_pci->align_entry = 8; /* cache line boundary */
|
|
|
+ csrs->POx_WBASE[2].csr =
|
|
|
+ hose->sg_pci->dma_base | wbase_m_ena | wbase_m_sg;
|
|
|
+ csrs->POx_WMASK[2].csr = (hose->sg_pci->size - 1) & wbase_m_addr;
|
|
|
+ csrs->POx_TBASE[2].csr = virt_to_phys(hose->sg_pci->ptes);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Disable window 3.
|
|
|
+ */
|
|
|
+ csrs->POx_WBASE[3].csr = 0;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Make sure that the AGP Monster Window is disabled.
|
|
|
+ */
|
|
|
+ csrs->POx_CTRL.csr &= ~(1UL << 61);
|
|
|
+
|
|
|
+#if 1
|
|
|
+ printk("FIXME: disabling master aborts\n");
|
|
|
+ csrs->POx_MSK_HEI.csr &= ~(3UL << 14);
|
|
|
+#endif
|
|
|
+ /*
|
|
|
+ * TBIA after modifying windows.
|
|
|
+ */
|
|
|
+ marvel_pci_tbi(hose, 0, -1);
|
|
|
+}
|
|
|
+
|
|
|
+static void __init
|
|
|
+marvel_init_io7(struct io7 *io7)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+
|
|
|
+ printk("Initializing IO7 at PID %d\n", io7->pe);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get the Port 7 CSR pointer.
|
|
|
+ */
|
|
|
+ io7->csrs = IO7_PORT7_CSRS_KERN(io7->pe);
|