Merge git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile
[cascardo/linux.git] / arch / tile / kernel / pci_gx.c
index 8352d85..a97a645 100644 (file)
@@ -91,7 +91,7 @@ static int rc_delay[TILEGX_NUM_TRIO][TILEGX_TRIO_PCIES];
        TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_CONFIG_ENDPOINT_G1
 
 /* Array of the PCIe ports configuration info obtained from the BIB. */
-struct pcie_port_property pcie_ports[TILEGX_NUM_TRIO][TILEGX_TRIO_PCIES];
+struct pcie_trio_ports_property pcie_ports[TILEGX_NUM_TRIO];
 
 /* Number of configured TRIO instances. */
 int num_trio_shims;
@@ -195,10 +195,7 @@ static int tile_pcie_open(int trio_index)
 #endif
 
        /* Get the properties of the PCIe ports on this TRIO instance. */
-       ret = hv_dev_pread(context->fd, 0,
-               (HV_VirtAddr)&pcie_ports[trio_index][0],
-               sizeof(struct pcie_port_property) * TILEGX_TRIO_PCIES,
-               GXIO_TRIO_OP_GET_PORT_PROPERTY);
+       ret = gxio_trio_get_port_property(context, &pcie_ports[trio_index]);
        if (ret < 0) {
                pr_err("PCI: PCIE_GET_PORT_PROPERTY failure, error %d,"
                       " on TRIO %d\n", ret, trio_index);
@@ -221,8 +218,8 @@ static int tile_pcie_open(int trio_index)
                unsigned int reg_offset;
 
                /* Ignore ports that are not specified in the BIB. */
-               if (!pcie_ports[trio_index][mac].allow_rc &&
-                   !pcie_ports[trio_index][mac].allow_ep)
+               if (!pcie_ports[trio_index].ports[mac].allow_rc &&
+                   !pcie_ports[trio_index].ports[mac].allow_ep)
                        continue;
 
                reg_offset =
@@ -243,7 +240,7 @@ static int tile_pcie_open(int trio_index)
                         */
                        if (port_config.strap_state == AUTO_CONFIG_EP ||
                            port_config.strap_state == AUTO_CONFIG_EP_G1)
-                               pcie_ports[trio_index][mac].allow_ep = 1;
+                               pcie_ports[trio_index].ports[mac].allow_ep = 1;
                }
        }
 
