]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/powerpc/platforms/cell/iommu.c
[POWERPC] Cell fixup DMA offset for new southbridge
[karo-tx-linux.git] / arch / powerpc / platforms / cell / iommu.c
index d2b20eba5b87270d21ca78ea2b892bbf361c8aff..e3ea5311476ed99925436b0ad4afd6e2db0d2848 100644 (file)
@@ -46,6 +46,8 @@
 
 #include "iommu.h"
 
+static dma_addr_t cell_dma_valid = SPIDER_DMA_VALID;
+
 static inline unsigned long 
 get_iopt_entry(unsigned long real_address, unsigned long ioid,
                         unsigned long prot)
@@ -255,9 +257,6 @@ static void enable_mapping(void __iomem *base, void __iomem *mmio_base)
        set_iost_origin(mmio_base);
 }
 
-static void iommu_dev_setup_null(struct pci_dev *d) { }
-static void iommu_bus_setup_null(struct pci_bus *b) { }
-
 struct cell_iommu {
        unsigned long base;
        unsigned long mmio_base;
@@ -306,12 +305,15 @@ static void cell_do_map_iommu(struct cell_iommu *iommu,
        }
 }
 
-static void iommu_devnode_setup(struct device_node *d)
+static void pci_dma_cell_bus_setup(struct pci_bus *b)
 {
        const unsigned int *ioid;
        unsigned long map_start, map_size, token;
        const unsigned long *dma_window;
        struct cell_iommu *iommu;
+       struct device_node *d;
+
+       d = pci_bus_to_OF_node(b);
 
        ioid = get_property(d, "ioid", NULL);
        if (!ioid)
@@ -330,12 +332,6 @@ static void iommu_devnode_setup(struct device_node *d)
        cell_do_map_iommu(iommu, *ioid, map_start, map_size);
 }
 
-static void iommu_bus_setup(struct pci_bus *b)
-{
-       struct device_node *d = (struct device_node *)b->sysdata;
-       iommu_devnode_setup(d);
-}
-
 
 static int cell_map_iommu_hardcoded(int num_nodes)
 {
@@ -345,8 +341,8 @@ static int cell_map_iommu_hardcoded(int num_nodes)
 
        /* node 0 */
        iommu = &cell_iommus[0];
-       iommu->mapped_base = ioremap(0x20000511000, 0x1000);
-       iommu->mapped_mmio_base = ioremap(0x20000510000, 0x1000);
+       iommu->mapped_base = ioremap(0x20000511000ul, 0x1000);
+       iommu->mapped_mmio_base = ioremap(0x20000510000ul, 0x1000);
 
        enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base);
 
@@ -358,8 +354,8 @@ static int cell_map_iommu_hardcoded(int num_nodes)
 
        /* node 1 */
        iommu = &cell_iommus[1];
-       iommu->mapped_base = ioremap(0x30000511000, 0x1000);
-       iommu->mapped_mmio_base = ioremap(0x30000510000, 0x1000);
+       iommu->mapped_base = ioremap(0x30000511000ul, 0x1000);
+       iommu->mapped_mmio_base = ioremap(0x30000510000ul, 0x1000);
 
        enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base);
 
@@ -429,7 +425,7 @@ static void *cell_alloc_coherent(struct device *hwdev, size_t size,
        ret = (void *)__get_free_pages(flag, get_order(size));
        if (ret != NULL) {
                memset(ret, 0, size);
-               *dma_handle = virt_to_abs(ret) | CELL_DMA_VALID;
+               *dma_handle = virt_to_abs(ret) | cell_dma_valid;
        }
        return ret;
 }
@@ -443,7 +439,7 @@ static void cell_free_coherent(struct device *hwdev, size_t size,
 static dma_addr_t cell_map_single(struct device *hwdev, void *ptr,
                size_t size, enum dma_data_direction direction)
 {
-       return virt_to_abs(ptr) | CELL_DMA_VALID;
+       return virt_to_abs(ptr) | cell_dma_valid;
 }
 
 static void cell_unmap_single(struct device *hwdev, dma_addr_t dma_addr,
@@ -458,7 +454,7 @@ static int cell_map_sg(struct device *hwdev, struct scatterlist *sg,
 
        for (i = 0; i < nents; i++, sg++) {
                sg->dma_address = (page_to_phys(sg->page) + sg->offset)
-                                       | CELL_DMA_VALID;
+                                       | cell_dma_valid;
                sg->dma_length = sg->length;
        }
 
@@ -489,6 +485,12 @@ void cell_init_iommu(void)
 {
        int setup_bus = 0;
 
+       /* If we have an Axon bridge, clear the DMA valid mask. This is fairly
+        * hackish but will work well enough until we have proper iommu code.
+        */
+       if (of_find_node_by_name(NULL, "axon"))
+               cell_dma_valid = 0;
+
        if (of_find_node_by_path("/mambo")) {
                pr_info("Not using iommu on systemsim\n");
        } else {
@@ -499,16 +501,13 @@ void cell_init_iommu(void)
 
                if (setup_bus) {
                        pr_debug("%s: IOMMU mapping activated\n", __FUNCTION__);
-                       ppc_md.iommu_dev_setup = iommu_dev_setup_null;
-                       ppc_md.iommu_bus_setup = iommu_bus_setup;
+                       ppc_md.pci_dma_bus_setup = pci_dma_cell_bus_setup;
                } else {
                        pr_debug("%s: IOMMU mapping activated, "
                                 "no device action necessary\n", __FUNCTION__);
                        /* Direct I/O, IOMMU off */
-                       ppc_md.iommu_dev_setup = iommu_dev_setup_null;
-                       ppc_md.iommu_bus_setup = iommu_bus_setup_null;
                }
        }
 
-       pci_dma_ops = cell_iommu_ops;
+       pci_dma_ops = &cell_iommu_ops;
 }