aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2006-05-18 04:06:37 -0400
committerPaul Mackerras <paulus@samba.org>2006-05-19 01:02:23 -0400
commit4c76e0bcdeac27b45d55955f073a97ff8452a42f (patch)
tree9a274ffdfb1159012c10b7367e8d09207fbd28d0 /arch
parentd4ad66faecc4dd9f3db14e0b013741a6f867b089 (diff)
[PATCH] powerpc: pseries: Use generic dma-window parsing function
Change the pseries iommu init code to use the new of_parse_dma_window() to parse the ibm,dma-window and ibm,my-dma-window properties of pci and virtual device nodes. Also, clean up vio_build_iommu_table() a little. Tested on pseries, with both vio and pci devices. Signed-off-by: Jeremy Kerr <jk@ozlabs.org> Acked-by: Olof Johansson <olof@lixom.net> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/kernel/vio.c36
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c29
2 files changed, 24 insertions, 41 deletions
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index ac5c7bf907f5..2cda65b8171b 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -77,36 +77,28 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
77 } else 77 } else
78#endif 78#endif
79 { 79 {
80 unsigned int *dma_window; 80 unsigned char *dma_window;
81 struct iommu_table *newTceTable; 81 struct iommu_table *tbl;
82 unsigned long offset; 82 unsigned long offset, size;
83 int dma_window_property_size; 83
84 84 dma_window = get_property(dev->dev.platform_data,
85 dma_window = (unsigned int *)get_property( 85 "ibm,my-dma-window", NULL);
86 dev->dev.platform_data, "ibm,my-dma-window",
87 &dma_window_property_size);
88 if (!dma_window) 86 if (!dma_window)
89 return NULL; 87 return NULL;
90 88
91 newTceTable = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); 89 tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
92 90
93 /* 91 of_parse_dma_window(dev->dev.platform_data, dma_window,
94 * There should be some code to extract the phys-encoded 92 &tbl->it_index, &offset, &size);
95 * offset using prom_n_addr_cells(). However, according to
96 * a comment on earlier versions, it's always zero, so we
97 * don't bother
98 */
99 offset = dma_window[1] >> PAGE_SHIFT;
100 93
101 /* TCE table size - measured in tce entries */ 94 /* TCE table size - measured in tce entries */
102 newTceTable->it_size = dma_window[4] >> PAGE_SHIFT; 95 tbl->it_size = size >> PAGE_SHIFT;
103 /* offset for VIO should always be 0 */ 96 /* offset for VIO should always be 0 */
104 newTceTable->it_offset = offset; 97 tbl->it_offset = offset >> PAGE_SHIFT;
105 newTceTable->it_busno = 0; 98 tbl->it_busno = 0;
106 newTceTable->it_index = (unsigned long)dma_window[0]; 99 tbl->it_type = TCE_VB;
107 newTceTable->it_type = TCE_VB;
108 100
109 return iommu_init_table(newTceTable); 101 return iommu_init_table(tbl);
110 } 102 }
111} 103}
112 104
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index ed102f390689..44a507e6fb34 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -281,30 +281,22 @@ static void iommu_table_setparms(struct pci_controller *phb,
281 * iommu_table_setparms_lpar 281 * iommu_table_setparms_lpar
282 * 282 *
283 * Function: On pSeries LPAR systems, return TCE table info, given a pci bus. 283 * Function: On pSeries LPAR systems, return TCE table info, given a pci bus.
284 *
285 * ToDo: properly interpret the ibm,dma-window property. The definition is:
286 * logical-bus-number (1 word)
287 * phys-address (#address-cells words)
288 * size (#cell-size words)
289 *
290 * Currently we hard code these sizes (more or less).
291 */ 284 */
292static void iommu_table_setparms_lpar(struct pci_controller *phb, 285static void iommu_table_setparms_lpar(struct pci_controller *phb,
293 struct device_node *dn, 286 struct device_node *dn,
294 struct iommu_table *tbl, 287 struct iommu_table *tbl,
295 unsigned int *dma_window) 288 unsigned char *dma_window)
296{ 289{
290 unsigned long offset, size;
291
297 tbl->it_busno = PCI_DN(dn)->bussubno; 292 tbl->it_busno = PCI_DN(dn)->bussubno;
293 of_parse_dma_window(dn, dma_window, &tbl->it_index, &offset, &size);
298 294
299 /* TODO: Parse field size properties properly. */
300 tbl->it_size = (((unsigned long)dma_window[4] << 32) |
301 (unsigned long)dma_window[5]) >> PAGE_SHIFT;
302 tbl->it_offset = (((unsigned long)dma_window[2] << 32) |
303 (unsigned long)dma_window[3]) >> PAGE_SHIFT;
304 tbl->it_base = 0; 295 tbl->it_base = 0;
305 tbl->it_index = dma_window[0];
306 tbl->it_blocksize = 16; 296 tbl->it_blocksize = 16;
307 tbl->it_type = TCE_PCI; 297 tbl->it_type = TCE_PCI;
298 tbl->it_offset = offset >> PAGE_SHIFT;
299 tbl->it_size = size >> PAGE_SHIFT;
308} 300}
309 301
310static void iommu_bus_setup_pSeries(struct pci_bus *bus) 302static void iommu_bus_setup_pSeries(struct pci_bus *bus)
@@ -396,7 +388,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
396 struct iommu_table *tbl; 388 struct iommu_table *tbl;
397 struct device_node *dn, *pdn; 389 struct device_node *dn, *pdn;
398 struct pci_dn *ppci; 390 struct pci_dn *ppci;
399 unsigned int *dma_window = NULL; 391 unsigned char *dma_window = NULL;
400 392
401 DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self); 393 DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self);
402 394
@@ -404,7 +396,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
404 396
405 /* Find nearest ibm,dma-window, walking up the device tree */ 397 /* Find nearest ibm,dma-window, walking up the device tree */
406 for (pdn = dn; pdn != NULL; pdn = pdn->parent) { 398 for (pdn = dn; pdn != NULL; pdn = pdn->parent) {
407 dma_window = (unsigned int *)get_property(pdn, "ibm,dma-window", NULL); 399 dma_window = get_property(pdn, "ibm,dma-window", NULL);
408 if (dma_window != NULL) 400 if (dma_window != NULL)
409 break; 401 break;
410 } 402 }
@@ -498,7 +490,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
498{ 490{
499 struct device_node *pdn, *dn; 491 struct device_node *pdn, *dn;
500 struct iommu_table *tbl; 492 struct iommu_table *tbl;
501 int *dma_window = NULL; 493 unsigned char *dma_window = NULL;
502 struct pci_dn *pci; 494 struct pci_dn *pci;
503 495
504 DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev)); 496 DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev));
@@ -513,8 +505,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
513 505
514 for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table; 506 for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table;
515 pdn = pdn->parent) { 507 pdn = pdn->parent) {
516 dma_window = (unsigned int *) 508 dma_window = get_property(pdn, "ibm,dma-window", NULL);
517 get_property(pdn, "ibm,dma-window", NULL);
518 if (dma_window) 509 if (dma_window)
519 break; 510 break;
520 } 511 }