@@ -438,9 +435,27 @@ int __init tile_pci_init(void)
                return 0;
 
        /*
-        * Now determine which PCIe ports are configured to operate in RC mode.
-        * We look at the Board Information Block first and then see if there
-        * are any overriding configuration by the HW strapping pin.
+        * Now determine which PCIe ports are configured to operate in RC
+        * mode. There is a differece in the port configuration capability
+        * between the Gx36 and Gx72 devices.
+        *
+        * The Gx36 has configuration capability for each of the 3 PCIe
+        * interfaces (disable, auto endpoint, auto RC, etc.).
+        * On the Gx72, you can only select one of the 3 PCIe interfaces per
+        * TRIO to train automatically. Further, the allowable training modes
+        * are reduced to four options (auto endpoint, auto RC, stream x1,
+        * stream x4).
+        *
+        * For Gx36 ports, it must be allowed to be in RC mode by the
+        * Board Information Block, and the hardware strapping pins must be
+        * set to RC mode.
+        *
+        * For Gx72 ports, the port will operate in RC mode if either of the
+        * following is true:
+        * 1. It is allowed to be in RC mode by the Board Information Block,
+        *    and the BIB doesn't allow the EP mode.
+        * 2. It is allowed to be in either the RC or the EP mode by the BIB,
+        *    and the hardware strapping pin is set to RC mode.
         */
        for (i = 0; i < TILEGX_NUM_TRIO; i++) {
                gxio_trio_context_t *context = &trio_contexts[i];
@@ -449,8 +464,18 @@ int __init tile_pci_init(void)
                        continue;
 
                for (j = 0; j < TILEGX_TRIO_PCIES; j++) {
-                       if (pcie_ports[i][j].allow_rc &&
-                           strapped_for_rc(context, j)) {
+                       int is_rc = 0;
+
+                       if (pcie_ports[i].is_gx72 &&
+                           pcie_ports[i].ports[j].allow_rc) {
+                               if (!pcie_ports[i].ports[j].allow_ep ||
+                                   strapped_for_rc(context, j))
+                                       is_rc = 1;
+                       } else if (pcie_ports[i].ports[j].allow_rc &&
+                                  strapped_for_rc(context, j)) {
+                               is_rc = 1;
+                       }
+                       if (is_rc) {
                                pcie_rc[i][j] = 1;
                                num_rc_controllers++;
                        }
@@ -577,13 +602,8 @@ static void fixup_read_and_payload_sizes(struct pci_controller *controller)
                            rc_dev_cap.word);
 
        /* Configure PCI Express MPS setting. */
-       list_for_each_entry(child, &root_bus->children, node) {
-               struct pci_dev *self = child->self;
-               if (!self)
-                       continue;
-
-               pcie_bus_configure_settings(child, self->pcie_mpss);
-       }
+       list_for_each_entry(child, &root_bus->children, node)
+               pcie_bus_configure_settings(child);
 
        /*
         * Set the mac_config register in trio based on the MPS/MRS of the link.
@@ -736,7 +756,7 @@ int __init pcibios_init(void)
                        __gxio_mmio_read(trio_context->mmio_base_mac +
                                         reg_offset);
                if (!port_status.dl_up) {
-                       if (pcie_ports[trio_index][mac].removable) {
+                       if (pcie_ports[trio_index].ports[mac].removable) {
                                pr_info("PCI: link is down, MAC %d on TRIO %d\n",
                                        mac, trio_index);
                                pr_info("This is expected if no PCIe card"
@@ -835,9 +855,15 @@ int __init pcibios_init(void)
 
 #endif
 
+               /*
+                * To save VMALLOC space, we take advantage of the fact that
+                * bit 29 in the PIO CFG address format is reserved 0. With
+                * TRIO_TILE_PIO_REGION_SETUP_CFG_ADDR__MAC_SHIFT being 30,
+                * this cuts VMALLOC space usage from 1GB to 512MB per mac.
+                */
                trio_context->mmio_base_pio_cfg[mac] =
-                       iorpc_ioremap(trio_context->fd, offset,
-                       (1 << TRIO_TILE_PIO_REGION_SETUP_CFG_ADDR__MAC_SHIFT));
+                       iorpc_ioremap(trio_context->fd, offset, (1UL <<
+                       (TRIO_TILE_PIO_REGION_SETUP_CFG_ADDR__MAC_SHIFT - 1)));
                if (trio_context->mmio_base_pio_cfg[mac] == NULL) {
                        pr_err("PCI: PIO map failure for mac %d on TRIO %d\n",
                                mac, trio_index);
@@ -1029,7 +1055,7 @@ void pcibios_fixup_bus(struct pci_bus *bus)
 }
 
 /* Process any "pci=" kernel boot arguments. */
-char *pcibios_setup(char *str)
+char *__init pcibios_setup(char *str)
 {
        if (!strcmp(str, "off")) {
                pci_probe = 0;
@@ -1050,13 +1076,24 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
        return pci_enable_resources(dev, mask);
 }
 
-/* Called for each device after PCI setup is done. */
+/*
+ * Called for each device after PCI setup is done.
+ * We initialize the PCI device capabilities conservatively, assuming that
+ * all devices can only address the 32-bit DMA space. The exception here is
+ * that the device dma_offset is set to the value that matches the 64-bit
+ * capable devices. This is OK because dma_offset is not used by legacy
+ * dma_ops, nor by the hybrid dma_ops's streaming DMAs, which are 64-bit ops.
+ * This implementation matches the kernel design of setting PCI devices'
+ * coherent_dma_mask to 0xffffffffull by default, allowing the device drivers
+ * to skip calling pci_set_consistent_dma_mask(DMA_BIT_MASK(32)).
+ */
 static void pcibios_fixup_final(struct pci_dev *pdev)
 {
-       set_dma_ops(&pdev->dev, gx_pci_dma_map_ops);
+       set_dma_ops(&pdev->dev, gx_legacy_pci_dma_map_ops);
        set_dma_offset(&pdev->dev, TILE_PCI_MEM_MAP_BASE_OFFSET);
        pdev->dev.archdata.max_direct_dma_addr =
                TILE_PCI_MAX_DIRECT_DMA_ADDRESS;
+       pdev->dev.coherent_dma_mask = TILE_PCI_MAX_DIRECT_DMA_ADDRESS;
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_final);