|
@@ -153,3 +153,72 @@ titan_read_config(struct pci_bus *bus, unsigned int devfn, int where,
|
|
*value = __kernel_ldwu(*(vusp)addr);
|
|
*value = __kernel_ldwu(*(vusp)addr);
|
|
break;
|
|
break;
|
|
case 4:
|
|
case 4:
|
|
|
|
+ *value = *(vuip)addr;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return PCIBIOS_SUCCESSFUL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int
|
|
|
|
+titan_write_config(struct pci_bus *bus, unsigned int devfn, int where,
|
|
|
|
+ int size, u32 value)
|
|
|
|
+{
|
|
|
|
+ unsigned long addr;
|
|
|
|
+ unsigned char type1;
|
|
|
|
+
|
|
|
|
+ if (mk_conf_addr(bus, devfn, where, &addr, &type1))
|
|
|
|
+ return PCIBIOS_DEVICE_NOT_FOUND;
|
|
|
|
+
|
|
|
|
+ switch (size) {
|
|
|
|
+ case 1:
|
|
|
|
+ __kernel_stb(value, *(vucp)addr);
|
|
|
|
+ mb();
|
|
|
|
+ __kernel_ldbu(*(vucp)addr);
|
|
|
|
+ break;
|
|
|
|
+ case 2:
|
|
|
|
+ __kernel_stw(value, *(vusp)addr);
|
|
|
|
+ mb();
|
|
|
|
+ __kernel_ldwu(*(vusp)addr);
|
|
|
|
+ break;
|
|
|
|
+ case 4:
|
|
|
|
+ *(vuip)addr = value;
|
|
|
|
+ mb();
|
|
|
|
+ *(vuip)addr;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return PCIBIOS_SUCCESSFUL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+struct pci_ops titan_pci_ops =
|
|
|
|
+{
|
|
|
|
+ .read = titan_read_config,
|
|
|
|
+ .write = titan_write_config,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+void
|
|
|
|
+titan_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
|
|
|
|
+{
|
|
|
|
+ titan_pachip *pachip =
|
|
|
|
+ (hose->index & 1) ? TITAN_pachip1 : TITAN_pachip0;
|
|
|
|
+ titan_pachip_port *port;
|
|
|
|
+ volatile unsigned long *csr;
|
|
|
|
+ unsigned long value;
|
|
|
|
+
|
|
|
|
+ /* Get the right hose. */
|
|
|
|
+ port = &pachip->g_port;
|
|
|
|
+ if (hose->index & 2)
|
|
|
|
+ port = &pachip->a_port;
|
|
|
|
+
|
|
|
|
+ /* We can invalidate up to 8 tlb entries in a go. The flush
|
|
|
|
+ matches against <31:16> in the pci address.
|
|
|
|
+ Note that gtlbi* and atlbi* are in the same place in the g_port
|
|
|
|
+ and a_port, respectively, so the g_port offset can be used
|
|
|
|
+ even if hose is an a_port */
|
|
|
|
+ csr = &port->port_specific.g.gtlbia.csr;
|
|
|
|
+ if (((start ^ end) & 0xffff0000) == 0)
|
|
|
|
+ csr = &port->port_specific.g.gtlbiv.csr;
|
|
|
|
+
|
|
|
|
+ /* For TBIA, it doesn't matter what value we write. For TBI,
|