1 /* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License, version 2, as 4 * published by the Free Software Foundation. 5 * 6 * This program is distributed in the hope that it will be useful, 7 * but WITHOUT ANY WARRANTY; without even the implied warranty of 8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 * GNU General Public License for more details. 10 * 11 * You should have received a copy of the GNU General Public License 12 * along with this program; if not, write to the Free Software 13 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 14 * 15 * Copyright (C) 2013 Freescale Semiconductor, Inc. 16 * Author: Varun Sethi <varun.sethi@freescale.com> 17 * 18 */ 19 20 #define pr_fmt(fmt) "fsl-pamu-domain: %s: " fmt, __func__ 21 22 #include <linux/init.h> 23 #include <linux/iommu.h> 24 #include <linux/notifier.h> 25 #include <linux/slab.h> 26 #include <linux/module.h> 27 #include <linux/types.h> 28 #include <linux/mm.h> 29 #include <linux/interrupt.h> 30 #include <linux/device.h> 31 #include <linux/of_platform.h> 32 #include <linux/bootmem.h> 33 #include <linux/err.h> 34 #include <asm/io.h> 35 #include <asm/bitops.h> 36 37 #include <asm/pci-bridge.h> 38 #include <sysdev/fsl_pci.h> 39 40 #include "fsl_pamu_domain.h" 41 #include "pci.h" 42 43 /* 44 * Global spinlock that needs to be held while 45 * configuring PAMU. 46 */ 47 static DEFINE_SPINLOCK(iommu_lock); 48 49 static struct kmem_cache *fsl_pamu_domain_cache; 50 static struct kmem_cache *iommu_devinfo_cache; 51 static DEFINE_SPINLOCK(device_domain_lock); 52 53 static int __init iommu_init_mempool(void) 54 { 55 56 fsl_pamu_domain_cache = kmem_cache_create("fsl_pamu_domain", 57 sizeof(struct fsl_dma_domain), 58 0, 59 SLAB_HWCACHE_ALIGN, 60 61 NULL); 62 if (!fsl_pamu_domain_cache) { 63 pr_debug("Couldn't create fsl iommu_domain cache\n"); 64 return -ENOMEM; 65 } 66 67 iommu_devinfo_cache = kmem_cache_create("iommu_devinfo", 68 sizeof(struct device_domain_info), 69 0, 70 SLAB_HWCACHE_ALIGN, 71 NULL); 72 if (!iommu_devinfo_cache) { 73 pr_debug("Couldn't create devinfo cache\n"); 74 kmem_cache_destroy(fsl_pamu_domain_cache); 75 return -ENOMEM; 76 } 77 78 return 0; 79 } 80 81 static phys_addr_t get_phys_addr(struct fsl_dma_domain *dma_domain, dma_addr_t iova) 82 { 83 u32 win_cnt = dma_domain->win_cnt; 84 struct dma_window *win_ptr = 85 &dma_domain->win_arr[0]; 86 struct iommu_domain_geometry *geom; 87 88 geom = &dma_domain->iommu_domain->geometry; 89 90 if (!win_cnt || !dma_domain->geom_size) { 91 pr_debug("Number of windows/geometry not configured for the domain\n"); 92 return 0; 93 } 94 95 if (win_cnt > 1) { 96 u64 subwin_size; 97 dma_addr_t subwin_iova; 98 u32 wnd; 99 100 subwin_size = dma_domain->geom_size >> ilog2(win_cnt); 101 subwin_iova = iova & ~(subwin_size - 1); 102 wnd = (subwin_iova - geom->aperture_start) >> ilog2(subwin_size); 103 win_ptr = &dma_domain->win_arr[wnd]; 104 } 105 106 if (win_ptr->valid) 107 return (win_ptr->paddr + (iova & (win_ptr->size - 1))); 108 109 return 0; 110 } 111 112 static int map_subwins(int liodn, struct fsl_dma_domain *dma_domain) 113 { 114 struct dma_window *sub_win_ptr = 115 &dma_domain->win_arr[0]; 116 int i, ret; 117 unsigned long rpn, flags; 118 119 for (i = 0; i < dma_domain->win_cnt; i++) { 120 if (sub_win_ptr[i].valid) { 121 rpn = sub_win_ptr[i].paddr >> 122 PAMU_PAGE_SHIFT; 123 spin_lock_irqsave(&iommu_lock, flags); 124 ret = pamu_config_spaace(liodn, dma_domain->win_cnt, i, 125 sub_win_ptr[i].size, 126 ~(u32)0, 127 rpn, 128 dma_domain->snoop_id, 129 dma_domain->stash_id, 130 (i > 0) ? 1 : 0, 131 sub_win_ptr[i].prot); 132 spin_unlock_irqrestore(&iommu_lock, flags); 133 if (ret) { 134 pr_debug("PAMU SPAACE configuration failed for liodn %d\n", 135 liodn); 136 return ret; 137 } 138 } 139 } 140 141 return ret; 142 } 143 144 static int map_win(int liodn, struct fsl_dma_domain *dma_domain) 145 { 146 int ret; 147 struct dma_window *wnd = &dma_domain->win_arr[0]; 148 phys_addr_t wnd_addr = dma_domain->iommu_domain->geometry.aperture_start; 149 unsigned long flags; 150 151 spin_lock_irqsave(&iommu_lock, flags); 152 ret = pamu_config_ppaace(liodn, wnd_addr, 153 wnd->size, 154 ~(u32)0, 155 wnd->paddr >> PAMU_PAGE_SHIFT, 156 dma_domain->snoop_id, dma_domain->stash_id, 157 0, wnd->prot); 158 spin_unlock_irqrestore(&iommu_lock, flags); 159 if (ret) 160 pr_debug("PAMU PAACE configuration failed for liodn %d\n", 161 liodn); 162 163 return ret; 164 } 165 166 /* Map the DMA window corresponding to the LIODN */ 167 static int map_liodn(int liodn, struct fsl_dma_domain *dma_domain) 168 { 169 if (dma_domain->win_cnt > 1) 170 return map_subwins(liodn, dma_domain); 171 else 172 return map_win(liodn, dma_domain); 173 174 } 175 176 /* Update window/subwindow mapping for the LIODN */ 177 static int update_liodn(int liodn, struct fsl_dma_domain *dma_domain, u32 wnd_nr) 178 { 179 int ret; 180 struct dma_window *wnd = &dma_domain->win_arr[wnd_nr]; 181 unsigned long flags; 182 183 spin_lock_irqsave(&iommu_lock, flags); 184 if (dma_domain->win_cnt > 1) { 185 ret = pamu_config_spaace(liodn, dma_domain->win_cnt, wnd_nr, 186 wnd->size, 187 ~(u32)0, 188 wnd->paddr >> PAMU_PAGE_SHIFT, 189 dma_domain->snoop_id, 190 dma_domain->stash_id, 191 (wnd_nr > 0) ? 1 : 0, 192 wnd->prot); 193 if (ret) 194 pr_debug("Subwindow reconfiguration failed for liodn %d\n", liodn); 195 } else { 196 phys_addr_t wnd_addr; 197 198 wnd_addr = dma_domain->iommu_domain->geometry.aperture_start; 199 200 ret = pamu_config_ppaace(liodn, wnd_addr, 201 wnd->size, 202 ~(u32)0, 203 wnd->paddr >> PAMU_PAGE_SHIFT, 204 dma_domain->snoop_id, dma_domain->stash_id, 205 0, wnd->prot); 206 if (ret) 207 pr_debug("Window reconfiguration failed for liodn %d\n", liodn); 208 } 209 210 spin_unlock_irqrestore(&iommu_lock, flags); 211 212 return ret; 213 } 214 215 static int update_liodn_stash(int liodn, struct fsl_dma_domain *dma_domain, 216 u32 val) 217 { 218 int ret = 0, i; 219 unsigned long flags; 220 221 spin_lock_irqsave(&iommu_lock, flags); 222 if (!dma_domain->win_arr) { 223 pr_debug("Windows not configured, stash destination update failed for liodn %d\n", liodn); 224 spin_unlock_irqrestore(&iommu_lock, flags); 225 return -EINVAL; 226 } 227 228 for (i = 0; i < dma_domain->win_cnt; i++) { 229 ret = pamu_update_paace_stash(liodn, i, val); 230 if (ret) { 231 pr_debug("Failed to update SPAACE %d field for liodn %d\n ", i, liodn); 232 spin_unlock_irqrestore(&iommu_lock, flags); 233 return ret; 234 } 235 } 236 237 spin_unlock_irqrestore(&iommu_lock, flags); 238 239 return ret; 240 } 241 242 /* Set the geometry parameters for a LIODN */ 243 static int pamu_set_liodn(int liodn, struct device *dev, 244 struct fsl_dma_domain *dma_domain, 245 struct iommu_domain_geometry *geom_attr, 246 u32 win_cnt) 247 { 248 phys_addr_t window_addr, window_size; 249 phys_addr_t subwin_size; 250 int ret = 0, i; 251 u32 omi_index = ~(u32)0; 252 unsigned long flags; 253 254 /* 255 * Configure the omi_index at the geometry setup time. 256 * This is a static value which depends on the type of 257 * device and would not change thereafter. 258 */ 259 get_ome_index(&omi_index, dev); 260 261 window_addr = geom_attr->aperture_start; 262 window_size = dma_domain->geom_size; 263 264 spin_lock_irqsave(&iommu_lock, flags); 265 ret = pamu_disable_liodn(liodn); 266 if (!ret) 267 ret = pamu_config_ppaace(liodn, window_addr, window_size, omi_index, 268 0, dma_domain->snoop_id, 269 dma_domain->stash_id, win_cnt, 0); 270 spin_unlock_irqrestore(&iommu_lock, flags); 271 if (ret) { 272 pr_debug("PAMU PAACE configuration failed for liodn %d, win_cnt =%d\n", liodn, win_cnt); 273 return ret; 274 } 275 276 if (win_cnt > 1) { 277 subwin_size = window_size >> ilog2(win_cnt); 278 for (i = 0; i < win_cnt; i++) { 279 spin_lock_irqsave(&iommu_lock, flags); 280 ret = pamu_disable_spaace(liodn, i); 281 if (!ret) 282 ret = pamu_config_spaace(liodn, win_cnt, i, 283 subwin_size, omi_index, 284 0, dma_domain->snoop_id, 285 dma_domain->stash_id, 286 0, 0); 287 spin_unlock_irqrestore(&iommu_lock, flags); 288 if (ret) { 289 pr_debug("PAMU SPAACE configuration failed for liodn %d\n", liodn); 290 return ret; 291 } 292 } 293 } 294 295 return ret; 296 } 297 298 static int check_size(u64 size, dma_addr_t iova) 299 { 300 /* 301 * Size must be a power of two and at least be equal 302 * to PAMU page size. 303 */ 304 if (!is_power_of_2(size) || size < PAMU_PAGE_SIZE) { 305 pr_debug("%s: size too small or not a power of two\n", __func__); 306 return -EINVAL; 307 } 308 309 /* iova must be page size aligned*/ 310 if (iova & (size - 1)) { 311 pr_debug("%s: address is not aligned with window size\n", __func__); 312 return -EINVAL; 313 } 314 315 return 0; 316 } 317 318 static struct fsl_dma_domain *iommu_alloc_dma_domain(void) 319 { 320 struct fsl_dma_domain *domain; 321 322 domain = kmem_cache_zalloc(fsl_pamu_domain_cache, GFP_KERNEL); 323 if (!domain) 324 return NULL; 325 326 domain->stash_id = ~(u32)0; 327 domain->snoop_id = ~(u32)0; 328 domain->win_cnt = pamu_get_max_subwin_cnt(); 329 domain->geom_size = 0; 330 331 INIT_LIST_HEAD(&domain->devices); 332 333 spin_lock_init(&domain->domain_lock); 334 335 return domain; 336 } 337 338 static inline struct device_domain_info *find_domain(struct device *dev) 339 { 340 return dev->archdata.iommu_domain; 341 } 342 343 static void remove_device_ref(struct device_domain_info *info, u32 win_cnt) 344 { 345 unsigned long flags; 346 347 list_del(&info->link); 348 spin_lock_irqsave(&iommu_lock, flags); 349 if (win_cnt > 1) 350 pamu_free_subwins(info->liodn); 351 pamu_disable_liodn(info->liodn); 352 spin_unlock_irqrestore(&iommu_lock, flags); 353 spin_lock_irqsave(&device_domain_lock, flags); 354 info->dev->archdata.iommu_domain = NULL; 355 kmem_cache_free(iommu_devinfo_cache, info); 356 spin_unlock_irqrestore(&device_domain_lock, flags); 357 } 358 359 static void detach_device(struct device *dev, struct fsl_dma_domain *dma_domain) 360 { 361 struct device_domain_info *info, *tmp; 362 unsigned long flags; 363 364 spin_lock_irqsave(&dma_domain->domain_lock, flags); 365 /* Remove the device from the domain device list */ 366 list_for_each_entry_safe(info, tmp, &dma_domain->devices, link) { 367 if (!dev || (info->dev == dev)) 368 remove_device_ref(info, dma_domain->win_cnt); 369 } 370 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 371 } 372 373 static void attach_device(struct fsl_dma_domain *dma_domain, int liodn, struct device *dev) 374 { 375 struct device_domain_info *info, *old_domain_info; 376 unsigned long flags; 377 378 spin_lock_irqsave(&device_domain_lock, flags); 379 /* 380 * Check here if the device is already attached to domain or not. 381 * If the device is already attached to a domain detach it. 382 */ 383 old_domain_info = find_domain(dev); 384 if (old_domain_info && old_domain_info->domain != dma_domain) { 385 spin_unlock_irqrestore(&device_domain_lock, flags); 386 detach_device(dev, old_domain_info->domain); 387 spin_lock_irqsave(&device_domain_lock, flags); 388 } 389 390 info = kmem_cache_zalloc(iommu_devinfo_cache, GFP_ATOMIC); 391 392 info->dev = dev; 393 info->liodn = liodn; 394 info->domain = dma_domain; 395 396 list_add(&info->link, &dma_domain->devices); 397 /* 398 * In case of devices with multiple LIODNs just store 399 * the info for the first LIODN as all 400 * LIODNs share the same domain 401 */ 402 if (!old_domain_info) 403 dev->archdata.iommu_domain = info; 404 spin_unlock_irqrestore(&device_domain_lock, flags); 405 406 } 407 408 static phys_addr_t fsl_pamu_iova_to_phys(struct iommu_domain *domain, 409 dma_addr_t iova) 410 { 411 struct fsl_dma_domain *dma_domain = domain->priv; 412 413 if ((iova < domain->geometry.aperture_start) || 414 iova > (domain->geometry.aperture_end)) 415 return 0; 416 417 return get_phys_addr(dma_domain, iova); 418 } 419 420 static int fsl_pamu_domain_has_cap(struct iommu_domain *domain, 421 unsigned long cap) 422 { 423 return cap == IOMMU_CAP_CACHE_COHERENCY; 424 } 425 426 static void fsl_pamu_domain_destroy(struct iommu_domain *domain) 427 { 428 struct fsl_dma_domain *dma_domain = domain->priv; 429 430 domain->priv = NULL; 431 432 /* remove all the devices from the device list */ 433 detach_device(NULL, dma_domain); 434 435 dma_domain->enabled = 0; 436 dma_domain->mapped = 0; 437 438 kmem_cache_free(fsl_pamu_domain_cache, dma_domain); 439 } 440 441 static int fsl_pamu_domain_init(struct iommu_domain *domain) 442 { 443 struct fsl_dma_domain *dma_domain; 444 445 dma_domain = iommu_alloc_dma_domain(); 446 if (!dma_domain) { 447 pr_debug("dma_domain allocation failed\n"); 448 return -ENOMEM; 449 } 450 domain->priv = dma_domain; 451 dma_domain->iommu_domain = domain; 452 /* defaul geometry 64 GB i.e. maximum system address */ 453 domain->geometry.aperture_start = 0; 454 domain->geometry.aperture_end = (1ULL << 36) - 1; 455 domain->geometry.force_aperture = true; 456 457 return 0; 458 } 459 460 /* Configure geometry settings for all LIODNs associated with domain */ 461 static int pamu_set_domain_geometry(struct fsl_dma_domain *dma_domain, 462 struct iommu_domain_geometry *geom_attr, 463 u32 win_cnt) 464 { 465 struct device_domain_info *info; 466 int ret = 0; 467 468 list_for_each_entry(info, &dma_domain->devices, link) { 469 ret = pamu_set_liodn(info->liodn, info->dev, dma_domain, 470 geom_attr, win_cnt); 471 if (ret) 472 break; 473 } 474 475 return ret; 476 } 477 478 /* Update stash destination for all LIODNs associated with the domain */ 479 static int update_domain_stash(struct fsl_dma_domain *dma_domain, u32 val) 480 { 481 struct device_domain_info *info; 482 int ret = 0; 483 484 list_for_each_entry(info, &dma_domain->devices, link) { 485 ret = update_liodn_stash(info->liodn, dma_domain, val); 486 if (ret) 487 break; 488 } 489 490 return ret; 491 } 492 493 /* Update domain mappings for all LIODNs associated with the domain */ 494 static int update_domain_mapping(struct fsl_dma_domain *dma_domain, u32 wnd_nr) 495 { 496 struct device_domain_info *info; 497 int ret = 0; 498 499 list_for_each_entry(info, &dma_domain->devices, link) { 500 ret = update_liodn(info->liodn, dma_domain, wnd_nr); 501 if (ret) 502 break; 503 } 504 return ret; 505 } 506 507 static int disable_domain_win(struct fsl_dma_domain *dma_domain, u32 wnd_nr) 508 { 509 struct device_domain_info *info; 510 int ret = 0; 511 512 list_for_each_entry(info, &dma_domain->devices, link) { 513 if (dma_domain->win_cnt == 1 && dma_domain->enabled) { 514 ret = pamu_disable_liodn(info->liodn); 515 if (!ret) 516 dma_domain->enabled = 0; 517 } else { 518 ret = pamu_disable_spaace(info->liodn, wnd_nr); 519 } 520 } 521 522 return ret; 523 } 524 525 static void fsl_pamu_window_disable(struct iommu_domain *domain, u32 wnd_nr) 526 { 527 struct fsl_dma_domain *dma_domain = domain->priv; 528 unsigned long flags; 529 int ret; 530 531 spin_lock_irqsave(&dma_domain->domain_lock, flags); 532 if (!dma_domain->win_arr) { 533 pr_debug("Number of windows not configured\n"); 534 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 535 return; 536 } 537 538 if (wnd_nr >= dma_domain->win_cnt) { 539 pr_debug("Invalid window index\n"); 540 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 541 return; 542 } 543 544 if (dma_domain->win_arr[wnd_nr].valid) { 545 ret = disable_domain_win(dma_domain, wnd_nr); 546 if (!ret) { 547 dma_domain->win_arr[wnd_nr].valid = 0; 548 dma_domain->mapped--; 549 } 550 } 551 552 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 553 554 } 555 556 static int fsl_pamu_window_enable(struct iommu_domain *domain, u32 wnd_nr, 557 phys_addr_t paddr, u64 size, int prot) 558 { 559 struct fsl_dma_domain *dma_domain = domain->priv; 560 struct dma_window *wnd; 561 int pamu_prot = 0; 562 int ret; 563 unsigned long flags; 564 u64 win_size; 565 566 if (prot & IOMMU_READ) 567 pamu_prot |= PAACE_AP_PERMS_QUERY; 568 if (prot & IOMMU_WRITE) 569 pamu_prot |= PAACE_AP_PERMS_UPDATE; 570 571 spin_lock_irqsave(&dma_domain->domain_lock, flags); 572 if (!dma_domain->win_arr) { 573 pr_debug("Number of windows not configured\n"); 574 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 575 return -ENODEV; 576 } 577 578 if (wnd_nr >= dma_domain->win_cnt) { 579 pr_debug("Invalid window index\n"); 580 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 581 return -EINVAL; 582 } 583 584 win_size = dma_domain->geom_size >> ilog2(dma_domain->win_cnt); 585 if (size > win_size) { 586 pr_debug("Invalid window size \n"); 587 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 588 return -EINVAL; 589 } 590 591 if (dma_domain->win_cnt == 1) { 592 if (dma_domain->enabled) { 593 pr_debug("Disable the window before updating the mapping\n"); 594 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 595 return -EBUSY; 596 } 597 598 ret = check_size(size, domain->geometry.aperture_start); 599 if (ret) { 600 pr_debug("Aperture start not aligned to the size\n"); 601 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 602 return -EINVAL; 603 } 604 } 605 606 wnd = &dma_domain->win_arr[wnd_nr]; 607 if (!wnd->valid) { 608 wnd->paddr = paddr; 609 wnd->size = size; 610 wnd->prot = pamu_prot; 611 612 ret = update_domain_mapping(dma_domain, wnd_nr); 613 if (!ret) { 614 wnd->valid = 1; 615 dma_domain->mapped++; 616 } 617 } else { 618 pr_debug("Disable the window before updating the mapping\n"); 619 ret = -EBUSY; 620 } 621 622 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 623 624 return ret; 625 } 626 627 /* 628 * Attach the LIODN to the DMA domain and configure the geometry 629 * and window mappings. 630 */ 631 static int handle_attach_device(struct fsl_dma_domain *dma_domain, 632 struct device *dev, const u32 *liodn, 633 int num) 634 { 635 unsigned long flags; 636 struct iommu_domain *domain = dma_domain->iommu_domain; 637 int ret = 0; 638 int i; 639 640 spin_lock_irqsave(&dma_domain->domain_lock, flags); 641 for (i = 0; i < num; i++) { 642 643 /* Ensure that LIODN value is valid */ 644 if (liodn[i] >= PAACE_NUMBER_ENTRIES) { 645 pr_debug("Invalid liodn %d, attach device failed for %s\n", 646 liodn[i], dev->of_node->full_name); 647 ret = -EINVAL; 648 break; 649 } 650 651 attach_device(dma_domain, liodn[i], dev); 652 /* 653 * Check if geometry has already been configured 654 * for the domain. If yes, set the geometry for 655 * the LIODN. 656 */ 657 if (dma_domain->win_arr) { 658 u32 win_cnt = dma_domain->win_cnt > 1 ? dma_domain->win_cnt : 0; 659 ret = pamu_set_liodn(liodn[i], dev, dma_domain, 660 &domain->geometry, 661 win_cnt); 662 if (ret) 663 break; 664 if (dma_domain->mapped) { 665 /* 666 * Create window/subwindow mapping for 667 * the LIODN. 668 */ 669 ret = map_liodn(liodn[i], dma_domain); 670 if (ret) 671 break; 672 } 673 } 674 } 675 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 676 677 return ret; 678 } 679 680 static int fsl_pamu_attach_device(struct iommu_domain *domain, 681 struct device *dev) 682 { 683 struct fsl_dma_domain *dma_domain = domain->priv; 684 const u32 *liodn; 685 u32 liodn_cnt; 686 int len, ret = 0; 687 struct pci_dev *pdev = NULL; 688 struct pci_controller *pci_ctl; 689 690 /* 691 * Use LIODN of the PCI controller while attaching a 692 * PCI device. 693 */ 694 if (dev_is_pci(dev)) { 695 pdev = to_pci_dev(dev); 696 pci_ctl = pci_bus_to_host(pdev->bus); 697 /* 698 * make dev point to pci controller device 699 * so we can get the LIODN programmed by 700 * u-boot. 701 */ 702 dev = pci_ctl->parent; 703 } 704 705 liodn = of_get_property(dev->of_node, "fsl,liodn", &len); 706 if (liodn) { 707 liodn_cnt = len / sizeof(u32); 708 ret = handle_attach_device(dma_domain, dev, 709 liodn, liodn_cnt); 710 } else { 711 pr_debug("missing fsl,liodn property at %s\n", 712 dev->of_node->full_name); 713 ret = -EINVAL; 714 } 715 716 return ret; 717 } 718 719 static void fsl_pamu_detach_device(struct iommu_domain *domain, 720 struct device *dev) 721 { 722 struct fsl_dma_domain *dma_domain = domain->priv; 723 const u32 *prop; 724 int len; 725 struct pci_dev *pdev = NULL; 726 struct pci_controller *pci_ctl; 727 728 /* 729 * Use LIODN of the PCI controller while detaching a 730 * PCI device. 731 */ 732 if (dev_is_pci(dev)) { 733 pdev = to_pci_dev(dev); 734 pci_ctl = pci_bus_to_host(pdev->bus); 735 /* 736 * make dev point to pci controller device 737 * so we can get the LIODN programmed by 738 * u-boot. 739 */ 740 dev = pci_ctl->parent; 741 } 742 743 prop = of_get_property(dev->of_node, "fsl,liodn", &len); 744 if (prop) 745 detach_device(dev, dma_domain); 746 else 747 pr_debug("missing fsl,liodn property at %s\n", 748 dev->of_node->full_name); 749 } 750 751 static int configure_domain_geometry(struct iommu_domain *domain, void *data) 752 { 753 struct iommu_domain_geometry *geom_attr = data; 754 struct fsl_dma_domain *dma_domain = domain->priv; 755 dma_addr_t geom_size; 756 unsigned long flags; 757 758 geom_size = geom_attr->aperture_end - geom_attr->aperture_start + 1; 759 /* 760 * Sanity check the geometry size. Also, we do not support 761 * DMA outside of the geometry. 762 */ 763 if (check_size(geom_size, geom_attr->aperture_start) || 764 !geom_attr->force_aperture) { 765 pr_debug("Invalid PAMU geometry attributes\n"); 766 return -EINVAL; 767 } 768 769 spin_lock_irqsave(&dma_domain->domain_lock, flags); 770 if (dma_domain->enabled) { 771 pr_debug("Can't set geometry attributes as domain is active\n"); 772 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 773 return -EBUSY; 774 } 775 776 /* Copy the domain geometry information */ 777 memcpy(&domain->geometry, geom_attr, 778 sizeof(struct iommu_domain_geometry)); 779 dma_domain->geom_size = geom_size; 780 781 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 782 783 return 0; 784 } 785 786 /* Set the domain stash attribute */ 787 static int configure_domain_stash(struct fsl_dma_domain *dma_domain, void *data) 788 { 789 struct pamu_stash_attribute *stash_attr = data; 790 unsigned long flags; 791 int ret; 792 793 spin_lock_irqsave(&dma_domain->domain_lock, flags); 794 795 memcpy(&dma_domain->dma_stash, stash_attr, 796 sizeof(struct pamu_stash_attribute)); 797 798 dma_domain->stash_id = get_stash_id(stash_attr->cache, 799 stash_attr->cpu); 800 if (dma_domain->stash_id == ~(u32)0) { 801 pr_debug("Invalid stash attributes\n"); 802 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 803 return -EINVAL; 804 } 805 806 ret = update_domain_stash(dma_domain, dma_domain->stash_id); 807 808 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 809 810 return ret; 811 } 812 813 /* Configure domain dma state i.e. enable/disable DMA*/ 814 static int configure_domain_dma_state(struct fsl_dma_domain *dma_domain, bool enable) 815 { 816 struct device_domain_info *info; 817 unsigned long flags; 818 int ret; 819 820 spin_lock_irqsave(&dma_domain->domain_lock, flags); 821 822 if (enable && !dma_domain->mapped) { 823 pr_debug("Can't enable DMA domain without valid mapping\n"); 824 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 825 return -ENODEV; 826 } 827 828 dma_domain->enabled = enable; 829 list_for_each_entry(info, &dma_domain->devices, 830 link) { 831 ret = (enable) ? pamu_enable_liodn(info->liodn) : 832 pamu_disable_liodn(info->liodn); 833 if (ret) 834 pr_debug("Unable to set dma state for liodn %d", 835 info->liodn); 836 } 837 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 838 839 return 0; 840 } 841 842 static int fsl_pamu_set_domain_attr(struct iommu_domain *domain, 843 enum iommu_attr attr_type, void *data) 844 { 845 struct fsl_dma_domain *dma_domain = domain->priv; 846 int ret = 0; 847 848 849 switch (attr_type) { 850 case DOMAIN_ATTR_GEOMETRY: 851 ret = configure_domain_geometry(domain, data); 852 break; 853 case DOMAIN_ATTR_FSL_PAMU_STASH: 854 ret = configure_domain_stash(dma_domain, data); 855 break; 856 case DOMAIN_ATTR_FSL_PAMU_ENABLE: 857 ret = configure_domain_dma_state(dma_domain, *(int *)data); 858 break; 859 default: 860 pr_debug("Unsupported attribute type\n"); 861 ret = -EINVAL; 862 break; 863 }; 864 865 return ret; 866 } 867 868 static int fsl_pamu_get_domain_attr(struct iommu_domain *domain, 869 enum iommu_attr attr_type, void *data) 870 { 871 struct fsl_dma_domain *dma_domain = domain->priv; 872 int ret = 0; 873 874 875 switch (attr_type) { 876 case DOMAIN_ATTR_FSL_PAMU_STASH: 877 memcpy((struct pamu_stash_attribute *) data, &dma_domain->dma_stash, 878 sizeof(struct pamu_stash_attribute)); 879 break; 880 case DOMAIN_ATTR_FSL_PAMU_ENABLE: 881 *(int *)data = dma_domain->enabled; 882 break; 883 case DOMAIN_ATTR_FSL_PAMUV1: 884 *(int *)data = DOMAIN_ATTR_FSL_PAMUV1; 885 break; 886 default: 887 pr_debug("Unsupported attribute type\n"); 888 ret = -EINVAL; 889 break; 890 }; 891 892 return ret; 893 } 894 895 #define REQ_ACS_FLAGS (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF) 896 897 static struct iommu_group *get_device_iommu_group(struct device *dev) 898 { 899 struct iommu_group *group; 900 901 group = iommu_group_get(dev); 902 if (!group) 903 group = iommu_group_alloc(); 904 905 return group; 906 } 907 908 static bool check_pci_ctl_endpt_part(struct pci_controller *pci_ctl) 909 { 910 u32 version; 911 912 /* Check the PCI controller version number by readding BRR1 register */ 913 version = in_be32(pci_ctl->cfg_addr + (PCI_FSL_BRR1 >> 2)); 914 version &= PCI_FSL_BRR1_VER; 915 /* If PCI controller version is >= 0x204 we can partition endpoints*/ 916 if (version >= 0x204) 917 return 1; 918 919 return 0; 920 } 921 922 /* Get iommu group information from peer devices or devices on the parent bus */ 923 static struct iommu_group *get_shared_pci_device_group(struct pci_dev *pdev) 924 { 925 struct pci_dev *tmp; 926 struct iommu_group *group; 927 struct pci_bus *bus = pdev->bus; 928 929 /* 930 * Traverese the pci bus device list to get 931 * the shared iommu group. 932 */ 933 while (bus) { 934 list_for_each_entry(tmp, &bus->devices, bus_list) { 935 if (tmp == pdev) 936 continue; 937 group = iommu_group_get(&tmp->dev); 938 if (group) 939 return group; 940 } 941 942 bus = bus->parent; 943 } 944 945 return NULL; 946 } 947 948 static struct iommu_group *get_pci_device_group(struct pci_dev *pdev) 949 { 950 struct pci_controller *pci_ctl; 951 bool pci_endpt_partioning; 952 struct iommu_group *group = NULL; 953 struct pci_dev *bridge, *dma_pdev = NULL; 954 955 pci_ctl = pci_bus_to_host(pdev->bus); 956 pci_endpt_partioning = check_pci_ctl_endpt_part(pci_ctl); 957 /* We can partition PCIe devices so assign device group to the device */ 958 if (pci_endpt_partioning) { 959 bridge = pci_find_upstream_pcie_bridge(pdev); 960 if (bridge) { 961 if (pci_is_pcie(bridge)) 962 dma_pdev = pci_get_domain_bus_and_slot( 963 pci_domain_nr(pdev->bus), 964 bridge->subordinate->number, 0); 965 if (!dma_pdev) 966 dma_pdev = pci_dev_get(bridge); 967 } else 968 dma_pdev = pci_dev_get(pdev); 969 970 /* Account for quirked devices */ 971 swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); 972 973 /* 974 * If it's a multifunction device that does not support our 975 * required ACS flags, add to the same group as lowest numbered 976 * function that also does not suport the required ACS flags. 977 */ 978 if (dma_pdev->multifunction && 979 !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) { 980 u8 i, slot = PCI_SLOT(dma_pdev->devfn); 981 982 for (i = 0; i < 8; i++) { 983 struct pci_dev *tmp; 984 985 tmp = pci_get_slot(dma_pdev->bus, PCI_DEVFN(slot, i)); 986 if (!tmp) 987 continue; 988 989 if (!pci_acs_enabled(tmp, REQ_ACS_FLAGS)) { 990 swap_pci_ref(&dma_pdev, tmp); 991 break; 992 } 993 pci_dev_put(tmp); 994 } 995 } 996 997 /* 998 * Devices on the root bus go through the iommu. If that's not us, 999 * find the next upstream device and test ACS up to the root bus. 1000 * Finding the next device may require skipping virtual buses. 1001 */ 1002 while (!pci_is_root_bus(dma_pdev->bus)) { 1003 struct pci_bus *bus = dma_pdev->bus; 1004 1005 while (!bus->self) { 1006 if (!pci_is_root_bus(bus)) 1007 bus = bus->parent; 1008 else 1009 goto root_bus; 1010 } 1011 1012 if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS)) 1013 break; 1014 1015 swap_pci_ref(&dma_pdev, pci_dev_get(bus->self)); 1016 } 1017 1018 root_bus: 1019 group = get_device_iommu_group(&dma_pdev->dev); 1020 pci_dev_put(dma_pdev); 1021 /* 1022 * PCIe controller is not a paritionable entity 1023 * free the controller device iommu_group. 1024 */ 1025 if (pci_ctl->parent->iommu_group) 1026 iommu_group_remove_device(pci_ctl->parent); 1027 } else { 1028 /* 1029 * All devices connected to the controller will share the 1030 * PCI controllers device group. If this is the first 1031 * device to be probed for the pci controller, copy the 1032 * device group information from the PCI controller device 1033 * node and remove the PCI controller iommu group. 1034 * For subsequent devices, the iommu group information can 1035 * be obtained from sibling devices (i.e. from the bus_devices 1036 * link list). 1037 */ 1038 if (pci_ctl->parent->iommu_group) { 1039 group = get_device_iommu_group(pci_ctl->parent); 1040 iommu_group_remove_device(pci_ctl->parent); 1041 } else 1042 group = get_shared_pci_device_group(pdev); 1043 } 1044 1045 return group; 1046 } 1047 1048 static int fsl_pamu_add_device(struct device *dev) 1049 { 1050 struct iommu_group *group = NULL; 1051 struct pci_dev *pdev; 1052 const u32 *prop; 1053 int ret, len; 1054 1055 /* 1056 * For platform devices we allocate a separate group for 1057 * each of the devices. 1058 */ 1059 if (dev_is_pci(dev)) { 1060 pdev = to_pci_dev(dev); 1061 /* Don't create device groups for virtual PCI bridges */ 1062 if (pdev->subordinate) 1063 return 0; 1064 1065 group = get_pci_device_group(pdev); 1066 1067 } else { 1068 prop = of_get_property(dev->of_node, "fsl,liodn", &len); 1069 if (prop) 1070 group = get_device_iommu_group(dev); 1071 } 1072 1073 if (!group || IS_ERR(group)) 1074 return PTR_ERR(group); 1075 1076 ret = iommu_group_add_device(group, dev); 1077 1078 iommu_group_put(group); 1079 return ret; 1080 } 1081 1082 static void fsl_pamu_remove_device(struct device *dev) 1083 { 1084 iommu_group_remove_device(dev); 1085 } 1086 1087 static int fsl_pamu_set_windows(struct iommu_domain *domain, u32 w_count) 1088 { 1089 struct fsl_dma_domain *dma_domain = domain->priv; 1090 unsigned long flags; 1091 int ret; 1092 1093 spin_lock_irqsave(&dma_domain->domain_lock, flags); 1094 /* Ensure domain is inactive i.e. DMA should be disabled for the domain */ 1095 if (dma_domain->enabled) { 1096 pr_debug("Can't set geometry attributes as domain is active\n"); 1097 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 1098 return -EBUSY; 1099 } 1100 1101 /* Ensure that the geometry has been set for the domain */ 1102 if (!dma_domain->geom_size) { 1103 pr_debug("Please configure geometry before setting the number of windows\n"); 1104 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 1105 return -EINVAL; 1106 } 1107 1108 /* 1109 * Ensure we have valid window count i.e. it should be less than 1110 * maximum permissible limit and should be a power of two. 1111 */ 1112 if (w_count > pamu_get_max_subwin_cnt() || !is_power_of_2(w_count)) { 1113 pr_debug("Invalid window count\n"); 1114 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 1115 return -EINVAL; 1116 } 1117 1118 ret = pamu_set_domain_geometry(dma_domain, &domain->geometry, 1119 ((w_count > 1) ? w_count : 0)); 1120 if (!ret) { 1121 if (dma_domain->win_arr) 1122 kfree(dma_domain->win_arr); 1123 dma_domain->win_arr = kzalloc(sizeof(struct dma_window) * 1124 w_count, GFP_ATOMIC); 1125 if (!dma_domain->win_arr) { 1126 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 1127 return -ENOMEM; 1128 } 1129 dma_domain->win_cnt = w_count; 1130 } 1131 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 1132 1133 return ret; 1134 } 1135 1136 static u32 fsl_pamu_get_windows(struct iommu_domain *domain) 1137 { 1138 struct fsl_dma_domain *dma_domain = domain->priv; 1139 1140 return dma_domain->win_cnt; 1141 } 1142 1143 static struct iommu_ops fsl_pamu_ops = { 1144 .domain_init = fsl_pamu_domain_init, 1145 .domain_destroy = fsl_pamu_domain_destroy, 1146 .attach_dev = fsl_pamu_attach_device, 1147 .detach_dev = fsl_pamu_detach_device, 1148 .domain_window_enable = fsl_pamu_window_enable, 1149 .domain_window_disable = fsl_pamu_window_disable, 1150 .domain_get_windows = fsl_pamu_get_windows, 1151 .domain_set_windows = fsl_pamu_set_windows, 1152 .iova_to_phys = fsl_pamu_iova_to_phys, 1153 .domain_has_cap = fsl_pamu_domain_has_cap, 1154 .domain_set_attr = fsl_pamu_set_domain_attr, 1155 .domain_get_attr = fsl_pamu_get_domain_attr, 1156 .add_device = fsl_pamu_add_device, 1157 .remove_device = fsl_pamu_remove_device, 1158 }; 1159 1160 int pamu_domain_init() 1161 { 1162 int ret = 0; 1163 1164 ret = iommu_init_mempool(); 1165 if (ret) 1166 return ret; 1167 1168 bus_set_iommu(&platform_bus_type, &fsl_pamu_ops); 1169 bus_set_iommu(&pci_bus_type, &fsl_pamu_ops); 1170 1171 return ret; 1172 } 1173