14e0ee78fSHiroshi Doyu /* 24e0ee78fSHiroshi Doyu * OF helpers for IOMMU 34e0ee78fSHiroshi Doyu * 44e0ee78fSHiroshi Doyu * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. 54e0ee78fSHiroshi Doyu * 64e0ee78fSHiroshi Doyu * This program is free software; you can redistribute it and/or modify it 74e0ee78fSHiroshi Doyu * under the terms and conditions of the GNU General Public License, 84e0ee78fSHiroshi Doyu * version 2, as published by the Free Software Foundation. 94e0ee78fSHiroshi Doyu * 104e0ee78fSHiroshi Doyu * This program is distributed in the hope it will be useful, but WITHOUT 114e0ee78fSHiroshi Doyu * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 124e0ee78fSHiroshi Doyu * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 134e0ee78fSHiroshi Doyu * more details. 144e0ee78fSHiroshi Doyu * 154e0ee78fSHiroshi Doyu * You should have received a copy of the GNU General Public License along with 164e0ee78fSHiroshi Doyu * this program; if not, write to the Free Software Foundation, Inc., 174e0ee78fSHiroshi Doyu * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 184e0ee78fSHiroshi Doyu */ 194e0ee78fSHiroshi Doyu 204e0ee78fSHiroshi Doyu #include <linux/export.h> 21*7eba1d51SWill Deacon #include <linux/iommu.h> 224e0ee78fSHiroshi Doyu #include <linux/limits.h> 234e0ee78fSHiroshi Doyu #include <linux/of.h> 24cbff5634SBrian Norris #include <linux/of_iommu.h> 254e0ee78fSHiroshi Doyu 261cd076bfSWill Deacon static const struct of_device_id __iommu_of_table_sentinel 271cd076bfSWill Deacon __used __section(__iommu_of_table_end); 281cd076bfSWill Deacon 294e0ee78fSHiroshi Doyu /** 304e0ee78fSHiroshi Doyu * of_get_dma_window - Parse *dma-window property and returns 0 if found. 314e0ee78fSHiroshi Doyu * 324e0ee78fSHiroshi Doyu * @dn: device node 334e0ee78fSHiroshi Doyu * @prefix: prefix for property name if any 344e0ee78fSHiroshi Doyu * @index: index to start to parse 354e0ee78fSHiroshi Doyu * @busno: Returns busno if supported. Otherwise pass NULL 364e0ee78fSHiroshi Doyu * @addr: Returns address that DMA starts 374e0ee78fSHiroshi Doyu * @size: Returns the range that DMA can handle 384e0ee78fSHiroshi Doyu * 394e0ee78fSHiroshi Doyu * This supports different formats flexibly. "prefix" can be 404e0ee78fSHiroshi Doyu * configured if any. "busno" and "index" are optionally 414e0ee78fSHiroshi Doyu * specified. Set 0(or NULL) if not used. 424e0ee78fSHiroshi Doyu */ 434e0ee78fSHiroshi Doyu int of_get_dma_window(struct device_node *dn, const char *prefix, int index, 444e0ee78fSHiroshi Doyu unsigned long *busno, dma_addr_t *addr, size_t *size) 454e0ee78fSHiroshi Doyu { 464e0ee78fSHiroshi Doyu const __be32 *dma_window, *end; 474e0ee78fSHiroshi Doyu int bytes, cur_index = 0; 484e0ee78fSHiroshi Doyu char propname[NAME_MAX], addrname[NAME_MAX], sizename[NAME_MAX]; 494e0ee78fSHiroshi Doyu 504e0ee78fSHiroshi Doyu if (!dn || !addr || !size) 514e0ee78fSHiroshi Doyu return -EINVAL; 524e0ee78fSHiroshi Doyu 534e0ee78fSHiroshi Doyu if (!prefix) 544e0ee78fSHiroshi Doyu prefix = ""; 554e0ee78fSHiroshi Doyu 564e0ee78fSHiroshi Doyu snprintf(propname, sizeof(propname), "%sdma-window", prefix); 574e0ee78fSHiroshi Doyu snprintf(addrname, sizeof(addrname), "%s#dma-address-cells", prefix); 584e0ee78fSHiroshi Doyu snprintf(sizename, sizeof(sizename), "%s#dma-size-cells", prefix); 594e0ee78fSHiroshi Doyu 604e0ee78fSHiroshi Doyu dma_window = of_get_property(dn, propname, &bytes); 614e0ee78fSHiroshi Doyu if (!dma_window) 624e0ee78fSHiroshi Doyu return -ENODEV; 634e0ee78fSHiroshi Doyu end = dma_window + bytes / sizeof(*dma_window); 644e0ee78fSHiroshi Doyu 654e0ee78fSHiroshi Doyu while (dma_window < end) { 664e0ee78fSHiroshi Doyu u32 cells; 674e0ee78fSHiroshi Doyu const void *prop; 684e0ee78fSHiroshi Doyu 694e0ee78fSHiroshi Doyu /* busno is one cell if supported */ 704e0ee78fSHiroshi Doyu if (busno) 714e0ee78fSHiroshi Doyu *busno = be32_to_cpup(dma_window++); 724e0ee78fSHiroshi Doyu 734e0ee78fSHiroshi Doyu prop = of_get_property(dn, addrname, NULL); 744e0ee78fSHiroshi Doyu if (!prop) 754e0ee78fSHiroshi Doyu prop = of_get_property(dn, "#address-cells", NULL); 764e0ee78fSHiroshi Doyu 774e0ee78fSHiroshi Doyu cells = prop ? be32_to_cpup(prop) : of_n_addr_cells(dn); 784e0ee78fSHiroshi Doyu if (!cells) 794e0ee78fSHiroshi Doyu return -EINVAL; 804e0ee78fSHiroshi Doyu *addr = of_read_number(dma_window, cells); 814e0ee78fSHiroshi Doyu dma_window += cells; 824e0ee78fSHiroshi Doyu 834e0ee78fSHiroshi Doyu prop = of_get_property(dn, sizename, NULL); 844e0ee78fSHiroshi Doyu cells = prop ? be32_to_cpup(prop) : of_n_size_cells(dn); 854e0ee78fSHiroshi Doyu if (!cells) 864e0ee78fSHiroshi Doyu return -EINVAL; 874e0ee78fSHiroshi Doyu *size = of_read_number(dma_window, cells); 884e0ee78fSHiroshi Doyu dma_window += cells; 894e0ee78fSHiroshi Doyu 904e0ee78fSHiroshi Doyu if (cur_index++ == index) 914e0ee78fSHiroshi Doyu break; 924e0ee78fSHiroshi Doyu } 934e0ee78fSHiroshi Doyu return 0; 944e0ee78fSHiroshi Doyu } 954e0ee78fSHiroshi Doyu EXPORT_SYMBOL_GPL(of_get_dma_window); 961cd076bfSWill Deacon 97*7eba1d51SWill Deacon struct iommu_ops *of_iommu_configure(struct device *dev) 98*7eba1d51SWill Deacon { 99*7eba1d51SWill Deacon struct of_phandle_args iommu_spec; 100*7eba1d51SWill Deacon struct device_node *np; 101*7eba1d51SWill Deacon struct iommu_ops *ops = NULL; 102*7eba1d51SWill Deacon int idx = 0; 103*7eba1d51SWill Deacon 104*7eba1d51SWill Deacon /* 105*7eba1d51SWill Deacon * We don't currently walk up the tree looking for a parent IOMMU. 106*7eba1d51SWill Deacon * See the `Notes:' section of 107*7eba1d51SWill Deacon * Documentation/devicetree/bindings/iommu/iommu.txt 108*7eba1d51SWill Deacon */ 109*7eba1d51SWill Deacon while (!of_parse_phandle_with_args(dev->of_node, "iommus", 110*7eba1d51SWill Deacon "#iommu-cells", idx, 111*7eba1d51SWill Deacon &iommu_spec)) { 112*7eba1d51SWill Deacon np = iommu_spec.np; 113*7eba1d51SWill Deacon ops = of_iommu_get_ops(np); 114*7eba1d51SWill Deacon 115*7eba1d51SWill Deacon if (!ops || !ops->of_xlate || ops->of_xlate(dev, &iommu_spec)) 116*7eba1d51SWill Deacon goto err_put_node; 117*7eba1d51SWill Deacon 118*7eba1d51SWill Deacon of_node_put(np); 119*7eba1d51SWill Deacon idx++; 120*7eba1d51SWill Deacon } 121*7eba1d51SWill Deacon 122*7eba1d51SWill Deacon return ops; 123*7eba1d51SWill Deacon 124*7eba1d51SWill Deacon err_put_node: 125*7eba1d51SWill Deacon of_node_put(np); 126*7eba1d51SWill Deacon return NULL; 127*7eba1d51SWill Deacon } 128*7eba1d51SWill Deacon 1291cd076bfSWill Deacon void __init of_iommu_init(void) 1301cd076bfSWill Deacon { 1311cd076bfSWill Deacon struct device_node *np; 1321cd076bfSWill Deacon const struct of_device_id *match, *matches = &__iommu_of_table; 1331cd076bfSWill Deacon 1341cd076bfSWill Deacon for_each_matching_node_and_match(np, matches, &match) { 1351cd076bfSWill Deacon const of_iommu_init_fn init_fn = match->data; 1361cd076bfSWill Deacon 1371cd076bfSWill Deacon if (init_fn(np)) 1381cd076bfSWill Deacon pr_err("Failed to initialise IOMMU %s\n", 1391cd076bfSWill Deacon of_node_full_name(np)); 1401cd076bfSWill Deacon } 1411cd076bfSWill Deacon } 142