Lines Matching +full:fixed +full:- +full:size
1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * (C) Copyright IBM Corporation 2006-2008
26 #include <asm/pci-bridge.h>
29 #include <asm/cell-regs.h>
34 /* Define CELL_IOMMU_REAL_UNMAP to actually unmap non-used pages
43 * once spider-net has been fixed to pass the correct direction
88 #define IOSTE_PS_Mask 0x0000000000000007ul /* page size */
89 #define IOSTE_PS_4K 0x0000000000000001ul /* - 4kB */
90 #define IOSTE_PS_64K 0x0000000000000003ul /* - 64kB */
91 #define IOSTE_PS_1M 0x0000000000000005ul /* - 1MB */
92 #define IOSTE_PS_16M 0x0000000000000007ul /* - 16MB */
97 #define IO_PAGENO_BITS(shift) (IO_SEGMENT_SHIFT - (shift))
106 unsigned long size; member
125 * - on bus setup, look for a matching window, or create one
126 * - on dev setup, assign iommu_table ptr
138 reg = iommu->xlate_regs + IOC_IOPT_CacheInvd; in invalidate_tce_cache()
143 val = (((n /*- 1*/) << 53) & IOC_IOPT_CacheInvd_NE_Mask) in invalidate_tce_cache()
151 n_ptes -= n; in invalidate_tce_cache()
166 * driver - check mapping directions later, but allow read & write by in tce_build_cell()
180 (window->ioid & CBE_IOPTE_IOID_Mask); in tce_build_cell()
183 CBE_IOPTE_SO_RW | (window->ioid & CBE_IOPTE_IOID_Mask); in tce_build_cell()
188 io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset); in tce_build_cell()
190 for (i = 0; i < npages; i++, uaddr += (1 << tbl->it_page_shift)) in tce_build_cell()
195 invalidate_tce_cache(window->iommu, io_pte, npages); in tce_build_cell()
215 /* spider bridge does PCI reads after freeing - insert a mapping in tce_free_cell()
218 __pa(window->iommu->pad_page) | in tce_free_cell()
219 (window->ioid & CBE_IOPTE_IOID_Mask); in tce_free_cell()
222 io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset); in tce_free_cell()
229 invalidate_tce_cache(window->iommu, io_pte, npages); in tce_free_cell()
237 stat = in_be64(iommu->xlate_regs + IOC_IO_ExcpStat); in ioc_interrupt()
253 out_be64(iommu->xlate_regs + IOC_IO_ExcpStat, stat); in ioc_interrupt()
284 nidp = of_get_property(np, "node-id", NULL); in cell_iommu_find_ioc()
286 tmp = of_get_property(np, "ioc-translation", NULL); in cell_iommu_find_ioc()
295 return -ENODEV; in cell_iommu_find_ioc()
308 __func__, iommu->nid, segments); in cell_iommu_setup_stab()
312 page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(stab_size)); in cell_iommu_setup_stab()
314 iommu->stab = page_address(page); in cell_iommu_setup_stab()
315 memset(iommu->stab, 0, stab_size); in cell_iommu_setup_stab()
319 unsigned long base, unsigned long size, unsigned long gap_base, in cell_iommu_alloc_ptab() argument
328 segments = size >> IO_SEGMENT_SHIFT; in cell_iommu_alloc_ptab()
336 iommu->nid, ptab_size, get_order(ptab_size)); in cell_iommu_alloc_ptab()
337 page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(ptab_size)); in cell_iommu_alloc_ptab()
347 __func__, iommu->nid, iommu->stab, ptab, in cell_iommu_alloc_ptab()
351 reg = IOSTE_V | ((n_pte_pages - 1) << 5); in cell_iommu_alloc_ptab()
370 iommu->stab[i] = reg | (__pa(ptab) + (n_pte_pages << 12) * in cell_iommu_alloc_ptab()
371 (i - start_seg)); in cell_iommu_alloc_ptab()
372 pr_debug("\t[%d] 0x%016lx\n", i, iommu->stab[i]); in cell_iommu_alloc_ptab()
384 if (cell_iommu_find_ioc(iommu->nid, &xlate_base)) in cell_iommu_enable_hardware()
386 __func__, iommu->nid); in cell_iommu_enable_hardware()
388 iommu->xlate_regs = ioremap(xlate_base, IOC_Reg_Size); in cell_iommu_enable_hardware()
389 iommu->cmd_regs = iommu->xlate_regs + IOC_IOCmd_Offset; in cell_iommu_enable_hardware()
395 reg = in_be64(iommu->xlate_regs + IOC_IO_ExcpStat); in cell_iommu_enable_hardware()
396 out_be64(iommu->xlate_regs + IOC_IO_ExcpStat, in cell_iommu_enable_hardware()
398 out_be64(iommu->xlate_regs + IOC_IO_ExcpMask, in cell_iommu_enable_hardware()
402 IIC_IRQ_IOEX_ATI | (iommu->nid << IIC_IRQ_NODE_SHIFT)); in cell_iommu_enable_hardware()
405 ret = request_irq(virq, ioc_interrupt, 0, iommu->name, iommu); in cell_iommu_enable_hardware()
409 reg = IOC_IOST_Origin_E | __pa(iommu->stab) | IOC_IOST_Origin_HW; in cell_iommu_enable_hardware()
410 out_be64(iommu->xlate_regs + IOC_IOST_Origin, reg); in cell_iommu_enable_hardware()
411 in_be64(iommu->xlate_regs + IOC_IOST_Origin); in cell_iommu_enable_hardware()
414 reg = in_be64(iommu->cmd_regs + IOC_IOCmd_Cfg) | IOC_IOCmd_Cfg_TE; in cell_iommu_enable_hardware()
415 out_be64(iommu->cmd_regs + IOC_IOCmd_Cfg, reg); in cell_iommu_enable_hardware()
419 unsigned long base, unsigned long size) in cell_iommu_setup_hardware() argument
421 cell_iommu_setup_stab(iommu, base, size, 0, 0); in cell_iommu_setup_hardware()
422 iommu->ptab = cell_iommu_alloc_ptab(iommu, base, size, 0, 0, in cell_iommu_setup_hardware()
448 unsigned long offset, unsigned long size, in cell_iommu_setup_window() argument
457 window = kzalloc_node(sizeof(*window), GFP_KERNEL, iommu->nid); in cell_iommu_setup_window()
460 window->offset = offset; in cell_iommu_setup_window()
461 window->size = size; in cell_iommu_setup_window()
462 window->ioid = ioid; in cell_iommu_setup_window()
463 window->iommu = iommu; in cell_iommu_setup_window()
465 window->table.it_blocksize = 16; in cell_iommu_setup_window()
466 window->table.it_base = (unsigned long)iommu->ptab; in cell_iommu_setup_window()
467 window->table.it_index = iommu->nid; in cell_iommu_setup_window()
468 window->table.it_page_shift = IOMMU_PAGE_SHIFT_4K; in cell_iommu_setup_window()
469 window->table.it_offset = in cell_iommu_setup_window()
470 (offset >> window->table.it_page_shift) + pte_offset; in cell_iommu_setup_window()
471 window->table.it_size = size >> window->table.it_page_shift; in cell_iommu_setup_window()
472 window->table.it_ops = &cell_iommu_ops; in cell_iommu_setup_window()
474 if (!iommu_init_table(&window->table, iommu->nid, 0, 0)) in cell_iommu_setup_window()
477 pr_debug("\tioid %d\n", window->ioid); in cell_iommu_setup_window()
478 pr_debug("\tblocksize %ld\n", window->table.it_blocksize); in cell_iommu_setup_window()
479 pr_debug("\tbase 0x%016lx\n", window->table.it_base); in cell_iommu_setup_window()
480 pr_debug("\toffset 0x%lx\n", window->table.it_offset); in cell_iommu_setup_window()
481 pr_debug("\tsize %ld\n", window->table.it_size); in cell_iommu_setup_window()
483 list_add(&window->list, &iommu->windows); in cell_iommu_setup_window()
495 page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0); in cell_iommu_setup_window()
497 iommu->pad_page = page_address(page); in cell_iommu_setup_window()
498 clear_page(iommu->pad_page); in cell_iommu_setup_window()
500 __set_bit(0, window->table.it_map); in cell_iommu_setup_window()
501 tce_build_cell(&window->table, window->table.it_offset, 1, in cell_iommu_setup_window()
502 (unsigned long)iommu->pad_page, DMA_TO_DEVICE, 0); in cell_iommu_setup_window()
531 * node's iommu. We -might- do something smarter later though it may in cell_get_iommu_table()
535 if (iommu == NULL || list_empty(&iommu->windows)) { in cell_get_iommu_table()
537 dev->of_node, dev_to_node(dev)); in cell_get_iommu_table()
540 window = list_entry(iommu->windows.next, struct iommu_window, list); in cell_get_iommu_table()
542 return &window->table; in cell_get_iommu_table()
553 dev->archdata.dma_offset = addr + dma_iommu_fixed_base; in cell_dma_dev_setup()
556 dev->archdata.dma_offset = cell_dma_nommu_offset; in cell_dma_dev_setup()
562 cell_dma_dev_setup(&dev->dev); in cell_pci_dma_dev_setup()
575 dev->dma_ops = &dma_iommu_ops; in cell_of_bus_notify()
586 unsigned long *size) in cell_iommu_get_window() argument
591 /* Use ibm,dma-window if available, else, hard code ! */ in cell_iommu_get_window()
592 dma_window = of_get_property(np, "ibm,dma-window", NULL); in cell_iommu_get_window()
595 *size = 0x80000000u; in cell_iommu_get_window()
596 return -ENODEV; in cell_iommu_get_window()
599 of_parse_dma_window(np, dma_window, &index, base, size); in cell_iommu_get_window()
621 * However, there might be issue with getting the size right so let's in cell_iommu_alloc()
623 * multiple window support since the cell iommu supports per-page ioids in cell_iommu_alloc()
635 iommu->stab = NULL; in cell_iommu_alloc()
636 iommu->nid = nid; in cell_iommu_alloc()
637 snprintf(iommu->name, sizeof(iommu->name), "iommu%d", i); in cell_iommu_alloc()
638 INIT_LIST_HEAD(&iommu->windows); in cell_iommu_alloc()
647 unsigned long base, size; in cell_iommu_init_one() local
654 cell_iommu_get_window(np, &base, &size); in cell_iommu_init_one()
657 base, base + size - 1); in cell_iommu_init_one()
660 cell_iommu_setup_hardware(iommu, base, size); in cell_iommu_init_one()
663 cell_iommu_setup_window(iommu, np, base, size, in cell_iommu_init_one()
698 unsigned long base = 0, size; in cell_iommu_init_disabled() local
714 * pick up the first pci-internal node we can find and check in cell_iommu_init_disabled()
718 if (np->parent == NULL || np->parent->parent != NULL) in cell_iommu_init_disabled()
720 if (cell_iommu_get_window(np, &base, &size) == 0) in cell_iommu_init_disabled()
724 for_each_node_by_name(np, "pci-internal") { in cell_iommu_init_disabled()
725 if (np->parent == NULL || np->parent->parent != NULL) in cell_iommu_init_disabled()
727 if (cell_iommu_get_window(np, &base, &size) == 0) in cell_iommu_init_disabled()
736 if (np && size < memblock_end_of_DRAM()) { in cell_iommu_init_disabled()
737 printk(KERN_WARNING "iommu: force-enabled, dma window" in cell_iommu_init_disabled()
739 size >> 20, memblock_end_of_DRAM() >> 20); in cell_iommu_init_disabled()
740 return -ENODEV; in cell_iommu_init_disabled()
755 * Fixed IOMMU mapping support
757 * This code adds support for setting up a fixed IOMMU mapping on certain
758 * cell machines. For 64-bit devices this avoids the performance overhead of
759 * mapping and unmapping pages at runtime. 32-bit devices are unable to use
760 * the fixed mapping.
762 * The fixed mapping is established at boot, and maps all of physical memory
764 * we setup the fixed mapping immediately above the normal IOMMU window.
767 * IOMMU window from 0-2GB and the fixed mapping window from 2GB to 6GB. In
768 * this case a 64-bit device wishing to DMA to 1GB would be told to DMA to
770 * in the "dma-ranges" property.
772 * On machines with 30GB or more of memory, we are unable to place the fixed
775 * table, this region does not need to be part of the fixed mapping as no
776 * device should ever be DMA'ing to it. We then setup the fixed mapping
782 u64 cpu_addr, size, best_size, dev_addr = OF_BAD_ADDR; in cell_iommu_get_fixed_address() local
788 np = of_node_get(dev->of_node); in cell_iommu_get_fixed_address()
799 ranges = of_get_property(np, "dma-ranges", &len); in cell_iommu_get_fixed_address()
807 dev_dbg(dev, "iommu: no dma-ranges found\n"); in cell_iommu_get_fixed_address()
816 /* dma-ranges format: in cell_iommu_get_fixed_address()
819 * size : nsize cells in cell_iommu_get_fixed_address()
821 for (i = 0, best = -1, best_size = 0; i < len; i += range_size) { in cell_iommu_get_fixed_address()
823 size = of_read_number(ranges + i + naddr + pna, nsize); in cell_iommu_get_fixed_address()
825 if (cpu_addr == 0 && size > best_size) { in cell_iommu_get_fixed_address()
827 best_size = size; in cell_iommu_get_fixed_address()
845 cell_iommu_get_fixed_address(&pdev->dev) != OF_BAD_ADDR; in cell_pci_iommu_bypass_supported()
854 offset = (addr >> 24) - (segment << IO_PAGENO_BITS(24)); in insert_16M_pte()
879 pr_info("IOMMU: Using weak ordering for fixed mapping\n"); in cell_iommu_setup_fixed_ptab()
881 pr_info("IOMMU: Using strong ordering for fixed mapping\n"); in cell_iommu_setup_fixed_ptab()
889 pr_debug("iommu: fixed/dynamic overlap, skipping\n"); in cell_iommu_setup_fixed_ptab()
905 /* The fixed mapping is only supported on axon machines */ in cell_iommu_fixed_mapping_init()
910 pr_debug("iommu: fixed mapping disabled, no axons found\n"); in cell_iommu_fixed_mapping_init()
911 return -1; in cell_iommu_fixed_mapping_init()
914 /* We must have dma-ranges properties for fixed mapping to work */ in cell_iommu_fixed_mapping_init()
915 np = of_find_node_with_property(NULL, "dma-ranges"); in cell_iommu_fixed_mapping_init()
919 pr_debug("iommu: no dma-ranges found, no fixed mapping\n"); in cell_iommu_fixed_mapping_init()
920 return -1; in cell_iommu_fixed_mapping_init()
923 /* The default setup is to have the fixed mapping sit after the in cell_iommu_fixed_mapping_init()
925 * on any axon, then add the size of RAM and that's our max value. in cell_iommu_fixed_mapping_init()
941 * RAM with the fixed mapping, and also fit the dynamic in cell_iommu_fixed_mapping_init()
944 * need a fixed mapping for that area. in cell_iommu_fixed_mapping_init()
948 return -1; in cell_iommu_fixed_mapping_init()
957 return -1; in cell_iommu_fixed_mapping_init()
968 return -1; in cell_iommu_fixed_mapping_init()
987 printk(KERN_DEBUG "iommu: node %d, dynamic window 0x%lx-0x%lx " in cell_iommu_fixed_mapping_init()
988 "fixed window 0x%lx-0x%lx\n", iommu->nid, dbase, in cell_iommu_fixed_mapping_init()
992 iommu->ptab = cell_iommu_alloc_ptab(iommu, dbase, dsize, 0, 0, in cell_iommu_fixed_mapping_init()
1014 /* If we can find a pcie-endpoint in the device tree assume that in setup_iommu_fixed()
1015 * we're on a triblade or a CAB so by default the fixed mapping in setup_iommu_fixed()
1019 pciep = of_find_node_by_type(NULL, "pcie-endpoint"); in setup_iommu_fixed()
1052 if (np->parent == NULL || np->parent->parent != NULL) in cell_iommu_init()
1057 /* Create an iommu for each toplevel /pci-internal node for in cell_iommu_init()
1060 for_each_node_by_name(np, "pci-internal") { in cell_iommu_init()
1061 if (np->parent == NULL || np->parent->parent != NULL) in cell_iommu_init()